LoginSignup
9
6

More than 5 years have passed since last update.

`vimproc#system({expr})`の{expr}の展開のされ方

Last updated at Posted at 2013-07-19

この記事はVim Advent Calendar 2012 : ATND231日目の記事になります。

昨日の記事は@ujihisaさんのVim script初心者用入門記事でした。
なので、今回はVim scripterになると必ずお世話になるだろうvimproc.vim
具体的にはvimproc#system({expr})の{expr}の展開のされ方について説明します。


この記事で語ることは、基本的にvimproc#system()でのみで確認しています。
vimproc#system_bg()などでも同じ展開のされ方になると思いますが(たぶん)、
未確認なのでご了承ください。

以下のVim環境で確認しています。

  • Windows7 Pro SP1 64bit
  • VIM - Vi IMproved 7.3 MS-Windows 32-bit GUI version Included patches: 1-966
  • set shell=C:\Windows\System32\cmd.exe
  • set noshellslash
  • vimproc: c7bada0

{expr}の展開の流れ

vimproc#system({expr})の{expr}に指定された文字列は大まかに以下の順番で展開されます。
(実際にはもうちょっと複雑で、以下の通りではありません。が、処理は以下のようなことが処理されています。)

  1. コメント除去
  2. 複数のステートメントに分解する(アンパサンド、パイプ、セミコロン)

  3. 特殊文字を展開する

    1. ブロック
    2. チルダ
    3. 実行コマンドパス
    4. 変数
    5. ワイルドカード
    6. チルダ
  4. コメント除去

  5. 複数のステートメントに分解する(リダイレクト)

  6. 各ステートメントの実行

ただし、文字が以下に当てはまる場合には上記とは異なる扱いになります。

  • シングルクォート内の文字
  • ダブルクォート内の文字
  • バッククォート内の文字
  • エスケープされている文字

それぞれの説明

コメント除去

#以降の文字列はすべてコメントととして扱われます。

echo vimproc#system('echo hello # world!')
" hello
echo vimproc#system('echo hello $HOGE world!') " $HOGEが'#'のとき
" hello
echo vimproc#system('echo hello # world $HOGE hoge') " $HOGEが'#'のとき
" hello

複数のステートメントに分解する(アンパサンド、パイプ、セミコロン)

vimprocは&&||;によって複数のステートメントだと認識します。
もし変数に'&&'などが入っている場合、vimprocは1つのステートメントだと認識します。
(この場合の'&&'の処理は処理系に依存します)
また、vimprocは&|を単なる文字列として認識します(これも処理系に依存しますね)。

echo vimproc#system('echo hello && echo world')
" hello 
" world
echo vimproc#system('echo hello || echo world')
" world
echo vimproc#system('echo hello ; echo world')
" hello
" world
echo vimproc#system('echo hello $HOGE echo world') " $HOGEが'&&'のとき
" hello 
" world

特殊文字を展開する

ブロック

vimprocはブロックという値リストのようなものをサポートしています。
(:h vimshell-tips-blockを参照)

echo vimproc#system('echo /bin/{cd,ls}')
" /bin/cd /bin/ls
echo vimproc#system('echo {0..9}')
" 00 01 02 03 04 05 06 07 08 09
echo vimproc#system('echo {00..09}')
" 000 001 002 003 004 005 006 007 008 009
echo vimproc#system('echo {0..3}-{0..3}')
" 0..3}-{0..3
echo vimproc#system('echo /bin/$HOGE') " $HOGEが'{cd,ls}'のとき
" /bin/{cd,ls}

チルダ

~$HOMEの値に置換します。(チルダの前のスペースも必要!)

echo vimproc#system('echo ~')
" C:/Users/rbtnn
echo vimproc#system('echo a~')
" a~

実行コマンドパス

=に続くコマンド文字列をそのコマンドのパスに置換します。(イコールの前のスペースも必要!)

echo vimproc#system('echo  =cmd')
" C:/Windows/SysWOW64/cmd.exe
echo vimproc#system('echo  =ls')
" C:/Git/bin/ls.exe
echo vimproc#system('echo  =ls hello')
" C:/Git/bin/ls.exe hello

https://github.com/Shougo/vimproc.vim/pull/68 要参照

変数

環境変数を展開します。

echo vimproc#system('echo $HOME')
" C:/Users/rbtnn

ワイルドカード

vimprocは3種類のワイルドカード(*,?,[])をサポートしています。
(:h vimshell-tips-wildcardを参照)

echo vimproc#system('echo ~/ntuser.dat.????')
" C:/Users/rbtnn/ntuser.dat.LOG1 C:/Users/rbtnn/ntuser.dat.LOG2
echo vimproc#system('echo ~/.vim[a-z]c')
" C:/Users/rbtnn/.vimrc
echo vimproc#system('echo ~/.git*')
" C:/Users/rbtnn/.git C:/Users/rbtnn/.gitconfig C:/Users/rbtnn/.gitconfig.local C:/Users/rbtnn/.gitignore

複数のステートメントに分解する(リダイレクト)

vimprocは5種類のリダイレクト(<,1>,2>,>&,>>)をサポートしています。

シングルクォート

vimprocはシングルクォート内のシングルクォートを''で表すことができます。変数は展開されません。

echo vimproc#system("echo 'He''s a student.'")
" "He's a student."

ダブルクォート

vimprocはダブルクォート内で特定の文字をエスケープすることができ、以下のような辞書(escape_sequences)にて変換が行われます。変数は展開されます。

let escape_sequences = {
      \ 'a' : "\<C-g>", 'b' : "\<BS>",
      \ 't' : "\<Tab>", 'r' : "\<CR>",
      \ 'n' : "\<LF>",  'e' : "\<Esc>",
      \ '\' : '\',  '?' : '?',
      \ '"' : '"',  "'" : "'",
      \ '`' : '`',  '$' : '$',
      \}
echo vimproc#system('echo "hoge\nfoo"') " fooが出力されなかった。バグ?
" hoge
"
echo vimproc#system('echo "hoge\tfoo"')
" hoge  foo
echo vimproc#system('echo "\$HOHE"')
" $HOHE
echo vimproc#system('echo "$HOME"') 
" C:/Users/rbtnn

バッククォート

vimprocはバッククォート内にコマンドもしくはVim script式を入れて評価した結果を展開することができます。
(:h vimshell-tips-backquoteを参照)

echo vimproc#system('echo `git --version`')
" git version 1.8.1.msysgit.1
echo vimproc#system('echo `=3`') " Vim script式
" 3
echo vimproc#system('echo `=3*&columns`') " Vim script式
" 510

エスケープ

vimprocはクォート外では以下の4つの文字をエスケープ出来ます。

echo vimproc#system('echo \\')
" \
echo vimproc#system('echo \''')
" '
echo vimproc#system('echo \"')
" "\""
echo vimproc#system('echo \`')
" `

以上、「vimproc#system({expr})の{expr}の展開のされ方」でした。
vimproc.vim暗黒美夢王さんのプロダクトなのでvimshell.vimの挙動そのままですね。
明日の記事は@deris0126さんです。

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6