😽

Rustでvim plugin(with deno)

2 min read 4

(記事の内容としては、Vimの話に見せかけてほぼwasmとdenoとrustを組み合わせるだけの話です。むしろそちらで詰まってしまった人の方が有用に感じられるかもしれません。)
demo is here

はじめに

最近Vim/Neovim両対応のプラグインの基盤として denops.vimというものが実装されつつあります。
僕がこのプロジェクトに期待している理由の一つが、denoを利用しているためwasmを読みこみできるという点です。
このプロジェクトは「deno(Typescript)でかける」ことを一つのセールスポイントにしていますが、
個人的には「denoだけでなくwasmを経由して好きな言語でプラグインを書き、denoを簡単な処理や根元のIFにすることもできる」というのが
これを見た時の最初の感想でした。

最近はcoc.nvimというプラグインにより「vscodeのプラグインをvimに移植」ということが流行っていますが、
同様に「vscode,denops両対応」や「vim,shell両対応のツール」といったものを、よりシンプルに実装できるのではないかと期待しています。
(個人的にはvimlの関数やベストプラクティスの知識がほぼないので、その辺りの一部をrustやtsに投げられるのも良さそうです。結局vimlも合わせて勉強しないといけないのは変わりないですが。)

ということで、幾つか引っ掛かりポイントに足を取られながらも無事に"rust->wasm->deno->vimと処理を繋ぐことが出来たのでここに共有したいと思います。

rust to wasm

rust -> wasmのコンパイルにはwasm-packを使うことが多いのですが、こちらはdenoにまだ対応していないのでssvmupを使おうかかなり悩みました。
結果的にssvmupのコンパイルでもdenoでの読み込みに手間取ったこと、ssvmupはwasm-bindgenのバージョンが固定になっていることなどからwasm-packでゴリ押す方を選択しました。

wasm-packのbuildをdenoに読み込ませる方法

denoではnodejsとの違いからtutorialの方法がそのまま使えません。
主に問題になるのは、

あたりでしょうか。

それぞれwasm-packの引数、wasmのattribute, 雑なsedで変換することでdenoで読み込めるものになります。

  • wasm-pack buildの引数に--target webを追加
    + wasm-pack build
    - wasm-pack build --target web
    
  • #[wasm_bindgen(js_namespace = console, js_name = log)] のattributeでstdoutに出力
    src/main.rs
    + #[wasm_bindgen(js_namespace = console, js_name = log)]
      fn alart(s: &str);
    
  • fetch(input)new WebAssembly.Module(await Deno.readFile(new URL(input).pathname));で置換
    pkg/index.ts
    + input = fetch(input);
    - new WebAssembly.Module(await Deno.readFile(new URL(input).pathname));
    

成果物

here

こちらをdenops同様にvimのruntimepathに追加し

  cargo run --manifest-path=utils/denops-builder/Cargo.toml

でbuildする事でvimから:DenopsRustEcho を実行できるようになります。

上手くいかない場合は

  • cargo, sed, wasm-pack が利用可能か
  • build時のcargoコマンドを実行する際のcurrent dir
    • (runtimepathに追加した階層、project rootにあたるところで実行してください。普通にgit cloneしたところにcdしていただければ大丈夫です。)
  • rustのバージョンは最新か(stableで動くはずですが、それでも駄目ならnightlyをつかってみてください。)
  • denopsの他のプラグインは動作しているか, runtimepathは正しいか(2敗)

を確認してみてください。

ちなみにvimmerではない方もbuildまでは出来ますので、「denoでrustのwasmを使いたいけど上手くいかないよー」といった方も試してみていただければと思います。

Discussion

diffのプラマイが逆です(後で直します)

後で試してみようと思います!
所でですが一箇所browserがbrouserになっているようです。

ありがとうございます!助かります!
他にもちょいちょいガバっている所があるのでぼちぼち修整します……

ログインするとコメントできます