rcmdnk's blog

iSK PROFESSIONAL HI-FI HEADPHONE 黒 HP-3000

Vimでたまにcwを使って書き換えとかを行うときに どうも余計に消しすぎてる感じがして 気になってたんですが、 それがシェル用のシンタックスファイルのせいだった件について。

起こっている問題

シェルスクリプト等を書いている時に、 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も読み込んでいます。

VimでMarkdownの環境を整える その2

原因が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_iskg:sh_noiskというオプションが用意されてますが、 通常、何もセットしてないと

1
setl isk+=.

が実行される事になります。 isk(iskeyword)は、そこに含まれるものは区切り文字にならないもの、 と言った感じの物で、w等の動作に影響します。

つまり上の設定では.は単語中の文字列とみなされ、 abc.shは全体で1つの単語として見られ、wでは一区切りにされてしまいます。

解決策

上の但し書きにありますが、g:sh_noiskを設定すればこの設定は無視されます。

AFAICT “.” should be considered part of the iskeyword

等と言っていますが、そんなことはなかろう、ということで これを無視するため、~/.vimrcの中に

1
let g:sh_noisk=1

と書いておけばOK(別に値が1で無くてもg:sh_noiskが定義されてればOK)。

恐らく他のファイルタイプ等でこの値を使ってるものは無いと思いますが、 もし気にするなら

1
autocmd FileType sh,markdown let g:sh_noisk=1

とか、ファイルタイプを指定しておいてあげればより安全です。

Sponsored Links
  1. ちなみに余談ですがAFAICTって使ったことなかったですが As far as I can tellの略だそうです。

    なんかここではそんな勝手なこと言われても、と言う感じがしないでもないんですが。。。

Sponsored Links

« tmuxとscreenのそれぞれの優れてる点 VimのNeosnippetを使ってみる: Octopress用のsnippetも作ってみる »

}