Vim のレジスタに :terminal のシェル上からアクセスする
Vim その2 Advent Calendar 2018 の記事です。
Advent Calendar 4日目で mattn さんが紹介してくれていた Tapi について、 ちょうど Tapi を使ったプラグインを作っていたので紹介したいと思います。 実際にこんな事ができるという例としてもシンプルで分かりやすいと思います。
概要
tapi-reg.vim は Vim のレジスタと端末の標準入力/出力を繋げるものです。
:terminal
で動かしているシェル上に Vim のレジスタの内容を出力したり、
逆にシェル上から Vim のレジスタの内容を書き換えたりできます。
セットアップ
動作には jq コマンドが必要です。 インストールはほぼ全ての OS でパッケージが用意されています。
jq コマンドをインストールしたら
source <this repo>/macros/vimreg.sh
を .bashrc に書いてください。
vimreg
というコマンドが使えるようになります。
どんなことができるのか
以下は README をほぼそのまま英訳したものです。 詳しくは README を見て下さい。
:terminal
→Vim: :terminal
から Vim のレジスタの内容を書き換える
Vim の :terminal
のバッファから vimreg
コマンド経由で Vim のレジスタの内容を書き換えることができます。
$ echo 'send this text to vim register!' | vimreg
これで無名レジスタに send this text to vim register!
の内容がセットされます。
もちろんレジスタ名を指定する事もできます。
$ echo 'send this text to register a!' | vimreg a
vimreg
は標準入力から文字列を取得するため、もちろんこのようにもできます。
$ vimreg This is sent to vim register. ^D $
:terminal
←Vim:Vim のレジスタの内容を標準出力に出力する
vimreg
は --get
(-g
) オプションをサポートしています。
これは Vim のレジスタの内容を標準出力に出力するものです。
もしレジスタ名が指定されなかったら、無名レジスタの内容が出力されます。
$ vimreg -g Hello this is vim unnamed register content. $ vimreg -g a this is "a" register content.
また Vim レジスタの一覧とその内容を出力する事もできます (:registers
の出力と同じ)。
$ vimreg -l --- Registers --- "" --- Registers ---^J"" ^J^J"0 if a:args[1] ==# '--list'^J^J"1 ^J^J"2 if a:args[1] =~# '\v^(-l|--list)$'^J^J"3 local reg='"'^J^J"4 set +x^J^J"5 set -x^J^J"6 set -x^J^J"7 "0 --- Registers ---^J"" ^J^J"0 if a:args[1] ==# '--list'^J^J"1 ^J^J"2 if a:args[1] =~# '\v^(-l|--list)$'^J^J"3 local reg='"'^J^J"4 set +x^J^J"5 set -x^J^J"6 set -x^J^J"7 "1 ^J "2 if a:args[1] =~# '\v^(-l|--list)$'^J "3 local reg='"'^J "4 set +x^J "5 set -x^J "6 set -x^J "7 content=^J "8 printf '\e]51;["call","Tapi_reg",["set",%s,%s]]\x07' \^J "$(to_json_string "$reg")" "$(to_json_string "$content")"^J "9 $(to_json_string "$3") "a degure "s " "- $list || ". --list ": call system('clip.exe', execute('registers')) "% macros/vimreg.sh "# plugin/tapi_reg.vim "/ --list
疑似クリップボードサポート (Windows Subsystem Linux (以下 WSL) のみ)
もちろん vimreg では has('clipboard') == 1
の場合にクリップボードの内容も扱えます (つまりシェル上から Vim 経由でクリップボードの取得・設定もできます)。
しかしWSL では has('clipboard') == 0
にもかかわらずクリップボードを扱えるようになっています。
$ vimreg + Send this text to clipboard ^D $
CDDB に初めて登録したけどジャンル欄が文字化けてしまうので助けてほしい
CDDB は CD 入れると取得できるアレ。 自分はここのを使わせてもらってる。
https://freedbtest.dyndns.org/
設定はこの通りにしてある。
そして送る時はここを参考にした。
登録したやつはこれ。
DIVERSE DIRECT | nishi-ogikubo Landscape
2018/10/03
まだ表示されてない。 「更新: 2018-10-03 03:21:59」と書いてあるから明日にでもなったら表示されるはず。
Namazu: a Full-Text Search Engine: <La Kasketia>
2018/10/04
検索結果に表示された。
- https://freedbtest.dyndns.org/dbread.php?dbpath=misc/7d0b060b
- https://freedbtest.dyndns.org/dbread.php?dbpath=misc/6d060a0a
「更新: 2018-10-04 03:21:22」らしいので大体一日間隔でその時間に終わるっぽい。 ただバッチがいつ始まるか分からないので、いつ送れば登録されるかはわからない。
肝心のデータの方はというと、ジャンルが文字化けしてた。 同時に買った ∀rkadia のデータ を参考にして「ジャンル:同人」で送った。
おそらく UTF-8 で送らなければいけない所に CP932 で送って「<0x93><0xaf><0x90>l」のようになってしまっていると思われる。
これに対して2通りの方法を試した。
こっちは以下の手順。
こっちは以下の手順。
とりあえず明日両方見てどっちの方法が正しかったのかを見るつもり。
ただ後者がまた文字化けしたデータを送ってしまった可能性が高いと思っていて、
CDexGenres.txt
送ったあとに末尾に cp932 のデータが追加されていた。
255 Animation misc 255 Anime(J) misc 255 同人 misc
おそらくどこからか読み取った「255 同人 misc」の行がなかったから末尾に追加されたと思うんだけど、読み取った場所が CDDB からなのか他にも「同人」のデータが残ってしまった。
255 Animation misc 255 Anime(J) misc 255 同人 misc (cp932 の "255 同人 misc")
検索してみたらいくつか「同人」のデータはあった。
# jvgrep は日本語の複数エンコードで書かれた文字列を探せるやつです https://github.com/mattn/jvgrep $ jvgrep -R '同人' /mnt/c/app/cdex_151/ /mnt/c/app/cdex_151/LocalCDDB/CDexGenres.txt:4:255 同人 misc /mnt/c/app/cdex_151/LocalCDDB/SUBMIT.TXT:23:DGENRE=同人 /mnt/c/app/cdex_151/LocalCDDB/misc/6dto6d:24:DGENRE=同人 /mnt/c/app/cdex_151/LocalCDDB/misc/79to79:23:DGENRE=同人 /mnt/c/app/cdex_151/LocalCDDB/misc/7dto7d:25:DGENRE=同人
そもそも CDex 1.51 とかいう古いバージョンを使ってるのが悪くて、最新だと普通に UTF-8 で送るようになっているのかもしれない…
というわけで CDex 1.77 (Portable, Unicode 版) で再度送ってみた。
そういえばコンピレーションアルバムの場合は V.A.
と Various Artists
どちらがいいのかについてもちょっと迷ったことを思い出した。
項目検索できることをふと思い出して、再度試してみる。
Namazu: a Full-Text Search Engine: <+Artist:"Various Artists">
Namazu: a Full-Text Search Engine: <+Artist:"V.A.">
V.A.
が 4069 件、 Various Artists
が 56500 件だった。
長いものにはぐるぐる巻かれていくタイプなので、今後 "Various Artists" で統一する。
2018/10/05
送りすぎて制限されたかな…
追記(2018/10/25): メールで問い合わせた結果、回数等に制限はないとのこと。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Content-Length: 3 # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< サーバーからの応答がありませんHTTP/1.1 400 Bad Request Date: Sat, 06 Oct 2018 01:49:38 GMT Server: Apache/2.2.31 (FreeBSD) mod_fcgid/2.3.9 mod_ssl/2.2.31 OpenSSL/1.0.1u-freebsd Content-Length: 226 Connection: close Content-Type: text/html; charset=iso-8859-1 サーバーからの応答がありません<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
CDex 1.77 で送ったはずなのに Submit via : CDex 1.51
となっているのでもしかして昨日あたりから制限されてたんだろうか(エラーは出なかったけど)。
それとも送るのが遅かっただけだろうか。
結果的に制限されてしまった?のでちょっともうよくわからない。 誰か直せる人直して…
追記: 2018/10/25
管理人の方からメールの返信が来て、 文字化けはジャンルに日本語が入ることを想定していなかったことが原因とのことで、 現在は対応してもらって Web 上でも表示できるようになっていた。
- https://freedbtest.dyndns.org/dbread.php?dbpath=misc/7d0b060b
- https://freedbtest.dyndns.org/dbread.php?dbpath=misc/6d060a0a
ちなみに書いてなかったけど、Web の表示は文字化けてたけど、CDDB に問い合わせて取得したデータは文字化けていなかった。
400エラーについては
- 回数等に制限は設けておらず
- 「必ず発生するということであればなにか送信してくるデータが想定外の形でこちらが受け取れていないのかもしれません」とのこと
端末アプリで Ctrl-[ が Esc になる理由
理由
SHIFT キーはキーコードを -0x20、CTRL キーはキーコードを -0x40 する機能
全文
vim-jp.slack.com の #random から。
heavenshell [10:08 AM] TouchBar MBP にしたら強制的に C-[ になるので、オススメです!ようやく矯正できた。 mattn [10:09 AM] 人間の方が最適化されている yoshitia [10:12 AM] Escが物理的にない状況用にデフォルトでCtrl-[ 用意してるのすごい mattn [10:14 AM] いや、用意した訳ではないです。 SHIFT キーはキーコードを -0x20、CTRL キーはキーコードを -0x40 する機能なのです。 なので `[` つまり 0x5b は 0x1b になる。 0x1b = ESC 同様に CTRL-H は H が 0x48 なので 0x08、つまり BS になる。 yoshitia [10:17 AM] 元からある仕組み上、代用ができちゃうだけなんですね mattn [10:17 AM] ですです。 逆に言うと `;` は 0x3b なので CTRL を使うと 0 以下になる、つまり使えないという事です。 端末の場合はマッピング出来る事もありますが、gvim で出来ないのはそれが理由です。 yoshitia [10:19 AM] 符号付UNICODEの機運(ない KoRoN [10:26 AM] 僕は ENTER の代わりに CTRL+M 使うことが多い。 (0x4D - 0x40 = 0x0D) あれ? あれ? M=0x4D, m=0x6D だな。 小文字基準で CTRL は -0x60 とすべきなのかな。 (edited) mattn [10:30 AM] あ、ですです これちなみに Unicode も受け継いでてくれてて KoRoN [10:30 AM] でもそうすると 5b が説明つかん? mattn [10:30 AM] `a` と `A` は -0x60 なんすよね CTRL は 0x40 KoRoN [10:31 AM] やっぱ大文字基準で、 SHIFT=+0x20 CTRL=-0x40 のほうが合致しそう。 KoRoN [10:32 AM] そういや昔のプログラム、全部大文字だったりしたな。 mattn [10:32 AM] これ、0 割れした場合の処理が端末毎に異なってるのがイヤらしいんすよ。 * 受け付けない * 300 から引く みたいな色々流儀がある