ハイパーマッスルエンジニア

Vim、ShellScriptについてよく書く

Vimに生命を吹き込む(NeoVim×FloatingWindow)

f:id:rasukarusan:20191208172849p:plain
Vimに生命を吹き込む(NeoVim×FloatingWindow)

はじめに

この記事はHameeアドベントカレンダー13日目の記事です。

最近VimからNeoVimに乗り換えた。
VimPluginの王ShougoさんのPluginもいくつかNeoVim対応が増えてきていた(というかNeoVimにした方が楽な状態になってた)ので、NeoVimにしてみた。

NeoVimの中でも特に気になったのがFloating Window。今回はこれの紹介とVimScriptを開発していく上でのちょっとしたTipsを書いていく。

Floating WindowでVimに「生命」を吹き込みたかった

FloatingWindowで遊んで出来上がったものがこれ。
pasteするときに上から降らしたり、deleteするときに一個ずつバラバラにしたりして、さもVimが生きているかのような振る舞いを目指した。

https://user-images.githubusercontent.com/17779386/69538032-bbfabd80-0fc4-11ea-85e2-4da46b2317b8.gif
TETRIS Pasteと名付けた

https://rasukarusan.github.io/blog-assets/neovim-floating-window-tips/randomcolor.gif
floating windowでdeleteをTETRISっぽく

ソースはこちら github.com

github.com

これを紹介したかっただけなので今回の記事はもう満足してる。お疲れサマンサ。

Floating Windowって何?

画面分割などでウィンドウをタイル型に並べるのではなく、重なるように配置できるNeoVimの新機能。イメージ的には補完表示で出てくるウィンドウに近い。
FloatingWindowで作成されたウィンドウはVimの通常のバッファとほぼ同じなので、移動などの操作もhjklだし、勿論Vimコマンドも使用できる。 詳しくは下記サイトが参考になる。 https://rhysd.hatenablog.com/entry/2019/03/10/230119

https://rasukarusan.github.io/blog-assets/advent-calender-2019-hamee/neovim_floating.gif
floating windowで関数説明やGitのログを表示できる

FloatingWindowはNeoVimにしか入っていないが、通常のVimでも「ポップアップウィンドウ」という名前で導入されている。 生成の仕方はそれぞれ違うが、たぶん同じようなことができるんだろう。

VimScriptで遊ぶときのTips

今回のFloatingWindowのように、Vimで新しい機能が導入されたときや、.vimrcに自作関数を作りたいときに、どうやって遊んでいくか。自分はこうやっているよというのを紹介したい。

FloatingWindowで遊ぶときのTipsは別記事に上げたので興味ある人はそっちをどうぞ。FloatingWindowの話はここで終わりだ。

1.VimScriptの実行の仕方

例えば下記サイトに書かれているコードを試したいとする。

qiita.com

上記サイトから抜粋。

" 新しい floating window を開いて、そのウィンドウにフォーカスを移す。
" 第2引数が v:true になっているのでフォーカスが移ります。
call nvim_open_win(bufnr(''), v:true, {'relative': 'cursor', 'height': 3, 'width': 10, 'row': 1, 'col': 1})
" Hoge を定義(黄色地に黒文字になります)
hi Hoge guifg=#2e3440 guibg=#ebcb8b
" Hoge をデフォルトのハイライトにする(Normal の代わりに使う)。
set winhighlight=Normal:Hoge

このコードを試したいと思ったらやることは3つ。

  1. どこでもいいのでvim test.vimでスクリプトを作成する
  2. コピぺする
  3. :source %でスクリプトを実行する

こんな感じ。

https://rasukarusan.github.io/blog-assets/advent-calender-2019-hamee/source.gif
:source %でスクリプトを実行する

source %%はVimではカレントバッファのファイル名を示すので、「現在開いているファイルを読み込む(実行する)」に等しい。%以外にも色々あるので:help cmdline-specialで調べてみると面白い。

2. もっと楽に実行する

:source %をキーマップするととっても楽。
自分は.vimrcに以下を記載して、Shift+Sで実行できるようにしている。

" 現在開いているスクリプトを読み込む
nnoremap S :source %<CR>

同様に、.vimrcに追加したものをすぐに反映したいときは以下でいける

" source ~/.vimrcを簡略化
nnoremap rr :source ~/.vimrc<CR>

3. 関数化して呼び出す

VimScriptで関数を作るときはTest()のように先頭を大文字にしてグローバル関数して定義するか、s:test()のようにs:をつけてローカル関数にするかなどいくつかやり方がある。基本はこの2つでいいんじゃねえかな。

function! Test()
    echo "Test"
endfunction

function! s:test()
    echo "test"
endfunction

function! s:test_return()
    return 5
endfunction

call Test()
call s:test()

let i = s:test_return()
echo i

" Test
" test
" 5

ただ、s:の関数を呼び出すときは少し注意が必要で、nnoremapなどのmap系で使う場合はs:ではなく<SID>test()としなければならない。

nnoremap Test :call <SID>test()<CR>

参考 https://whileimautomaton.net/2008/06/30070800

おまけ

ちなみにNeoVimに乗り換えるのはめちゃくちゃ楽で、.vimrcinit.vimにするだけでOK。NeoVim自体もbrew でインストール可能なので一回やってみてもいいかもね。
.vimrcの内容もほぼ書き換えなしでそのまま移行できる。自分は1,2箇所の書き換えのみでスルッと移行できた。

以下の3ステップで導入完了となる。

# NeoVimインストール
$ brew install neovim
# 今まで使っていた.vimrcをそのまま流用
$ ln -sf ~/dotfiles/.vimrc ~/.config/nvim/init.vim
# NeoVim起動
$ nvim

終わり

NeoVimはおもしろい。