読者です 読者をやめる 読者になる 読者になる

MyEnigma

とあるエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

Vim用のスクリプトで、vim scriptの代わりにPythonを使う方法

Vim Python

Vim script テクニックバイブル ~Vim使いの魔法の杖

Vim script テクニックバイブル ~Vim使いの魔法の杖

目次

 

はじめに

ROS用のVimスクリプトを見ていたら、

中身が殆どPythonスクリプトだったので、

どんな風に実現しているのか調べていたら、

最近のVim(v7.0以降)は元々の機能として

pythonが利用できるようになっていたらしいです。。。

 

これまで何度もVim scriptやプラグインを作ろうと思いましたが、

Vim scriptの難解さに尻込みしてきたので、

pythonでVim用のツールを作れるなら、

一気にプラグインを作れそうな気がしてきました。

 

今回は、Vim scriptでpythonを使う時のメモを残しておきます。

Vimでpythonを使えるようにする。

最新のVimはpythonが初めから使えるようですが、

自分のMacのVimはバージョンが古くて使えませんでした。

 

確認の仕方は、Vimで

:python print('Hello')

として、Helloと表示されるかでわかります。

またpythonをpyと省略した

:py print("Hello')

でもOKです。

 

自分の場合(Mac Yosemite)、上記のコードがエラーで表示されなかったので、

brew upgrade vim

で最新版の7.4にアップデートしたら使えるようになりました。

 

Vim script内でのpythonの使い方

先ほどのprint文のように、

vimのコマンドラインでpythonが使えるのも嬉しいですが、

一番嬉しいのはvimscript内でpythonが使えることだと思います。

つまり、難解なvim scriptをあまり使わずに、

自分用のVim scriptをpythonで作ることができるようになります。

 

vim script内でpythonを利用するには

2つの方法があります。

 

一つ目は下記のコードのように、

function! GetHTML()
python << PYTHON
print "Hello python"
PYTHON
endfunction

"python << PYTHON"文と"PYTHON"文までの間に

pythonコードを書く方法です。

(PYTHONの部分はどんな文字列でもよい)

 

二つ目は、

pyfileというコマンドを使って、

外部のpythonファイルを呼び出す方法があります。

function! GetHTML()
pyfile hoge.py
endfunction

いずれにしても、pythonで書かれたメイン処理を

Vim scriptで簡単にラッピングできますし、

Vimscriptで、様々なpythonライブラリを使えるようになるので

かなり便利ですね。

vim用Python scriptの中でvimのデータを利用する

前述の方法で、vim scriptの中でpythonを呼ぶことができますが、

やはりvimのデータとpythonのデータのやりとりをしなければ、

あまり意味がありません。

 

そこで、vimとpythonのブリッジの役割を果たすのが、

下記のドキュメントで説明されているvimというpythonモジュールです。

先ほどのvim script内のpythonコード内で

import vim

とすることで様々なvimのデータにアクセスすることができます。

 

下記はvim scriptで使えそうな

vim-pythonインターフェイスの使用例です。

python << EOF
import vim
print "Hello python in vim"

#===コマンド実行系===
#vimのコマンドを実行
vim.command("echo 'vim script'")

#===データ取得系===

#現在開いているファイルのパスを取得
print vim.current.buffer.name

#今カーソルがある行の文章を取得
print vim.current.line

#現在ファイルの行数を取得
print len(vim.current.buffer)

# vimスクリプトの変数のデータを取得する
# (python用にエンコーディングする)
var = unicode(vim.eval("var"),'utr-8')

#スコープの付いた変数を読み込む
print vim.eval("g:var_g")

# ヴィジュアルモードの選択範囲のテキストを出力
var=""
for i in vim.current.range:
    var+=i
print var


#===データ追加削除系===

#現在のバッファの末尾に文字を追加
vim.current.buffer.append("aaa")

#現在のバッファの10行目の下に文字を追加
vim.current.buffer.append("vvv",10)

#現在のバッファの1行目を置換
vim.current.buffer[0]="bbb"

#現在のバッファの1行目削除
del vim.current.buffer[0]

#vimスクリプトの変数を変更する
vim.command(':let var = "updated value"')

#無名レジスタに単語を入れる(ペーストできるようにする)
code="hogehoge"
vim.command(":let @*='"+code+"'")



EOF

 

また、pyfileで起動するpythonスクリプトに引数を与えたい場合は、

下記の記事のようにsysモジュールを使って渡すようにしましょう。

 

詳細は先ほどの公式ドキュメントを参照してもらえると、

もっと詳しい使い方がわかると思います。

 

vimのコマンドの引数をvimscript内のPythonに渡す方法

Pythonで作成したvimコマンドに、

引数を渡したい時は、下記のように

commandでvimscriptの関数を呼ぶ時に、

<f-args>で引数をHoge関数に渡し、

この変数をローカル変数(l:arg)に渡して、

そのローカル変数の値をpythonのvimモジュールから、

eval関数で取得することができます。

function! Hoge(arg)
let l:arg=a:arg
python << EOF
import vim
var = vim.eval("l:arg")
print(var)
EOF
endfunction

" Command enable
command! -nargs=* hoge :call hoge(<f-args>)

これでVimコマンドの引数を使って、

Python処理ができますね。

 

最後に

vimプラグイン作りたくなってきました(笑)

参考資料

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

myenigma.hatenablog.com

Vim script テクニックバイブル ~Vim使いの魔法の杖

Vim script テクニックバイブル ~Vim使いの魔法の杖