読者です 読者をやめる 読者になる 読者になる

自動改行困る

困りませんか?
ウチは嫌です。

なので、改めて色々見てみました。

そしたら、こうみたいなので、こうしました。;

" 自動形成について(特に、自動改行) (:h formatoptions, :h fo-table)
augroup noo
  autocmd!
  autocmd FileType * setlocal tw=0
  " 自動改行を抑制
  autocmd FileType * setlocal fo-=t
  autocmd FileType * setlocal fo-=c
  " コメントスタイルの自動挿入を抑制
  autocmd FileType * setlocal fo-=r
  autocmd FileType * setlocal fo-=o
augroup END

いや。こんな事、全くもって今更で、公に晒すのがむしろ痛々しい程に、"何を今更" な話なのですが...あえて。

無知は怖い。無知は恥ずかしいし、本当にかっこわるいし、まじいらね、ほんっとしげばいいと思う。
な感じで、もはや抑えられない S 気質がムックリと覚醒したわけでして ...っと(笑

この問題に関するレポートは結構あって、対処法には諸説ある模様。
おそらくこんな感じかと。;

  1. textwidth=0 説
  2. formationoption=q 説
  3. FileType イベント "も" 説

で、良く目にするのが、前者 2 つ。

経験的にも、この 2 説 で上手く行くと思っていたのですが、実はそうではないようで、
FileType イベントも考慮する必要があったと。

ここでの決定打は、こちら。;

どうやら、.vimrc読み込み後、filetypeが切り替わった際に、$VIMRUNTIME/ftplugin配下のファイルが読み込まれ、ここでformatoptionsが上書きされてしまっているようです。
: *snip*
上記の様なことをやりたいだけであれば、FileTypeイベントでいけるみたいです。

に、にねん遅れ...

そして以下、いつもの記憶のアウトソーシングとして記録。

ん? set textwidth=0 でも set formatoptions=q でもないとか?!

この度、別キッカケで vim 自体を delete & insert して作業していたら、再びこの現象に。

このストレス、実は以前にも経験していたりする。

理屈としては難しくなく、こんな自分ですら、容易に解決策をイメージできる。
ところが、この単純さだけに、
この問題を解決しようと手を着けてみると、一体それがどこで制御され、どの設定が効いているのか分かりずらず、イライラさせられる。

以前やった時は、冒頭で触れた textwidth=0 説 と formatoptions=q 説 をもって解決したので、ひとまず fix としたのです。

が、今になって分かった事は、どうも解ではなかった様子。みたい?

.vimrc には set tw=0set fo=q と定義しても、勝手に改行が発動する。

なぜ?

で、本当はこんな事を調べたくてアクション起こしたんじゃないので、後にしようと思ったのですが、
度々遭遇するこの振る舞いに、いよいよカッとなって、アタックすることに。

:h formatoptions
:h fo-table

使った道具

いずれも、vimコマンドライン でのお話。

で。
読み込むファイルは ~/.vimrc だけでなく色々あって、色々読み込まれているうちに、後に読んだ内容が、陰で書き換えていた、とかな話は視界にチラチラ入ってきてはいたので、恐らくこんなんだろうと、そのセンを狙う。

まさか、自分がこんな部位に手を出すことになるだろうとは思ってもいなかったわけで。

:scriptnames

設定ファイルやスクリプトが、どう読み込まれているか、を見るのに。

~/.vimrc で set tw=0set fo=q としているのに、何故効いていないのか、それを知りたくて。

実は、これを知ったキッカケはコチラだったりするのですが ...;

読み込まれたスクリプトは    :scriptnames にて確認できます。

:h scriptnames

:verbose set {値を知りたいオプション}?

そのオプションが、どこの、どんな値が効いているのかを知りたくて。

今回ですと、formatoptions(fo) とか、textwidth(tw) とかで、例えば、formatoptions であれば、:verbose set fo?
もちろん、fo と略ではなくて、:verbose set fo? とフルでも同じ。

これをするとコマンドラインに、fo の値と、そのリソースが出力される。
例えばこんな感じに。;

  formatoptions=tcqmM
    Last set from /opt/homebrew-cask/Caskroom/macvim-kaoriya/latest/MacVim.app/Contents/Resources/vim/vimrc

ちょーベンリ!

こんなことが出来ること知ったキッカケは、コチラでした。;

However, set fo? showed formatoptions=croql.

:set fo? でも良いのですが、個人的に、どこのが悪さ効いているのも知りたかったので、verbose 入れることにしてます。

:h set-verbose
:h set
:h E518

こんなかんじで

まずは一旦、~/.vimrc を真っ新にし、;

  1. twfo のみを定義したり外したり、
  2. そしてその値をチマチマ変えながら、
  3. :so なり再起動したりしては適宜 :scriptnames 走らせ、
  4. :verbose set fo? やら :verbose set tw? やらを叩いて、結果を確認...

と言ったことを、ちまちまと、バカの一つ覚えの如く繰り返したわけです。

つか、もっとスマートは方法あるとは思ってみるのですが、いかんせん orz...あったら知りたいdesu。

わかったり、わからなかったりしたこと

formatoptions オプションのデフォルトは "tcq"

ちなみに "t" とか "c" とか言うのは、"フラグ" 言うらしい。

詳細はヘルプ、:h formatoptions:h fo-table で良いと思います。
こんな自分でも、このヘルプの説明で何となく理解できたので。

その他には。;

» vimが勝手に自動改行するのを回避する方法

fo オプションの設定について気を付けること

まずは結び方。

"=" で結ぶより、"-=" や "+=" が良いらしい。

将来追加されるフラグによる問題を避けるため、コマンド ":set" では "+=" と "-=" を使うこと |add-option-flags|。

:h formatoptions

次に、複数のフラグを定義したい時は、ひとつずつやること、だと。

Note フラグは1個ずつ追加したり取り除いたりするよう注意。オプション 'guioptions' が "ab" という値であるとき、"set guioptions-=ba" は機能しない。なぜなら、"ba" という文字列は現れていないからである。

:h add-option-flags

順番は vimrc >> .vimrc >> vim.vim な感じ

ここでは、なるたけ単純に、~/.vimrc ファイルを扱うケースを想定して進めたいと思います。*1

:verbose set fo? 叩いて、fo を最後に設定しているリソースとして、どうやら 3 つにまとまる様子。
vimrcに、おなじみの .vimrc、そして ftplugin の vim.vim

で、これをリストにしたのが以下表。
なお、パスは長くなりすぎるとアレなので、伝わる程度で。

ファイル パス
vimrc MacVim.app/Contents/Resources/vim/vimrc
.vimrc ~/.vimrc
vim.vim MacVim.app/Contents/Resources/vim/runtime/ftplugin/vim.vim

:scriptnames で見ると、fo の値は、どんな感じで上書きされ、定義されていくかが見えるかと思います。

この読み込みの流れと、それによる fo 値の関係を考えてみたのが下の表。
一応、~/.vimrc では fo=q と設定しているとして。

リソース 設定内容 fo の値の状態
0 デフォルト "tcq" "tcq"
1 vimrc set formatoptions+=mM "tcqmM"
2 .vimrc 例. set fo=q "q"
3 vim.vim setlocal fo-=t fo+=croql "croql"

で、この場合ですと最終的に fo は "croql" となるのかな、と思います。

結果、
この状態でコメント行を書いていると、ある箇所で自動改行されてしまって、
新規で、行がコメント行として追加される。

となるみたい、な感じですか?

set と setlocal とか

setsetlocal があって、その違いは分かるのですが。

例えば今回の場合ですと、
~/.vimrc の後に ftplugin の {ファイルタイプ}.vim を読み込んでいるはず。
なのに、~/.vimrc の設定が効いている。上書きされていない様子。ん?

また、今回のケースだと set を使うと上手くいかないらしい。
setlocal を使うべきと。

setではなくsetlocalを使うこと。setでは.vimrcの設定を完全に上書きし、rubyファイルと同時に他の種類のファイルを開くとそちらにも影響してしまう。

うんうん。わかる。

そこではバッファローカルな設定を行うので:setlocalを使います。:setを使ってはいけません。

うん、そうそう。

setlocal は 《ローカルな値のみを変更するので》、《カレントバッファ/ウィンドウについてローカルな値のみを設定する》 ものである、と。
確かに。

そこまではいい。こんなレベルの自分でも理解できる。

で、喉のつっかえは、ここから先。
これが今回の、よくわからなかったりしたこと。いずれも今回のケースを前提として。;

  • set ではなく setlocal だと上手く行く、その理由は何にあるのか。
  • あと、今回の冒頭のようにすると何故に、後に読み込まれるファイルのスクリプトではなく、~/.vimrc の設定が効いてくれるのか。
  • さらには、もしかして、set と setlocal で、何か優先順位みたいなのあったりするんだろーか。

とかとか、この辺りが、もやもやと。
...したままでも、まぁ、今回はうっちゃって、この点に関しては、おいおい、と言うことで(笑

:h local-options
:h setlocal

はい、おしまい。

*1:このパラグラフでは、言葉足らずで、色々誤解を生むかもしれませんが、できるだけスッキリ進めたいので、現実的な細部はそのまま触れずに簡略化して、極めて大雑把に表現してます。