流行ってるみたいなので遅ればせながら便乗。需要?何それおいしいの?
- Perl基礎文法最速マスター - サンプルコードによるPerl入門 - Perlプログラミングの基礎から応用まで
- Route 477(2010-01-25)
- PHP基礎文法最速マスター - Shin x blog
- Python基礎文法最速マスター - LazyLife@Diary
- VBA基礎文法最速マスター - いろいろ解析日記
- Java基礎文法最速マスター - いろいろ解析日記
- Bash基礎文法最速マスター - いろいろ解析日記
- Haskell基礎文法最速マスター - think and error
- Brainf*ck基礎文法最速マスター - このブログは証明できない。
- VBScript 基礎文法最速マスター - CX's VBScript Diary - VBScript グループ
- JavaScript基礎文法最速マスター - gifnksmの雑多なメモ
以下、Vim 7.2 を前提とします。
1. 基礎
echo コマンド
echo 'Hello, world!'
:echo コマンドの出力には必ず改行が含まれます。改行を含みたくない場合は :echon コマンドを使います。
echon 'Hello, ' echon 'world!'
代入
値の代入には :let コマンドを使います。
let a = 1
データの型
データには型があり、以下のいずれかです。
- 整数値
- 小数値
- 文字列
- リスト
- 辞書
- 関数参照
関数参照はこの記事では省略します。
実行
実行するには :source コマンドを使います。
source script.vim
シェルから実行する場合は -S オプションを使います。
vim -S script.vim
2. 数値
3. 文字列
文字列の表現
文字列はシングルクォートかダブルクォートで囲みます。
ダブルクォートの中では\t(タブ)や\n(改行)などの特殊文字を利用することができます。
シングルクォート内ではシングルクォート自身を表現するのにシングルクォートを 2 つ重ねます。それ以外の文字は一切展開されません。
let str = "abc" let str = 'def' let str = "abc\ndef" let str = 'That''s right!'
文字列操作
各種文字列操作です。
" 結合 let join1 = 'aaa' . 'bbb' let join2 = join(['aaa', 'bbb', 'ccc'], ',') " 分割 let record = split('aaa,bbb,ccc', ',') " 長さ let length = strlen('abcdef') " 切り出し let substr = 'abcd'[1] " b let substr = 'abcd'[0 : 1] " ab let substr = 'abcd'[ : 1] " ab let substr = 'abcd'[2 : ] " cd let substr = 'abcd'[1 : -1] " bcd " 検索 let result = stridx('abcd', 'cd') " 見つかった場合はその位置、見つからなかった場合は-1が返る
4. リスト
リストの表現
let list = [1, 2, 3]
リストの要素の参照と代入
let list = [1, 2, 3] let e0 = list[0] " => 1 let e2 = list[-1] " => 3 let e1_2 = list[1 : 2] " => [2, 3] let e_1 = list[ : 1] " => [1, 2] let list[0] = 10 let list[1] = 20 " => list == [10, 20, 3]
リスト操作
リストを操作する関数です。
let list = [1, 2, 3] " len(リストの長さ) let length = len(list) " 3 " remove(任意の要素を取り出す) let first = remove(list, 0) " first == 1, list = [2, 3] let last = remove(list, -1) " last == 3, list = [2] " insert(任意の位置に要素を追加) " (単純な関数の呼び出しには :call コマンドを使います。) call insert(list, 5, 0) " list == [5, 2] " add(末尾に要素を追加) call add(list, 9) " list == [5, 2, 9]
5. 辞書
辞書は、他の言語でハッシュテーブルや連想配列と呼ばれているデータ構造です。キーには文字列のみ使用できます。
辞書の表現
let dict = {} " 空の辞書 let dict = {'a': 1, 'b': 2}
辞書の要素の参照と代入
let a = dict['a'] let b = dict.b let dict['a'] = 10 let dict.c = 30
辞書操作
" 全てのキーをリストで取得 let keylist = keys(dict) " 全ての値をリストで取得 let valuelist = values(dict) " 全てのキーと値を [[key, value], ...] の形式のリストで取得 let itemlist = items(dict) " キーの存在確認 let exists = has_key(dict, 'a') " キーの削除 call remove(dict, 'a')
6. 制御コマンド
if コマンド
if 条件 endif
if 〜 elseif コマンド
他の言語のように else if ではなく elseif であることに注意しましょう。
if 条件 elseif 条件 endif
while コマンド
let i = 0 while i < 5 " 処理 let i += 1 endwhile
for コマンド
for はリストの中身を走査するコマンドです。
for e in [1, 2, 3] echo e endfor
7. その他の演算子
ここまでで出てきていない演算子です。
比較演算子
- ==
- !=
- >
- >=
- <
- <=
これらの意味は一般的な言語と同様です。数値同士の場合は数値比較、文字列同士の場合は文字列比較になります。
文字列と数値を比較した場合、文字列が数値に変換され、数値として比較されます。
文字列同士を比較する場合、大文字と小文字を区別するかは Vim の 'ignorecase' オプションに左右されます。このオプションを無視して比較するには以下の演算子を使います。
- 大文字小文字を区別する
- ==#
- !=#
- >#
- >=#
- <#
- <=#
- 大文字小文字を無視する
- ==?
- !=?
- >?
- >=?
- <?
- <=?
比較演算子のまとめです。
'ignorecase'次第 | 大小文字考慮 | 大小文字無視 | |
---|---|---|---|
等しい | == | ==# | ==? |
等しくない | != | !=# | !=? |
より大きい | > | ># | >? |
より大きいか等しい | >= | >=# | >=? |
より小さい | < | <# | <? |
より小さいか等しい | <= | <=# | <=? |
正規表現マッチ | =~ | =~# | =~? |
正規表現非マッチ | !~ | !~# | !~? |
== と != はリストや辞書の同値性テストに使えます。
let res = [1, 2, 3] == [1, 2, 3] " 1
is と isnot 演算子は、数値や文字列の場合は型変換を行わない厳格な比較をします。リストや辞書の場合は同一性テストをします。
let res = 1 is '1' " 0 let res = 1 is 1 " 1 let list = [0, 1] let res = list is [0, 1] " 0 let res = list is list " 1
8. 関数
関数は :function コマンドで定義します。ユーザ定義の関数名は組み込み関数名と区別するために大文字で始める必要があります。
function! Sum(v1, v2) return a:v1 + a:v2 endfunction
- function! の ! は、同名の関数を再定義する際に既存の関数を上書きすることを示します。スクリプトを再読み込みした時のために、基本的に付けておいた方が良いでしょう。
- 関数内で引数にアクセスするには、a: という接頭子が必要です。
同一スクリプト内でのみ使える関数(スクリプトローカルな関数)を定義するには、関数名の先頭に s: を付けます。この場合 s: 以降の関数名は大文字で始める必要はありません。
function! s:sum(v1, v2) return a:v1 + a:v2 endfunction
可変長引数を使いたい場合は引数の最後を ... にします。可変長引数にアクセスするには以下のようにします。
- a:0
- 可変長部分の引数の数
- a:n
- n は数字。n 番目の引数にアクセスする。a:1 a:2 など。
- a:000
- 可変長部分を表すリスト。ぶっちゃけこれを使えば前者の 2 つはなくてもなんとかなる。
function! s:sum(v1, ...) let num = a:v1 for i in a:000 let num += i endfor return num endfunction
9. ファイル入出力
Vim のバッファを経由する方法もありますが、ここでは Vim の環境に影響を与えない方法を示します。
readfile() 関数
ファイルの中身を行区切りのリストで取得します。
for line in readfile(fname) if line =~ 'Date' echo line endif endfor
writefile() 関数
行区切りのリストをファイルに書き出します。
call writefile(['line1', 'line2', 'line3'], fname)
知っておいた方がよい文法
真偽値
:if :while や条件演算子等の真偽値が求められる場所では、値は数値に変換され、その値が 0 かそれ以外かで判定されます。0 の時は偽、それ以外の時は真です。
値の変換
先ほどの真偽値や、文字列の連結、数値演算など特定の箇所では値は暗黙的に適切な値に変換されます。
整数値が文字列になる場合は、10 進数表記の文字列になります。
文字列が整数値になる場合は、リテラル表記と同様に解釈されます。文字列の末尾にゴミがあっても無視されます。変換できない場合は 0 に変換されます。
それ以外の暗黙な変換は行われません。整数値と小数値の変換も暗黙的には行われないので注意してください。
変換が必要な場面で型の変換ができない場合はエラーになります。
値の再代入
すでにある変数に値を代入する場合、元の値と新しい値が型変換可能な型でない場合はVim は融通が利かないのでエラーになります。
その場合は :unlet コマンドを使って一旦変数を削除する必要があります。
let a = [1,2,3] "let a = 1 " エラー! unlet a " 一旦 unlet する必要がある let a = 1
これは特に様々な値が入ったリストを :for で回す際に注意が必要です。
for i in [0, 1.1, ['list'], 'string'] echo i unlet i " i は for の部分で再代入されるので unlet が必要 endfor
変数が定義されているかどうかの判定
exists() 関数を使います。
let e = exists('var1')
便利な関数
- range()
- 連番のリストを生成します。:for と組み合わせると効果的です。
- range(3) == [0, 1, 2]
- range(1, 3) == [1, 2, 3]
- range(1, 5, 2) == [1, 3, 5]
- map(expr, string)
- 第一引数のリストの各要素を string で渡した文字列を評価した値に変換します。v:val が要素として参照できます。
- 辞書も渡せます。辞書の場合は辞書の各値が変換される他、v:key でキーを参照できます。
- 渡したリスト自体が書き換えられるので注意してください。コピーは作られません。
- map([1, 2, 3], 'v:val + 1') == [2, 3, 4]
- filter(expr, string)
- 第一引数のリストの各要素を string で渡した文字列を評価した結果が真になるもののみになるようにフィルタリングします。v:val が要素として参照できます。
- 辞書も渡せます。辞書の場合は辞書の各値が評価される他、v:key でキーを参照できます。
- 渡したリスト自体が書き換えられるので注意してください。コピーは作られません。
- filter([1, 2, 3], 'v:val % 2 == 1') == [1, 3]
リスト代入
リストを複数の変数にばらして代入できます。代入先の変数の数と代入元のリストの長さは同じである必要があります。
let [key, value] = ['key', 'value'] let [e1, e2; rest] = ['e1', 'e2', 'rest1', 'rest2']
例外処理
専用のコマンド群があります。
try throw "エラーメッセージ" catch /error/ " エラーメッセージにマッチする正規表現 catch " 空の場合は必ずマッチする " ... 例外処理 ... finally " 必ず行われる処理 endtry