vim script ことはじめ#1

ちょっとどうしても vim script で作りたい物があるので、vim scriptのお勉強をしようと思います :)

とても細かく解説されているドキュメントがありました。

Vim documentation: usr_41
http://vim-jp.org/vimdoc-ja/usr_41.html

とりあえずちょっと書いてみる

vim立ち上げて、次のようなコードを記述した後に

for in range(1, 4)
    echo 'count is ' i
endfor

記述したコードをすべてヤンクし、コマンドモードに移って

:@"

と入力して実行すると、ヤンクしたスクリプトが実行出来るみたいです!
知らなかった :(

一応実行結果

:@"
:count is  1
:count is  2
:count is  3
:count is  4

変数定義

グローバル

let [変数名] = [値]

ローカル

let s:[変数名] = [値]

利用されている変数名一覧表示

コマンドモードで下記を実行

:let

変数削除

スクリプト終了時に利用されている変数は自動で解放されることは無いので、ちゃんとお掃除してあげましょうという内容

削除の方法は

unlet s:[変数名]

ですが、上記の方法だと変数が存在しなかった場合にエラーになるようなので、実際には次のような削除の仕方をしたほうが良いみたいです。

unlet! s:[変数名]

変数の存在チェック

exists関数を使うみたいです。
実際の使い方は

" 例として変数名 hoge
if !exists('s:hoge')
    let s:hoge = 0
endif

if文等で指定する評価値についての注意

ちょっと話逸れますが、vim では 数値の 0 以外の値は全て true と判断されるようです。

また、if文等の評価式に文字列などを指定した場合、暗黙で数値型へ型変換されます。その際に文字列の先頭に数値が入ってない場合は全て 0 になるので少し注意が必要です。

例で上げると下記は false と判定されます

if 'true'

文字列定義

ここはJavaScriptとかと大体同じ感じがします

let s:str = 'シングルクォートで指定する場合'
let s:str = "ダブルクォートで指定する場合"
let s:str = '文中に"ダブルクォート"を利用したい場合'
let s:str = "文中に'シングルクォート'を利用したい場合"
let s:str = "バックスラッシュで\"エスケープ\"もOK"

と思ったけど、なんか特殊な縛りありました

シングルクォートの文字列は特殊

シングルクォートで定義した文字列の文中でシングルクォートを利用する場合はバックスラッシュでは無く '' と記述する

let s:str = 'バックスラッシュで''エスケープ''もOK'

シングルクォートで定義した文字列では特殊文字は使えない

特殊文字については例としては下記のようなもの

\t              <Tab>
\n              <NL>, 改行
\r              <CR>, <Enter>
\e              <Esc>
\b              <BS>, バックスペース
\"              "
\\              \, バックスラッシュ
\<Esc>          <Esc>
\<C-W>          CTRL-W

ということで、大人しく文字列には "" を使いましょう :(

文字列結合

文字列結合はPHPとかと同じくドット繋ぎです

"サンプル" . "です"

条件式

if

if 評価式
elseif 評価式
else
endif

評価式につては、通常のプログラムと大体同じ感じです == とか != とか

ただ、2つほど特殊(?)なのがあるみたいです。

右辺パターンにマッチする

if str =~ " "

右辺パターンにマッチしない

if str !~ " "

str は文字列が入っている変数と思ってください


式の実行

引数にくっつけた式を実行するには次のとおり

:execute [コマンド式]

関数

関数定義は次の通り

function 関数名(引数1, 引数2)
    処理
endfunction

※注意点
関数名は大文字から始める必要があるようです

なので、実際に記述する際は

function SampleFunc(num1, num2)
    let total = a:num1 * a:num2
endfunction

といった形になります。
また上記で記述している関数内で定義している total は、関数内でのローカル変数になります。

関数内で取り扱う変数にはプレフィックスが必要なものがあります

  • g:hoge
    • 関数内からグローバル変数にアクセスする際に必要
  • a:hoge
    • 関数の引数として渡された変数にアクセスする際に必要
  • hoge
    • 関数内のローカル変数

hoge は変数名

関数の再定義

同じ関数名で再定義を行う場合は、!マークを付けて記述すれば良いみたいです

function! SampleFunc(num1, num2, num3)
endfunction

関数の呼び出し

call SampleFunc(1, 2, 3)

関数呼び出し - range編

vimでは少し特殊なrange指定で関数を呼び出すといった方法があります。
具体的な呼び出し方法は次のような形になります

まず、次のような関数を定義し

function! RangeFunc()
    echo "line " . line(".") . " contents: " . getline(".")
endfunction

実行は次の通り

1,3call RangeFunc()

超違和感(´・ω・`)・・・

call の手前に書いてある 1,3 が実行する関数側に渡す range の範囲値になります。上記で指定しているのは実行する際に1行目から3行目までを1行ずつ実行するみたいです。

実行してみると次のような結果が出力されます

line 1 contains: function! RangeFunc()
line 2 contains:     echo "line " . line(".") . " contains: " . getline(".")
line 3 contains: endfunction

関数内で使えるものは色々とありますが、今回使っているのは

  • line(".")
    • 現在実行されている range の行数を取得
  • getline(".")
    • 現在実行されている行を1行すべて取得する

こんな感じで指定を行えるのは、vim上で文字列処理を色々するからなのかなーと思ったり :(

関数呼び出し - 可変長引数編

可変長な引数の呼び出しもOKです!

function! ArgsFunc (param, ...)
    echo "param is " . param
    let index = 1
    while index <= a:0
        echo "arg " . index . " is " . a:{index}
        let index = index + 1
    endwhile
endfunction

呼び出し時は

call ArgsFunc("arguments", 1, 2, 3, 4, 5)

とやると、出力結果は

param is arguments
args 1 is 2
args 2 is 3
args 3 is 4
args 4 is 5

こんな感じになります。

さすがに長くなってきたので、続きは別エントリーに。
ではでは。