vimshell
zshをも超える究極のShell
Shougo
--------------------------------
vimshellとは?
VimScriptによって実装された究極のシェル。
略してvshell。ただし、eshellとは違ってまだまだ未完成です。
一番の特徴としては、Vimのプラグインと連携ができること。
特にWindowsはシェルが貧弱なので、使用していてイライラしますが、vimshellはWindowsでも動作するので安心です。
ただしWindows上では一部の機能が制限されるので注意。
加えて、他のシェルの便利な機能を多数取り込んでいます。
設定して当たり前の機能は標準的に使えるため、zshと比べて設定の手間もありません。
ただし非同期実行を行わない場合、vimshellはVimのシェル設定を用いてプログラムを起動します。
よって、シェルは適切に設定しておく必要があります。
ちなみに、使いやすいシェルを目指しているため、変数の規則などが普通のシェルと異なります。
--------------------------------
入手方法
http://github.com/Shougo/vimshell/tree/master (毎週更新)
ちゃんとしたドキュメントができたらwww.vim.orgにも登録したいです。
しかし実装がまだ不完全で安定していないこともあり、登録はまだまだ先になるでしょう。
--------------------------------
非同期実行のさせかた
非同期実行するには、vimprocが必要です。
私がvimshell用に修正したvimprocがあるので、それをリポジトリから取ってきます。
http://github.com/Shougo/vimproc/tree/master
そしてproc.soをmakeします。
ただしMacの場合、make時に
$ make -f make_mac.mak
とする必要があります。
コンパイルが通ったら、autoloadにあるproc.vimとproc.soを.vimのautoloadディレクトリにコピーします。
Windowsの場合、上記のリポジトリから自力でコンパイルするか、
http://yukihiro.nakadaira.googlepages.com/vimproc.zip
ここからproc.dllを.vimのautoloadディレクトリにコピーします。
ここのproc.vimは古いので、proc.vimはgithubのリポジトリから取ってきてautoloadディレクトリにコピーする必要があります。
あとは
let g:VimShell_EnableInteractive = 1
とすると、非同期実行が有効になります。
--------------------------------
使い方
:VimShell でvimshellを起動します。
普通のシェルと似たような動作をするので、直感的に操作できるでしょう。
ただし、パス指定は/で行います。Windowsで\をパスに使用するとエスケープシーケンスと誤解され、動作しません。
--------------------------------
似た感じのスクリプト
・vimsh.vim
・Shell.vim
・Vim-Shellプロジェクト
・Screen.vim
・eshell.el
・ansi-term.el
・zsh
--------------------------------
vimsh.vimの良いところ
・インタラクティブなシェルが起動できる(Windows以外)
・Vimから独立している
vimsh.vimの悪いところ
・Pythonインタフェースが必要
・バグが多い
・必要なくても勝手に起動する
--------------------------------
Shell.vimの良いところ
・動作が単純
・完全にVimScriptで動作する
・一部が内部コマンドで実現されている
Shell.vimの悪いところ
・もう長い間更新されてない
・インタラクティブなプログラムを起動するとフリーズしてしまう
--------------------------------
Vim-Shellプロジェクトの良いところ
・内部で完全なシェルを動作させることができる
・エスケープシーケンスを解釈するので、色分けもできる
・比較的有名
Vim-Shellプロジェクトの悪いところ
・あまりに巨大なパッチなので、本家に取り込まれることはない
・Vimのバージョンごとの互換性がない
・シェルに依存する
・しかも更新頻度が遅い(Vim7.2には未対応)
・Windowsでは動作しない
--------------------------------
Screen.vimの良いところ
・GNU screenの機能をVimから使用できる
・比較的に汎用性はある
Screen.vimの悪いところ
・WindowsやGVimでは使えない
・当然GNU screenが必要
・Vimからコマンドを送るだけなので、結果がVimのバッファに取り込めない
--------------------------------
eshell.elの良いところ
・完全なシェルを動作させることができる
・Emacsのシェル設定に依存しない
・Windowsでも動作する
・完全にEmacs内で動作する
・cursesも動作する(ansi-term.elを使った方がよい)
・色分けやエスケープシーケンスに対応
・Emacs Lispも動作する
・Emacsに標準添付
eshell.elの悪いところ
・Emacsen専用
・起動が遅い
・Windows上では対話プログラムの動作が不安定
・他のシェルと比べると情報が少ない
・入力のリダイレクションが未実装
--------------------------------
ansi-term.elの良いところ
・完全なターミナルを動作させることができる
・cursesも動作する
・エスケープシーケンス完全対応
・Emacsに標準添付
ansi-term.elの悪いところ
・Emacsen専用
・日本語入力ができない
・Windowsでは使用できない
・シェルに依存する
・入力がansi-termに取られてしまうので、キーバインドが破壊される
--------------------------------
zshの良いところ
・有名
・他のソフトから独立している
・カスタマイズ性が高い
・比較的情報が多い
・補完機能が強力
zshの悪いところ
・sh系の文法にはやはり問題が多い
・自動補完ができない
・起動が遅い
・Windowsでは動作しない
・キーバインドの設定など、Vimにはカスタマイズ性が劣る
・凝ったことをしようとすると大変
--------------------------------
vimshell.vimの良いところ
・完全にVim内で動作する
・シェルへの依存性は低い(非同期実行の場合)
・コマンドが色分けされるので見やすい
・開発が早い
・Vimのプラグインと連携ができる
・ワンライナー対応
・非同期実行をサポート
・自動ディレクトリスタックやauto_cdなど、zshの機能を一部取り込んでいる
・内部コマンドを簡単に追加可能
・WindowsやGVimでもほとんどの機能を使用できる
・VimScriptの文法を一部取り込んだ新たなシェルである
・エスケープシーケンスによる色づけに対応
vimshell.vimの悪いところ
・制御構造がないので、スクリプト機能が貧弱
・情報が少ない
・まともなマニュアルがない
・仕様が頻繁に変わる
・普通のシェルとの互換性は低い
--------------------------------
vimshellの歴史
Shell.vimの表示が見づらいので色分けを始める
↓
内部が汚かったので、大幅改造
↓
もはや別物になったのでvimshellに改名
↓
githubで公開してみる
↓
反響大きい
↓
thincaさんの薦めで、内部をプラグイン化
↓
ついカッとなり、zshの機能を取り込む
↓
ついカッとなり、ワンライナー対応してみる
↓
さらなる暴走
↓
そして現在に至る……
詳しくはChangeLog:で。
--------------------------------
vimshellの代表的機能
・色分け
・ヒストリ
・他のプラグインとの連携
・ディレクトリスタック
・auto_cd
・スクリプト実行
・シェル呼び出し
・ワンライナー対応
・簡易電卓
・プラグインによる機能拡張
・aliasコマンド
・シェル変数
・非同期実行
・独自のカレントディレクトリ
・vimコマンド
・コマンドラインスタック
・パイプ
--------------------------------
完全にVim内で動作する
Vimの中で動作するので、Vimのキーマッピングを完全に利用することができます。
VimScriptが書けるならば、オリジナルのキーバインドを用意したり、
内部コマンドを追加することも簡単です。
特にVim戦闘力が上昇しすぎてVimからでるのが苦痛となってしまっている、達人Vimmerへの福音となるでしょう。
--------------------------------
色分け
vimshellバッファ上で、.ファイルやディレクトリ、実行ファイル等を認識し、見やすいように色分けをします。
ちなみに、vimshのToDoにも色分けのことは書いてあったので、vimshellのほうが先に実装したことになります。
最近ではエスケープシーケンス機能を強化、256色を含めた多数のエスケープシーケンスを認識します。
特にWindows環境やGVimでも動作するのが魅力。
ただし、ハイライトを大量に使うので重いです。
--------------------------------
ヒストリ
私はものぐさなので、ヒストリ機能には力を注いでいます。
ヒストリ一覧はhistoryコマンドで参照できます。
入力時にオムニ補完を起動すると、ヒストリ補完になります。
部分マッチで検索され、非常に便利なので是非お使いください。
今まで入力したコマンドラインの上で<CR>してもヒストリ実行できます。
当然のように、ヒストリはvimshell内で共有しているので、別のvimshellからも同じヒストリが参照できます。
ヒストリに記録したくないときは、コマンドの先頭に空白文字を入れます。
zshのように、連続したコマンドはヒストリに記録しません。
それだけではなく、重複したコマンド履歴は削除されるので、履歴がすっきりします。
'h ヒストリ番号' や、 'h コマンド名'でヒストリから検索して実行できます。
--------------------------------
他のプラグインとの連携
vimshellはほぼ100% Vimの機能を使って実装されているので、他のプラグインと連携させることができます。
というより、これがなかったら私もvimshellは使ってないと思います。
編集はVimの機能をそのまま使えますし、キーマッピングも自由自在です。
例えばneocomplcacheと連携させることで、ヒストリからの引数補完や、自動ディレクトリ補完が実現できます。
バージョンが上がるごとにneocomplcacheのファイル名補完も強力になっているので、vimshellから使用すると幸せになれます。
--------------------------------
ディレクトリスタック
bashやzshのように、ディレクトリスタックを当然完備。
しかも何も設定せずにauto_pushdしてくれるので、pushdコマンドはありません(!)。
ディレクトリスタックを参照するにはdirsコマンド、ディレクトリスタックからcdするにはpopdコマンドを使います。
Ver.5.33より、他のシェルと同様に、"cd -"でpopdと同じ動作になります。
cdを省略して、"-"でも同じ意味です。
--------------------------------
シェル呼び出し
非同期実行など、vimshellでは対応できない用途にも対応するため、
shellコマンドでシェルを一時的に呼び出せるようになっています。
shell&とすると、バックグラウンドでシェルを実行します。
--------------------------------
screen実行
screen コマンド名 で、コマンドをscreen上で実行できます。
どうしてもvimshell上で実行できないプログラムに便利です。
ただしscreen上のターミナルでないと、シェルのバックグラウンド実行になります。
--------------------------------
バックグラウンド実行
プログラム名の最後に&をつけると、プログラムをバックグラウンドで実行します。
プログラムの出力もバッファで確認できるので、非同期実行に便利です。
vimprocがないと、通常のシェルを使ったバックグラウンド実行になります。
iexeと組み合わせると、別バッファで簡単にインタプリタを実行できます。
強制終了したいときは、<C-c>です。
"iexe コマンド名&"と"コマンド名&"の違いは、
"iexe"の場合はプログラムにキーボードからの入力を送りますが、"コマンド名&"の場合はプログラムに一切入力を与えないことです。
--------------------------------
auto_cd
ディレクトリ名で実行すると、そのディレクトリに移動します。
zshの機能を移植しました。
例えば、..で上のディレクトリへ移動できます。これはまさにLife Changingな機能です。
特に設定せずに使えます。
--------------------------------
スクリプト実行
vimshコマンドの引数にスクリプトファイルを指定することで、
スクリプトファイルに書かれたコマンドを入力として、実行を行います。
ただし制御構造が実装されていないため、あまり使用価値はありません。
vimshellは初期化ファイルとして、.vimshrcを読み込みます。
aliasの設定はそこで行っておくと便利です。
--------------------------------
ワンライナー対応
thincaさんのパッチを取り込むことにより、Windowsでもワンライナーコマンドが動作するようになりました。
--------------------------------
簡易電卓
evコマンドを使用すると、引数をVimScriptとして評価するため、簡易的な電卓として使えます。
Vim7.2以降ならば、少数を使用した計算にも対応しています。
例:
vimshell% ev 3+3
6
--------------------------------
プラグインによる機能拡張
vimshellの内部コマンドとして、autoload/internal/にある*.vimファイルを読み込むため、
自分でそこにプラグインファイルを追加することで、簡単にコマンドが追加できます。
今後、プラグイン作成のためのマニュアルを作る予定です。
--------------------------------
aliasコマンド
コマンドにalias名をつけることができます。
コマンドの簡略化に便利。ちゃんと引数やパイプも認識します。
例:
alias hoge = ls -la
alias ls = 'ls -la'
--------------------------------
シェル変数
let $hoge=34 などとすることで、簡単にシェル変数に書き込めます。
シェル変数はそれぞれのvimshellバッファ固有の変数です。
環境変数に代入するには、
let $Hoge = $hoge
のように、変数名の先頭を大文字にします。
普通のシェルと違って、 = の間に空白があってもなくても動作します。
代入する式はVimScriptとなっているので、計算も自由自在です。
ただしvimshellでは変数名の頭に必ず$を付けなければなりません。
注意してください。
コマンドの終了ステータスは$$statusに書き込まれますが、Windowsでは上手く動作しません。
--------------------------------
非同期実行
vimprocを使って非同期処理を実装中です。ようやくLinuxでは動作するようになりました。
"iexe コマンド名"で動作します。
しかしWindowsではパイプを使った処理となるため、インタプリタの動作が異なります。
どうやらAPIがサポートされてないらしく、諦めるほかありません。
出力を取るためにはEnterを押す必要があったりと、若干癖がありますが、
Vimから様々なインタプリタを動作させることができるのは驚きです。
Ver.5.12より、
let g:VimShell_EnableInteractive = 1
と設定しないと非同期実行が出来なくなりました。
その代わり、通常のプログラム実行時にもvimprocが使われるようになります。
特にWindowsでは動作が安定化するので、設定しておくことをおすすめします。
非同期実行モードになっていると、Vimのシェル設定を一切使用しません。全てを自前で処理します。
これにより、Windowsでもワンライナーが動作するなど、様々な利点がありますが、
現状制御構造が全く実装されていないため、シェルスクリプトとして利用することができません。
対話的に実行するなら充分ですが、注意してください。
特権が必要なコマンドでも、sudo hogeで動作させることができます。
ただしsudoを実行する権限が必要です。他のシェルを使わなくて済むので、以外と便利。
非同期実行が有効になっている時に、どうしてもシェルで実行させたい場合、
"iexe コマンド名"を使えば、強制的にシェル実行をさせることができます。
--------------------------------
独自のカレントディレクトリ
vimshellはVimのカレントディレクトリとは別に独自のカレントディレクトリを持っていて、
カレントディレクトリの保存や復元を自動で行います。
vimshellからVim側のカレントディレクトリを変更したいときは、gcdコマンドを使用してください。
--------------------------------
vimコマンド
"vim ファイル名"というコマンドを実行することで、指定したファイルをvimで開きます。
"view ファイル名"とすると、読み込み専用で開きます。
ちょっとファイルの中身を確認したいときに便利。
neocomplcacheと併用するとファイル名補完が自動でできるので、":edit"で補完して開くより圧倒的に早いです。
--------------------------------
コマンドラインスタック
コマンド入力中に<C-z>を押すと、一度コマンドラインがクリアされ、次に<CR>を押したときに復元されます。
スタックになっているので、連続して行うこともできます。
この機能はzshからインスパイアされました。
--------------------------------
ファイルの関連づけ
g:VimShell_ExecuteFileListにプログラムが登録されていたら、実行時にプログラムの引数として呼び出すようにしました。
Windowsでいうファイルの関連づけになります。
zshにも「サフィックスエイリアス」という似たような機能がありました。
例えば let g:VimShell_ExecuteFileList['rb'] = 'ruby' としておくと、
./hoge.rb
でrubyプログラムを実行できます。
--------------------------------
プロンプト移動
Normal modeで<C-p>, <C-n>を押すと、プロンプト間を移動できます。
Emacsのシェルモードを参考に実装しました。
コマンドの履歴を参照するときに便利です。
--------------------------------
出力の削除
Normal modeで<C-d>を押すと、前のプロンプトまでの出力を削除できます。
Emacsのシェルモードを参考に実装しました。
あまりに出力が長くなってしまったときに活用してください。
--------------------------------
シェルコマンド補完
Insert modeで<TAB>を押すと、シェルコマンドを補完できます。
自前で補完処理を実装したので、内部コマンドやエイリアスも補完できます。
今後はユーザーが補完処理を定義できるようにする予定です。
--------------------------------
バッククォート
echo `ls`
のように、コマンドの引数にコマンドの結果が使えます。
VimScriptの埋め込みもできるので、
echo `=3`
とすれば、evコマンドの代わりにもなります。
--------------------------------
パイプ
苦労しましたが、ようやくパイプを実装しました。
% ls | grep vim
というようなコードが動作します。
非同期実行が有効でなくても、シェルを呼び出すのでうまく動作します。
ただし、現状 | をパイプのマーカーとして処理するので、
| 単体でプログラムに渡せません。
--------------------------------
ワイルドカード
% ls *.htm
というようなワイルドカードも普通に使えます。
指定されたファイルが存在しない場合、zshのようにエラーになるので注意。
ワイルドカードの除外もサポートしました。
% ls *~*.htm
'~'で区切ってパターンを記述することで、「パターンを除外したパターン」という意味になります。
zshの機能を移植。
--------------------------------
ブロック
% echo /hoge/piyo/{hoge,hogera}
-> /hoge/piyo/hoge /hoge/piyo/hogera
ブロック構文もサポートしました。これでまともなシェルらしくなります。
ついでにzshのような数値展開も実装。
% echo {00..09}
-> 00 01 02 03 04 05 06 07 08 09
zshを超えるのももう少しかもしれません。
--------------------------------
ユーザープロンプト
g:VimShell_UserPrompt変数にVimScriptの式を文字列として代入することで、
ユーザーが追加で表示されるプロンプトを定義できます。
g:VimShell_Promptと違い、固定文字列でなくても良いです。
例えば、このように毎回カレントディレクトリを表示するようにすれば便利です。
let g:VimShell_UserPrompt = 'getcwd()'
ただし、セキュリティの関係上、vimshellの関数を呼び出す前に値を設定しなければ無効になります。
Ver.5.32以降より、ユーザープロンプトを\nで区切ることで、
複数行のユーザープロンプトが表示できるようになりました。
--------------------------------
グローバルエイリアス
zshのようなグローバルエイリアスにも対応。
galias G = '|grep'
とすることで、引数のGは'|grep'に置き換わります。
'ls G hoge'は'ls |grep hoge'という意味になります。
パイプライン処理を手軽に駆けるので便利です。
--------------------------------
プログラム名展開
% echo =ls
のように、'='に続けてパスが通っているプログラム名を記述すると、
プログラムのフルパスに置き換わります。
デバッガの引数にするときや、ページャを使ってソースを読みたい場合に便利です。
--------------------------------
vimdiffコマンド
"vimdiff file1 file2"というコマンドを実行することで、簡単にvimdiffを実行できます。
vimshellからいちいちdiffを呼び出すのは不便なので、存分に活用しましょう。
--------------------------------
キーバインド等のカスタマイズ
vimshellのキーバインドはftplugin/vimshell.vimにて定義されています。
よって、after/ftplugin/vimshell.vimを作成すれば、簡単にカスタマイズできます。
--------------------------------
私の設定
let g:VimShell_UserPrompt = 'getcwd()'
let g:VimShell_EnableInteractive = 1
let g:VimShell_EnableSmartCase = 1
let g:VimShell_EnableAutoLs = 1
" Initialize execute file list.
let g:VimShell_ExecuteFileList = {}
call vimshell#set_execute_file('txt,vim,c,h,cpp,d,xml,java', 'vim')
let g:VimShell_ExecuteFileList['rb'] = 'ruby'
let g:VimShell_ExecuteFileList['pl'] = 'perl'
let g:VimShell_ExecuteFileList['py'] = 'python'
call vimshell#set_execute_file('html,xhtml', 'gexe firefox')
if has('win32') || has('win64')
" Display user name on Windows.
let g:VimShell_Prompt = $USERNAME."% "
" Use ckw.
let g:VimShell_UseCkw = 1
else
" Display user name on Linux.
let g:VimShell_Prompt = $USER."% "
call vimshell#set_execute_file('bmp,jpg,png,gif', 'gexe eog')
call vimshell#set_execute_file('mp3,m4a,ogg', 'gexe amarok')
let g:VimShell_ExecuteFileList['zip'] = 'zipinfo'
call vimshell#set_execute_file('tgz,gz', 'gzcat')
call vimshell#set_execute_file('tbz,bz2', 'bzcat')
endif
" !: vimshell interactive execute.
nnoremap ! :<C-u>VimShellInteractive<Space>
" &: vimshell background execute.
nnoremap & :<C-u>VimShellExecute<Space>
プロンプトをユーザー名にしているだけで、後は凝った設定はしてないです。
ちなみにneocomplcacheでは、vimshellのヒストリファイルを辞書として使用してます。
これはなかなか便利です。
g:VimShell_ExecuteFileListによる関連づけも設定しています。
ユーザープロンプトを設定するのは一番最初にします。
vimshellを読み込む前に設定しないと、セキュリティの関係で再設定できなくなるからです。
--------------------------------
情報
あのtaku_oさんに紹介されました!!
http://d.hatena.ne.jp/taku-o/20090126
pcmasterさんによる紹介
http://d.hatena.ne.jp/pcmaster/20090505/p1
はてなブックマークがものすごいことになってます。
やはり皆さん、今までのシェルには不満を持っているようですね。
しかしneocomplcacheと比較すると、まだまだ知名度は低いです。
皆さんも使ってみたら感想をお寄せください。
最近はMacVim-Kaoriyaにvimprocが内蔵され、使いやすくなっています。
splhackさんにはvimshellのMac対応に協力してもらいました。ありがとうございます。
Nico Raffatoさんが、vimshellの非同期実行機能を進化させ、Conqueという独立したプラグインとして配布しています。
vimshellが役に立ったようで嬉しいです。一部の機能はvimshellにも取り込んでいます。
現在はvimprocをPythonインタフェースで置き換えようとしているようです。
--------------------------------
今後の予定
vimshellの歴史は以外と古く、neocomplcacheより前から作り始めていました。
現在neocomplcacheが安定し、私もvimshellを日常的に使用するようになったので、今後は貧弱なスクリプト機能を改善する予定です。
--------------------------------
まとめ
機能追加の要望やバグ、質問等があれば、githubのIssuesに書いてください。
http://github.com/Shougo/vimshell/issues
まめにチェックをしているので、皆さんのブログに書いていただいてもかまいません。
Twitterやブログもやってます。
http://vinarian.blogspot.com/
http://twitter.com/ShougoMatsu
更新情報は主にブログに、重要な情報はTwitterでもアナウンスする予定です。
夢はシェルに戻らなくても、ほとんどの作業をvimshell内で完結できるようにすることです。
私はプログラムのコンパイル・実行環境として、日常的にvimshellを使用しています。
おかげで最近は通常のシェルをあまり使わなくなりました。
vimshellは今後ますます進化します。皆さんの手で、最強のシェルを手に入れましょう。
--------------------------------
更新履歴
2009/09/12 Ver.5.34に対応。
2009/09/03 Ver.5.32に対応。
2009/08/29 全体的に見直し。
2009/07/24 Ver.5.27に対応。
2009/07/12 Ver.5.24に対応。
2009/07/03 Ver.5.21に対応。
2009/06/30 Ver.5.18に対応。
2009/06/21 Ver.5.16に対応。
2009/06/18 Ver.5.15に対応。
2009/06/13 Ver.5.14に対応。
2009/06/05 Ver.5.13に対応。
2009/05/30 Ver.5.12に対応。
2009/05/23 Ver.5.11に対応。
2009/05/7 Ver.5.8に対応。
2009/03/7 やっつけで作成。
--------------------------------