" Vim indent file " Language: C++ " Maintainer: G-HAL " Last Change: 2006 Sep 01 Fri - Sep 11 Mon, Tue,10 Oct,2006, Tue,31 Oct,2006, Mon,11 Aug,2008 " Remark: Modified cindent " ~/.vim/indent/cpp.vim " : ラベル行のインデント量を、デフォルトの0から、半コマ戻しに変更する。 " # プリプロセッサ行のインデント量を、デフォルトの0から、半コマ戻しに変更する。 " " Attention: " cinoptions 指定の幅を確認すべき所を手抜きで無視している。 " ? : 構文で "^\s*value_name:" とか言う書き方 " (: の前にスペースを入れずに ANK を書く)をするとラベルと間違える。 " " Note: " indentexpr に入れる関数を s: 宣言で 呼出にしたらこけた。 " GetModifiedCppIndent から使う関数を s: 宣言で 呼出にしたらこけた。 " if exists("b:did_indent") finish endif let b:did_indent = 1 " 前行から現行のインデント量の推測 function! GetLastlineIndent() " " デフォルトの推定値 let llnum = prevnonblank(v:lnum -1) let last_line = getline(llnum) let def_indent = indent(llnum) " " コメントの削除 " コメントのネストや、コメント終了のうしろに記述、などは、 " 普通しないので、そのへん手抜き。 let ptr = match(last_line, '\(\/\/\|\/\*\)' ) if 0 <= ptr let last_line = strpart(last_line, 0, ptr) endif let ptr = matchend(last_line, '\(\*\/\)' ) if 0 <= ptr let last_line = strpart(last_line, ptr) endif " " 前行のインデント量が不規則なケース if (last_line =~? '^\s*#') || ((last_line =~? '^\s*\k*:\([^:]\|$\)') && (last_line !~? '^\s*\(public\|protected\|private\):')) " ラベルの場合 let def_indent = indent(llnum) + &shiftwidth / 2 " ラベルの場合、継続行インデントの様な特殊なインデントは、無いと思う。 else " 継続行インデントが、かかっているか否か検索 let lllnum = llnum let i = 0 while i < 10 " cinoptions の ) 指定を見るべきだが面倒くさい。 let lllnum = prevnonblank(lllnum -1) let ldef_indent = indent(lllnum) if (ldef_indent != def_indent) if (ldef_indent + &shiftwidth) < def_indent " 継続行インデントだった " cinoptions の +,(,u,U,w,W,m,M 指定を確認すべきだが面倒くさい。 let def_indent = ldef_indent endif break endif let i = i + 1 endwhile endif " " 前行からインデント量が変化するケース if 0 <= match(last_line, '{[^}]*$') " cinoptions の >,e,f,{,^,l,b 指定の幅を確認すべきだが面倒くさい。 " {{{ とかやると、インデント基準位置が狂うが、 " 行中最後の { の virtual column を取得する方法が判らん。 let def_indent = def_indent + &shiftwidth elseif (last_line =~? '^\s*if\s[^;]*$') " cinoptions の n 指定の幅を確認すべきだが面倒くさい。 let def_indent = def_indent + &shiftwidth elseif (last_line =~? '^\s*\(public\|protected\|private\):') " cinoptions の g,h 指定の幅を確認すべきだが面倒くさい。 let def_indent = def_indent + &shiftwidth elseif (last_line =~? '^\s*\(case\s\|default:\)') " cinoptions の :,= 指定の幅を確認すべきだが面倒くさい。 let def_indent = def_indent + &shiftwidth endif " " cinoptions の },p,t,i 指定の幅を確認すべきだが面倒くさい。 " cinoptions の / 指定の幅を確認すべきだが面倒くさい。 return def_indent " cinoptions の c,C 指定は無視していい筈だ。 endfunction function! GetModifiedCppIndent() let cur_line = getline(v:lnum) " " ラベル専用インデント if (cur_line =~? '^\s*#') || ((cur_line =~? '^\s*\k*:\([^:]\|$\)') && (cur_line !~? '^\s*\(public\|protected\|private\|default\|\):')) let def_indent = GetLastlineIndent() let new_indent = def_indent - &shiftwidth / 2 if new_indent < 0 let new_indent = 0 endif return new_indent endif " " 標準インデント let def_cindent = cindent(v:lnum) return def_cindent endfunction setlocal indentexpr=GetModifiedCppIndent() " End of File