Vimscriptの基本
vim参考
非常にわかりやすかったので自分なりにかみ砕いて写経
Vim scriptでプラグインを作ろう~Vimはいいぞ!ゴリラと学ぶVim講座(8)
vimのコメントアウト
"コメント
exコマンドってなんだ
":から始まる文字列
:Command
.vim拡張子について
vimのexコマンドをまとめたファイル
#vimファイルを読み込む(実行する)
:source file
内容
"gorillaと出力する
echo 'gorilla'
使えるデータ型
データ型 | 例 |
---|---|
整数、少数、16進数 | 1,1.5,0x1E |
文字列 | ‘a’,”a” |
辞書 | {‘name’:’tarou’} |
リスト | [1,2,3] |
文字列
'str'と"str"の違い
""では\tなどの特殊文字が展開される(タブスペース)
文字列の結合
.で結合できる
"aaabbbが出力される
echo 'aaa' . 'bbb'
変数の宣言
変数の命名規則
変数にはアルファベット・数字・アンダースコアが使える
数字から始まる変数は使うことができない
"すべてエラーになる
1str
two-xxx
aaa+bbb
twoでエラーになるのは面白い
宣言
let name = 'tarou'
echo name
代入
let name = 'tarou'
let name = 'suzuki'
echo name
辞書/連想配列
let animal = {'name':'gorilla', 'age':27}
" {'name':'gorilla', 'age':27}
echo animal
"get(辞書名,key,default)
"gorilla
echo get(animal,name,'none')
"keyが存在しない場合はdefault値が返される
辞書に要素を追加する
二種類のやり方がある
let animal = {}
"{dict}.{key} = {value}
let animal.name = 'gorira'
"{dict}[{name]} = {value}
let animal['age'] = 27
辞書から要素を削除する
"{'age': 27 , 'name': 'gorilla'}
echo animal
"call remove({dict},{key})
call remove(animal, 'age')
"{'name': 'gorilla'}
echo animal
リスト
異なるデータ型を保持できる
let anko = ['cat',10,{'name':'gorilla'}]
" ['cat',10,{'name':'gorilla'}]
echo anko
要素を取り出す
"list名[id]
"cat
echo anko[0]
"get(list名,id,default値)
"{'name':'gorilla'}
echo get(anko,2,'none')
"keyが存在しない場合はdefault値が返される
listを一つの文字列として返す
let anko = ['hello', 'my' , 'name' ,'is', 'gorilla']
"hello my name is gorilla
echo join(anko,' ')
"hello-my-name-is-gorilla
echo join(anko,'-')
変数のスコープ
接頭辞 | スコープ |
---|---|
g: | グローバルスコープ |
s: | スクリプトスコープ・スクリプトファイル内のみ利用可能 |
l: | 関数ローカルスコープ・関数内のみ利用可能 |
a: | 関数の引数・関数内のみ利用可能 |
v: | グローバルスコープ・vimがあらかじめ定義している変数 |
"グローバルスコープ。あらかじめvimrcなどで指定しておきPluginのon/offに使用したりできる
let g:file_path = '/home....'
"関数にもスコープをあてることができる
function s:hello(msg) abort
"関数内スコープ
echo a:msg
return 'done'
endfunction
"呼び出しもs:...になる
let text = s:hello()
if文
"{expr}=1:True
"{expr}=0:False
if {expr}
"do something
elseif {expr}
"do something
else
"do something
endif
三項演算子
"aの評価がtrueならb,falseならc
a ? b : c
論理和・論理積
"どちらかがtrueならtrue
echo 1 || 1
"どちらもtrueならtrue
echo 1 && 1
比較演算子
"大文字小文字の区別を無視する
"デフォルトでは無効
set: ignorecase
意味 | 演算子 | ignorecaseに左右されない演算子 |
---|---|---|
等しい | == | ==# |
等しくない | != | !=# |
大きい | > | ># |
大きいか等しい | >= | >=# |
同一インスタンス | is | is# |
異なるインスタンス | isnot | isnot# |
ユーザーの設定によって挙動が変わらないように基本#をつける
バッファ
"スクリプトスコープなのでコマンドで打つ際は注意
let s:session_list_buffer = 'SESSIONS'
"指定した名前でバッファを開く?
execute 'new' s:session_list_buffer
"移行このバッファにおける設定を決めていく
set buftype=nofile
"nnoremap... ノーマルモードにおいて
再帰的に実行しないキーマップ
キー入れ替えなども可能
"nmap... ノーマルモードにおいて
再帰的に実行するキーマップ
設定したいキーに他の設定があった場合それを呼び出す
下記のようにした際に無限ループが発生する
:nmap j gj
:nmap gj j
"<silent>... キーマップで実行されるコマンドがコマンドラインに表示されない
"<buffer>... 現在のbufferにのみキーマップを適用する
"<Plug>... キーを割り当てない・関数のように後から設定できる?
":<C-u><CR>... コマンドラインでCtrl-u / Enterを押したとき
"bwipeout!... bwコマンドbdがlsから消えるのに対して実際に削除されるコマンド
nnoremap <silent> <buffer>
\ <Plug>(session-close)
\ :<C-u>bwipeout!<CR>
"trim()... 文字列から文字を取り除く
nnoremap <silent> <buffer>
\ <Plug>(session-open)
\ :<C-u>call session#load_session(trim(getline('.')))<CR>
"決めた設定に対して代入のような動作?
nmap <buffer> q <Plug>(session-close)
nmap <buffer> <CR> <Plug>(session-open)
ウィンドウ
"すでに表示されている指定されたバッファーを開く(vim8.0以降追加機能
win_gotoid(id)
"読み込まれているが表示されていないバッファーを開く
win_getid('buffer名')
テキスト
テキストを取得
"n行のテキストを出力
echo getline(n)
"nからm行までのテキストを出力
echo getline(n,m)
"現在のカーソルがある行のテキストを出力
echo getline('.')
テキストを挿入
"行番号n+1にtextが挿入される。
"call append('行番号','text')
テキストを上書き
"もともとその行にあった文字列は消える。
"n行にstrが挿入される
call setline(n,str)
"listを挿入することもできる
"n行目からname
"n+1行目にage...をそれぞれ挿入(上書き)する
call setline(n,['name','age','add'])
カーソル
現在のカーソル位置を取得
:echo line(".")
:echo col(".")
"タプルで取得
:echo getpos(".")
カーソルを移動させる
:call cursor( n , m )
:let c = getpos(".")
:call setpos( '.' , c )
関数
"基本の形
function! Echo(msg) abort
echo a:msg
endfunction
function{!} 関数名(引数) {abort}
処理 echo {a:} msg
戻り値 return 'str'
endfuntion
{!}... 同名の関数がある場合上書きするオプション
{abort}... 関数内でエラーが起きた場合処理を終了するオプション
vimのデフォルトでは処理が継続される
{a:}... 関数内スコープの引数a:引数名
呼び出し方
function! MyName() abort
return 'SUZUKI'
endfunction
echo MyName()
EXコマンドの実行
"execute {expr}
"{expr}の実行結果をEXコマンドとして実行できる
"複数の引数がある場合スペースで結合される
"anko
execute 'echo "anko"'
"gorilla godzilla
execute 'echo' '"gorilla"' '"godzilla"'
外部コマンドの実行
"system(command)
"system(command,option)
"my name is gorilla
echo system('echo "my name is gorilla")
"どちらも可能
echo system('ls -la')
echo system('ls','-la')
Lambdaってなんだ
vim8.0で追加された機能
{引数 -> 式}で表現できる
"式を入れて計算できるようにするlambda
let F = { a,b -> a + b }
"3
echo F(1,2)
"javaでありがちなfilterとして機能するlambda
"PATHはdirectory
"取得したものがdirctoryじゃなければtrue
let F = { file -> !isdirectory(PATH . '/' . file ) }
"readdirは指定したディレクトリ内のファイルリストを得る
"引数として取得物(file名が送られている
let xxx = readdir("PATH",F)
現在実行中のファイルパスを取得する
"現在実行中スクリプトがあるディレクトリ
let s:dir = expand('<sfile>:p:h')
let s:py_path = s:dir . '/' . 'xxx.py'
"のxxx.pyを実行する
execute ':pyfile ' . s:py_path
"現在触っているファイルのカレントパス取得
:echo expand("%")
"現在触っているファイルのフルパスを取得
:echo expand("%:p")
"現在触っているファイルのカレントパスを拡張子抜きで取得
:echo expand("%:r")
"現在触っているファイル拡張子を取得
:echo expand("%:e")
"ファイルを指定して取得
:let = file_path
:echo fnamemodify(file_path , ":p" )