Upload
cohama
View
18.238
Download
5
Embed Size (px)
DESCRIPTION
Citation preview
Vim script とvimrc の正しい書き方
2013/9/7 Nagoya.vimcohama / @c0hama
もくじ
1. Vim script とは?2. 文法、変数、式3. 制御構文4. 関数、コマンド、autocmd5. vimrc について6. vimrc の正しい書き方
1. Vim script とは?
さっきの復習
● :から始まるコマンドをExコマンドと呼ぶ● :write とか :quit とか :split とか
Vim script とは?
● Ex コマンドの : をとって適当なファイルに縦に
並べて書きます● これが Vim script です● vimrc は Vim が起動時に自動で実行する Vim
script ファイル
Vim script が何故重要か?
● みんなプラグイン書きましょう● vimrc は Vim script で書く● つまり、Vim script を知っているとより凝った設
定を書くことができる○ Ruby の時はインデント幅 2、JavaScript は 4○ 保存時に行末スペースをすべて削除○ 全角スペースを可視化する○ etc
注意
❖ Vim script は vi からの後方互換性をひたすら守りながら進化してきた言語です
❖ Vim の進化とともにいろいろな機能が後付けされてきました
❖ という理由があるので言語仕様に文句を言わない(あきらめが肝心)
2. 文法、変数、式
Vim script の文法
❖ Vim script は全て Ex コマンド
❖ 大半は Ex コマンド + その引数という構文になっている
❖ コマンドの引数がどのように解釈されるかは Ex コマンドによって異なる
: echo "hello, world"vimrc に書くときは : は不要
Ex コマンド 引数
Vim script の例
❖ echo a b➢ 変数 a と b の内容を出力する
❖ map a b➢ a というキー入力を b というコマンドに割り当てる
❖ set foldmethod=marker➢ foldmethod というオプションに文字列 "marker" を設
定する➢ = の両側にスペースを入れることはできない
❖ let msg = "marker"➢ msg という変数に文字列 "marker" を設定する
Vim script を書く上で重要なこと
● :help を引く
● どの Ex コマンドがどういう引数をとるかは全て :help に書いてある
● あと、引数を省略した場合とか ! を付けた場合とか
変数
❖ let {変数名} = {式}➢ 例) let name = "cohama"➢ let x = 1➢ let x += 1
注意➢ x += 1 のようには書けません。
➢ これは :x というコマンドに += と 1 という引数を渡すと
いう意味 = Vim が終了する
データ型
❖ 数値➢ 1 -3 0x2A 0777
❖ 浮動小数点➢ 1.5 1.0e3
❖ 文字列➢ "hoge" '\fuga' "\u0061"
❖ リスト➢ [1, 2, "hoge", [0.5, 1.2]]
❖ 辞書(連想配列)➢ {"xyz": 123, "abc": [1, 2]}
変数のスコープ
❖ トップレベルに書くとグローバル変数になる❖ 関数の中に書くとローカル変数❖ その他は明示的に指定する
➢ g:hoge => グローバル
➢ l:fuga => ローカル
➢ s:piyo => スクリプトローカル
➢ a:abcd => 関数の引数
➢ b:xxxx => バッファローカル
➢ w:yyyy => ウィンドウローカル
❖ プラグインの設定でよくグローバル変数を使う❖ バッファローカルもたまに使う
式
❖ 式が必要とされている場所では、式が使える❖ 数値計算
➢ 1 + 1.5 a * 2 (3/2 + 1) % 4
❖ 文字列連結➢ "hoge" . "fuga"
❖ リスト連結➢ [1, 1, 3] + [4, 5]
❖ 比較➢ 3 > 2 "hoge" =~# "^ho.*"
❖ 条件演算子➢ (a == 42) ? "correct" : "wrong"
コメント
❖ Vim script におけるコメントは "❖ ただし、コメントを書けない場合があるので注意
" これはコメント
let a = 1 " これもコメント
map a b " これはコメントではない!
3. 制御構文
if {condition}{statement}
endif
if {condition}{statement1}
elseif {condition}
{statement2}
else
{statement}
endif
条件分岐
if g:is_windows
colorscheme molokai
else
colorscheme desert
endif
例) Windows とそれ以外でカラースキームを変える
ループ
for {var} in {list}
endfor
while {cond}
{statement}
endwhile
for i in range(1, 10)
echo i
endfor
例) 1 から 10 までを出力する
例外
try
{try-block}
catch /{pattern}
{catch-clause}
finally
{finally-clause}
endtry
throw {expr}
Vim script で正しく例外処理を行うのは結構難しい
4. 関数、command、autocmd
関数
❖ もちろん Vim script にも関数はある❖ 組み込み関数
➢ str2nr() : 文字列から数値を返す
➢ sin() : sin 関数
➢ len() : リストまたは辞書の要素数を返す
➢ getpos() : カーソルの位置を返す
➢ rename() : ファイルの名前を変更する
ユーザ定義関数
❖ 自分で関数を作る" 引数を2倍して返す関数
function! Double(x)
return 2 * a:x
endfunction
" 保存してウィンドウを閉じるユーザ定義関数
function! WriteQuit()
write
quit
endfunction
ユーザ定義コマンド
❖ :コマンドもユーザで定義できる" 1行目を削除するExコマンド
command! DeleteFirstLine 1delete
" 複雑なことを行うExコマンド
command! DoSomething call DoSomething()
" 引数を取る場合
command! -nargs=* Hoge call Hoge(<f-args>)
autocmd
特定のイベントが発生した際に自動的にコマンドを実行させる
autocmd [group] {event} {pat} {cmd}
" 保存時に行末スペースを取り除く
autocmd myvimrc BufWritePre * %s/\s\+$//e
イベント
autocmd に指定できるイベントの例
❖ BufWritePre➢ バッファ全体が保存される直前
❖ BufWritePost➢ バッファ全体が保存された後
❖ WinEnter➢ 別のウィンドウに入った後
❖ WinLeave➢ ウィンドウから離れる前
❖ FileType➢ filetype が設定された時
5. vimrc について
vimrc とは
Vim の設定ファイル
Vim を Vim として使うために(ほぼ)必須
vimrc があると Vim は自動的に 'compatible' オプションをオフにする(Vim が Vim として動作するようになる)
vimrc の配置
❖ Unix 系の場合➢ $HOME/.vimrc➢ $HOME/.vim/vimrc (Vim 7.4 から)
❖ Windows の場合➢ $HOME/_vimrc➢ $HOME/vimfiles/vimrc (Vim 7.4 から)
❖ .vim (または vimfiles) で全てを管理するのがおすすめ❖ ちょっと Vim script を書くだけで、Unix 系と Windows の設
定を共有することも可能 ('runtimepath' を設定)
vimrc には何を書くの?
❖ オプション❖ マッピング
他には➢ ユーザ定義コマンド➢ プラグインの設定
などなど
オプション
❖ Vim の設定といえばオプション❖ 数えたら 350 くらいありました
" オン(オフ)にする
set number
set nonumber
" バッファローカル
setlocal tabstop=4
setlocal foldmethod=marker
オプション
" デフォルト値に戻す
set runtimepath&
" オンとオフを切り替え
set cusorline!
" オプションを変数のように設定・取得
let &shiftwidth = g:indent
let &tabstop = &shiftwidth
おすすめのオプション
...とかを当てにしない
いろいろ試しながら自分に一番合う設定をさがしましょう:options
:help options
:help option-list
「Vim オプション 一覧」とかで検索して出てくるやつは情報古い
ネットよりも:help
マッピング
あるキーの入力を別のコマンドに認識させる
" <F5> を押すと先頭行に #!/bin/sh と入力map <F5> ggO#!/bin/sh<ESC>
マッピングの種類
❖ モード別のマッピング➢ nmap : ノーマルモード
➢ imap : インサートモード
➢ xmap : ビジュアルモード
※ 他にもある
❖ 再マップする、しない" : と ; を入れ替え
noremap : ;
noremap ; :
※ 再マッピングする意思がなければ基本的には nnoremap
より柔軟なマッピング
<expr> をつけると式の評価結果にマッピングできる
" 下の2つは同じ意味
nnoremap j gj
nnoremap <expr> j "gj"
" 先頭行に変数の値を挿入する
let g:shebang = "#!/bin/sh"
nnoremap <expr> <F5> "ggO".g:shebang."\<Esc>"
さっきのnnoremap <F5> ggO#!/bin/sh<ESC>
6. vimrc の正しい書き方
Vim script には罠がいっぱい
正しい書き方を Tips 形式で紹介します
vimrc を正しく書く
vimrc を一瞬で開く、反映させる
Vim のナイスな設定を思いついたら即座に vimrc を開いて編集することが重要
nnoremap <F5> :<C-u>edit $MYVIMRC<CR>
gvimrc も必要なら追加
この部分をお好みのコマンドに変えよう・split (水平分割)・vsplit (垂直分割)・tabedit (新規タブ)などなど
vimrc を一瞬で開く、反映させる
vimrc を編集したら即座に反映させましょう
nnoremap <F6> :<C-u>source $MYVIMRC<CR>
\ :source $MYGVIMRC<CR>
※再読み込みすると問題が発生する場合がある。これを防ぐにはリローダブルな vimrc を書く必要がある
リローダブルな vimrc を書く
❖ 詳しくは kana さんの書いた「Vim の極め方」を参照のこと(http://whileimautomaton.net/2008/08/vimworkshop3-kana-presentation)
" 追加する形のオプションは一旦デフォルト値を設定
set backupdir& backupdir+=hoge
" あるいは起動時しか実行されないようにする
if has('vim_starting')
set runtimepath^=~/.vim
endif
リローダブルな vimrc を書く
" autocmd が複数登録されないように最初に消しておく
augroup myvimrc
autocmd!
augroup END
" 必ず augroup 名を指定して書く
autocmd myvimrc FileType scala setlocal sw=2
グローバルとローカルの設定を区別する
❖ 以下の設定の何が悪い?
" JavaScript のときはインデント幅4autocmd myvimrc FileType javascript
\ set shiftwidth=4 tabstop=4 softtabstop=4
:set はグローバルな設定値も変更してしまう!
代わりに :setlocal を使う
グローバルとローカルの設定を区別する
❖ 正しい設定
" JavaScript のときはインデント幅4autocmd myvimrc FileType javascript
\ setlocal shiftwidth=4 tabstop=4 softtabstop=4
グローバルとローカルの設定を区別する
❖ 以下の設定の何が悪い?
" 行末スペースをハイライトで可視化する
match Error /\s\+$/
:match はカレントウィンドウにしか作用しない!
(しかも vimrc 読み込み時の最初の1回だけ)WinEnter イベントを使ってカレントウィンドウが変わる都
度呼ばれるようにする
グローバルとローカルの設定を区別する
❖ 正しい設定
" 行末スペースをハイライトで可視化する
autocmd myautocmd VimEnter,WinEnter *
\ match Error /\s\+$/
マッピングを使い分ける
❖ マッピングを定義するためのコマンドはモードごとに細かく分かれている➢ nmap➢ xmap➢ imap➢ cmap➢ smap➢ omap
マッピングを使い分ける
❖ 以下の設定で何が起こるか?
" 見た目通りに移動
noremap j gj
noremap k gk
ただの :map はノーマル+ビジュアル+セレクト+演算待ち
モードに作用する・セレクトモードで j が入力できなくなる
(neosnippet のようなプラグインで困る)・dj のようなコマンドの挙動まで変わってしまう
マッピングを使い分ける
❖ こっちのほうが良さげ" 見た目通りに移動
nnoremap j gj
xnoremap j gj
nnoremap k gk
xnoremap k gk
" omap を残す場合
noremap j gj
sunmap j
noremap k gk
sunmap k
既存のコマンドを潰さないようにする
❖ 以下の設定の何が悪い?
" Ctrl+A で全選択
nnoremap <C-a> ggVG
<C-a> はカーソル下の数値をインクリメントする便利なコ
マンド。これを潰してしまうなんてもったいない!
既存のコマンドを潰さないようにする
❖ 正しい設定
" g Ctrl+A で全選択
nnoremap g<C-a> ggVG
マッピングする前に :help ^a などで調べること
既存のコマンドを潰さないようにする
❖ 以下の設定の何が悪い?
" <Tab> で現在行をインデント
nnoremap <Tab> >>
Vim では <Tab> と <C-i> が同一視される。
<C-i> は進むコマンドなので潰すのはもったいない!
同一視されるのは他にも <C-m> と <CR> など
既存のコマンドを潰さないようにする
❖ 正しい設定
" <Tab> で現在行をインデント
nnoremap <Tab> >>
" 進むコマンドを退避
nnoremap \<C-i> <C-i>
まとめ
Vim script はチューリング完全
Vim script でなんでもできる
vimrc を書いて Vim を自分に最適化
罠に注意
おわり