Haskell用vimファイル
Haskell用vimファイルあれこれをもらってきて使っているうちに,
Vimに馴染みがない人のための手抜き説明:
挿入モード中に,
- Ctrl-F 前後を見て再インデント
- Ctrl-T インデントを1段深く
- Ctrl-D インデントを1段浅く
Haskellに馴染みがない人のための手抜き説明:
Haskellは文法にインデントブロックを採用しています.
インデントの深さが同じ行ごとにまとまりとみなすのですが,
たとえば,
where c n r = product [n-r+1 .. n] `div` fact r fact n = product [1 .. n]
のような位置揃えが要求されるため,固定幅のインデント増減だけでは対応しにくいことになります.
それから数ヶ月,未だにvim scriptが良く分かっていないのですが,とりあえず自分で使っていてそれなりに便利だと思うので公開します.
リンク先の indent/haskell.vim がないとおそらく使えないので,注意.
setlocal expandtab setlocal noignorecase setlocal suffixesadd=.hs setlocal cpoptions+=M setlocal shiftwidth=1 "iabbrev case case of<Left><Left><Left> "iabbrev W where "iabbrev M module "iabbrev In instance "iabbrev Im import "compiler ghc "inoremap <C-T> _<BS><ESC>:call <SID>Indent()<CR>i inoremap <C-T> _<ESC>:call <SID>Indent()<CR>a<BS> inoremap <C-D> _<ESC>:call <SID>Unindent()<CR>a<BS> function! s:Indent() let pos = getpos('.') let lnum = pos[1] let cnum = pos[2] if lnum == 1 return endif let line = getline('.') " if line =~ '^\s*$' | execute 'normal a ' | endif normal ^kW let indent_pos = getpos('.') if indent_pos[1] == lnum - 1 normal j else call cursor(lnum, 0) normal ^ let indent_pos = getpos('.') let indent_pos[2] += g:haskell_indent_other " call cursor(lnum - 1, 0) " normal ^ " let indent_pos = getpos('.') endif " s/^\s*/\=repeat(' ', line =~ '^\s*$' ? indent_pos[2] : indent_pos[2] - 1)/ s/^\s*/\=repeat(' ', indent_pos[2] - 1)/ let new_line = getline('.') call cursor(lnum, cnum + len(new_line) - len(line)) endfunction function! s:Unindent() let pos = getpos('.') let lnum = pos[1] let cnum = pos[2] if lnum == 1 return endif let line = getline('.') " if line =~ '^\s*$' | execute 'normal a ' | endif normal ^ let cnum2 = getpos('.')[2] if cnum2 == 1 call cursor(lnum, cnum) return endif normal B let indent_pos = getpos('.') while indent_pos[2] >= cnum2 normal B let indent_pos = getpos('.') endwhile call cursor(lnum, 0) " s/^\s*/\=repeat(' ', line =~ '^\s*$' ? indent_pos[2] : indent_pos[2] - 1)/ s/^\s*/\=repeat(' ', indent_pos[2] - 1)/ let new_line = getline('.') call cursor(lnum, cnum + len(new_line) - len(line)) endfunction
主な改変箇所
で,適切にインデントを減らすように. - それに伴い,
は右端から戻らずさらに右へ行くように. - shiftwidthを1にして,<,>でインデントの深さを調整しやすくした.
- 行が空行のときに(自分の環境では?)バグらしかったので,そうならないよう修正.
- でも,インデントの途中にカーソルがいるときの挙動はおかしくなります.そうは使わないけれど.
ツッコミなどあればお願いします.