Open iranoan opened 2 years ago
9.0.0752 で再現
formatlistpat
にマッチする時、タブを含むインデントは物理文字数で適用される(タブは1セルとカウントされるformatlistpat
にマッチしない時、タブを含むインデントが見た目通りに適用されるこんな感じの矛盾があるっぽい。なんでこうなってるのかは不明。
補足:
breakindent
は warp された行の先頭に見た目上のインデントを追加する。
breakindentopt
はその動作をカスタマイズするためのオプション。
breakindentopt
の list:-1
という値は、インデント量の判定に formatlistpat
でマッチした物理的な長さを使ってる。
一方で breakindent
自身は、先行する空白文字を別口でインデントとするらしい。
そしてその場合の長さは物理的なものではなく、見た目的なものとなっている。
この違いが不自然さを生じていると考えられる。
先行する空白をインデントと認識している箇所。
https://github.com/vim/vim/blob/db4c94788ad70118fa1ccc5fbc821757350ac771/src/indent.c#L978-L979
コメントを見ると、見た目(cell)で取れることがわかる。
https://github.com/vim/vim/blob/db4c94788ad70118fa1ccc5fbc821757350ac771/src/indent.c#L430-L435
つまり prev_indent
にインデント幅が見た目(cellサイズ)で入ることがわかる。
その後 formatlistpat が利用でき、かつマッチする際に prev_indent
が上書きされる。
この時は見た目は考慮せず純粋にマッチした文字数に上書きされている。
https://github.com/vim/vim/blob/db4c94788ad70118fa1ccc5fbc821757350ac771/src/indent.c#L986-L1001
prev_indent = (*regmatch.endp - *regmatch.startp);
の箇所で
linetabsize_str()
に *regmatch.endp[0] = NUL
して
regmatch.startup[0]
(もしくは *regmatch.startup
) を渡せばよいはず。
ただ漫然と endp[0]
を書き替えて良いとも思えないので、
呼び出し前に退避して呼び出し後に復帰する
もしくは save & free するみたいなことが要りそうね。
やる気が切れたので僕はいったんここまで。
色々調べていただきありがとうございました 環境依存でないことが分かっただけでも助かります
質問の内容
とした時、折返し行のインデント量は、タブ文字が常に1として計算されます
これは意図してこの様になっているのでしょうか?
再現動画
上動画は GVim を使っていますが、下記設定ファイルのコメントに有るように端末でも再現します また
set expandtab
を使っていませんが、使った場合の自動整形はtabstop
に応じた個数だけスペースが入力されるので、strwidth() ではなく strdisplaywidth() 相当でインデントされたほうが対応を考えると自然な気がします\~/.vim/vimrc
Vimのバージョン