└── ftplugin └── haskell └── ormolu-haskell.vim /ftplugin/haskell/ormolu-haskell.vim: -------------------------------------------------------------------------------- 1 | if !exists("g:ormolu_command") 2 | let g:ormolu_command = "ormolu" 3 | endif 4 | if !exists("g:ormolu_options") 5 | let g:ormolu_options = [""] 6 | endif 7 | if !exists("g:ormolu_disable") 8 | let g:ormolu_disable = 0 9 | endif 10 | if !exists("g:ormolu_suppress_stderr") 11 | let g:ormolu_suppress_stderr = 0 12 | endif 13 | if !exists("b:ormolu_disable") 14 | " Inherit buffer level flag from global flag (default 0) 15 | let b:ormolu_disable = g:ormolu_disable 16 | endif 17 | 18 | function! s:OverwriteBuffer(output) 19 | if &modifiable 20 | let l:curw=winsaveview() 21 | try | silent undojoin | catch | endtry 22 | let splitted = split(a:output, '\n') 23 | if line('$') > len(splitted) 24 | execute len(splitted) .',$delete' 25 | endif 26 | call setline(1, splitted) 27 | call winrestview(l:curw) 28 | else 29 | echom "Cannot write to non-modifiable buffer" 30 | endif 31 | endfunction 32 | 33 | function! s:OrmoluHaskell() 34 | if executable(g:ormolu_command) 35 | call s:RunOrmolu() 36 | elseif !exists("s:exec_warned") 37 | let s:exec_warned = 1 38 | echom "ormolu executable not found" 39 | endif 40 | endfunction 41 | 42 | function! s:OrmoluSave() 43 | if (b:ormolu_disable == 1) 44 | else 45 | call s:OrmoluHaskell() 46 | endif 47 | if exists("bufname") 48 | write 49 | endif 50 | endfunction 51 | 52 | function! s:RunOrmolu() 53 | let cmd_base = g:ormolu_command . " " . join(g:ormolu_options, ' ') 54 | if exists("bufname") 55 | let orm_cmd = cmd_base . " " . bufname("%") 56 | if (g:ormolu_suppress_stderr == 1) 57 | let orm_cmd = orm_cmd . " 2>/dev/null" 58 | endif 59 | let output = system(orm_cmd) 60 | else 61 | let orm_cmd = cmd_base 62 | if (g:ormolu_suppress_stderr == 1) 63 | let orm_cmd = orm_cmd . " 2>/dev/null" 64 | endif 65 | let stdin = join(getline(1, '$'), "\n") 66 | let output = system(orm_cmd, stdin) 67 | endif 68 | if v:shell_error != 0 69 | echom output 70 | else 71 | call s:OverwriteBuffer(output) 72 | if exists("bufname") 73 | write 74 | endif 75 | endif 76 | endfunction 77 | 78 | function! OrmoluBlock() 79 | let [line_start, column_start] = getpos("'<")[1:2] 80 | let [line_end, column_end] = getpos("'>")[1:2] 81 | let lines = getline(line_start, line_end) 82 | let length = 1 + (line_end-line_start) 83 | let output = system(g:ormolu_command . " " . join(g:ormolu_options, ' '), lines) 84 | let formatted = split(output, '\v\n') 85 | 86 | if v:shell_error != 0 87 | echom output 88 | else 89 | 90 | if length > len(formatted) 91 | let max = line_end - 1 92 | else 93 | let max = (line_start + len(formatted)) - 1 94 | endif 95 | 96 | " If the length of outputted code is longer than visual block append empty 97 | " lines to fill 98 | if len(formatted) > length 99 | let c = 0 100 | while c < (len(formatted) - length) 101 | call append(line_end, "") 102 | let c = c+1 103 | endwhile 104 | endif 105 | 106 | " If the length of outputted code is longer than visual block delete lines 107 | if len(formatted) < length 108 | let c = 0 109 | while c < (length - len(formatted)) 110 | normal! dd 111 | let c = c+1 112 | endwhile 113 | endif 114 | 115 | " Empty the visual block 116 | let currentLine=line_start 117 | while currentLine <= line_end 118 | call setline(currentLine, "") 119 | let currentLine = currentLine + 1 120 | endwhile 121 | 122 | " Replace with ormolu output 123 | let currentLine=line_start 124 | let ix=0 125 | while currentLine <= max 126 | "echom "Replacing" 127 | call setline(currentLine, formatted[ix]) 128 | let currentLine = currentLine + 1 129 | let ix = ix + 1 130 | endwhile 131 | endif 132 | endfunction 133 | 134 | function! RunOrmolu() 135 | call s:OrmoluHaskell() 136 | endfunction 137 | 138 | function! ToggleOrmolu() 139 | if b:ormolu_disable == 1 140 | let b:ormolu_disable = 0 141 | echo "Ormolu formatting enabled for " . bufname("%") 142 | else 143 | let b:ormolu_disable = 1 144 | echo "Ormolu formatting disabled for " . bufname("%") 145 | endif 146 | endfunction 147 | 148 | function! DisableOrmolu() 149 | let b:ormolu_disable = 1 150 | echo "Ormolu formatting disabled for " . bufname("%") 151 | endfunction 152 | 153 | function! EnableOrmolu() 154 | let b:ormolu_disable = 0 155 | echo "Ormolu formatting enabled for " . bufname("%") 156 | endfunction 157 | 158 | augroup ormolu-haskell 159 | autocmd! 160 | autocmd BufWritePre *.hs call s:OrmoluSave() 161 | augroup END 162 | --------------------------------------------------------------------------------