起こっている問題
シェルスクリプト等を書いている時に、
wを使うと.
を単語内の文字とみなしてその先まで進んでしまう現象です。
つまりabc.sh
みたいな拡張子付きの文字列のabc
の部分だけ変更したいと思って
a
の部分でcwと押すと、
sh
の部分まで全部消えてしまって書き直さないといけなくなります。
syntax/sh.vim
この現象の原因はsyntax/sh.vimの中にありました。
syntax/sh.vimはシェルスクリプトなど、ファイルタイプがsh
の時に
読み込まれます。
また、Markdownを書くときにも、 joker1007/vim-markdown-quote-syntax というプラグインを使ってコードブロック内等をそれぞれの言語でハイライト 出来る様にするためにsh.vimも読み込んでいます。
原因がsh.vimの中にあったので これまでシェルスクリプトを書いたりMarkdownを書いたりするときに wの挙動がおかしくなっていたようです。
sh.vimの中に
syntax/sh.vim
1
2
3
4
5
6
7
8
9
10" AFAICT "." should be considered part of the iskeyword. Using iskeywords in
" syntax is dicey, so the following code permits the user to
" g:sh_isk set to a string : specify iskeyword.
" g:sh_noisk exists : don't change iskeyword
" g:sh_noisk does not exist : (default) append "." to iskeyword
if exists("g:sh_isk") && type(g:sh_isk) == 1 " user specifying iskeyword
exe "setl isk=".g:sh_isk
elseif !exists("g:sh_noisk") " optionally prevent appending '.' to iskeyword
setl isk+=.
endif
といった箇所があります1。
ここでg:sh_isk
とg:sh_noisk
というオプションが用意されてますが、
通常、何もセットしてないと
1
|
|
が実行される事になります。
isk
(iskeyword
)は、そこに含まれるものは区切り文字にならないもの、
と言った感じの物で、w等の動作に影響します。
つまり上の設定では.
は単語中の文字列とみなされ、
abc.sh
は全体で1つの単語として見られ、wでは一区切りにされてしまいます。
解決策
上の但し書きにありますが、g:sh_noisk
を設定すればこの設定は無視されます。
AFAICT “.” should be considered part of the iskeyword
等と言っていますが、そんなことはなかろう、ということで これを無視するため、~/.vimrcの中に
1
|
|
と書いておけばOK(別に値が1で無くてもg:sh_noisk
が定義されてればOK)。
恐らく他のファイルタイプ等でこの値を使ってるものは無いと思いますが、 もし気にするなら
1
|
|
とか、ファイルタイプを指定しておいてあげればより安全です。
-
ちなみに余談ですがAFAICTって使ったことなかったですが As far as I can tellの略だそうです。
なんかここではそんな勝手なこと言われても、と言う感じがしないでもないんですが。。。 ↩