asyncomplete-tabnine.vim を neovim に対応してみた
概要
tabnineはAIによる入力補完をサポートしてくれるツールです。
vimでも利用できるのですが、デフォルトで使うと同期処理されてレスポンスが遅く使い勝手が悪いです。
非同期用としてYouCompleteMeやCoC、Deopleteが対象となっていますが、私は普段asyncomplete.vimで補完をしているため対象になってませんでした。
asyncomplete-tabnine.vim とうプラグインを作ってくださった方がおり、インストールしてみたのですが、NeoVimではjob_start関数がないとエラーになっていました。
そこで自分用にneovimで動作させてみました。
リポジトリ
インストールする場合はREADMEを確認してください。
変更点
https://github.com/kitagry/asyncomplete-tabnine.vim/compare/master...hotoolong:master
上記の差分が修正点になります。興味のある方は確認してみてください。
vimのjob_startはneovimではjobstart関数(ハイフンがない)で似たように処理をしています。
引数で渡すコールバック関数の引数の数が違っていたりするので、
vimとneovim両者に対応する場合はどちらのコールバック関数も作成する必要がありそうです。冗長な状態ですね。
jobでIOを確立した後にchannelを制御するのも
vimではch_sendrawを使っているのに対してneovimではchansendを使っています。
このあたりもまだ理解が追いついてないのですがhelpを見ながらなんとか動かしてみたという状態です。
まとめ
以前からneovimで動作しないvim pluginを見かけては使いたかったけど仕様が無い気持ちでいました。
これで少しは便利に使えそうです。
ただ、以下のように
neovimとvimでscriptが若干違ってるのはいつか解消されるのかな。vimで動くプラグインがneovimで動かないというのが結構あるな。
— hotoolong (@hotoolong) 2020年9月12日
と両者の違いが吸収されていくのか少し期待していたのですが、
Shougoさんから
解消されないでしょう。逆にどんどん違いが大きくなる方に向かっています。
— 暗黒美無王 dark Vim (@ShougoMatsu) 2020年9月12日
VimはVim9スクリプトに、neovimはLuaに傾倒しているからです
とあったので
ますます乖離していきそうです。
もともとvimからneovimに完全に乗り換えていたのはvimの動作がもっさりしていたのがきっかけですが、
neovimは独自のエディタとして進んでいきそうです。
最近のVimのバージョンでは新しい機能も増えて速度も随分と改善されているように感じます。
neovimの開発がvimを踏襲したものになってはいないのでこのままneovimを使い続けるべきかとても心動かされる内容となりました。
しばらくは併用して考えるかもしれないです。
参考にした記事
vim-plug で プラグインの遅延ロードを行う
イントロ
最近neovimの起動が もっさり してきました。
プラグインマネージャーにはvim-plugを使っていまます。
こちらの環境で起動時間を改善してみました。
計測
nvim --startuptime ./startup.log
こちらのコマンドで起動時の処理時間が計測できます。
times in msec clock self+sourced self: sourced script clock elapsed: other lines 000.093 000.093: --- NVIM STARTING --- 002.755 002.662: locale set : : (途中省略) : 952.261 000.003: --- NVIM STARTED ---
左端が累計の時間、2番目が実行されている処理の時間です。
:%!sort -r -n -k 2
処理時間別に並び替えて重い処理を抽出できます。
プラグインの遅延ロード
vim-plugでは遅延ロードの種類が限定されています。
onとforをつかって遅延ロードさせるのが常套なのですが、
数秒後に読み込みのような設定はまだないようです。
タイマーで呼び出す
こちらの記事で取り上げられていて試してみたらとても良かったです。
以下のサンプルとしてlspの読み込みを遅延させています。
call plug#begin('~/.vim/plugged') " .. 省略 Plug 'prabirshrestha/vim-lsp', { 'on': [] } Plug 'mattn/vim-lsp-settings', { 'on': [] } " .. 省略 call plug#end() function! s:load_plug(timer) call plug#load( \ 'vim-lsp', \ 'vim-lsp-settings', \ ) endfunction call timer_start(500, function("s:load_plug"))
Plugにonでから配列を設定することで読み込まなくなります。
timer_startで500ms後にs:load_plug関数を呼び出すようにしています。
plug#loadで遅延させる対象のprefix部分の文字列を省いて登録しておくと呼び出せます。
はじめ間違ってPlugに設定している文字列をそのまま渡してしまいエラーになってしまいました。
気をつけて!
計測時に遅くなっているものとあとからロードしても問題なさそうなプラグインを設定して再度計測してみると
952.261ms → 455.829ms になりました。
これでしばらくは快適に過ごせそうです。
参考URL
vim-plug/plug.txt at master · junegunn/vim-plug · GitHub
neovimでpython3のエラーに遭遇
概要
結果としてはpython3のバージョンを上げてしまったのでエラーがでてたので対応したというものです。
起動時のエラー内容
ERROR: Failed to run healthcheck for "denite" plugin. Exception: function health#check[21]..health#denite#check[3]..<SNR>211_check_required_python[7]..denite#init#_python_version_check, line 8 Vim(python3):E319: No "python3" provider found. Run ":checkhealth provider"
上記のような内容のエラーが出ていました。
詳細確認
:checkhealth
してみたところ
## Python 3 provider (optional) - WARNING: No Python executable found that can `import neovim`. Using the first available executable for diagnostics. - ERROR: Python provider error: - ADVICE: - provider/pythonx: Could not load Python 3: /usr/local/bin/python3 does not have the "neovim" module. :help |provider-python| python3.9 not found in search path or not executable. /usr/local/bin/python3.8 does not have the "neovim" module. :help |provider-python| python3.7 not found in search path or not executable. python3.6 not found in search path or not executable. python3.5 not found in search path or not executable. python3.4 not found in search path or not executable. python3.3 not found in search path or not executable. /usr/bin/python is Python 2.7 and cannot provide Python 3. - INFO: Executable: Not found
というメッセージが出ていたので
help provider-python
して確認すると
To use Python plugins, you need the "pynvim" module. Run |:checkhealth| to see if you already have it (some package managers install the module with Nvim itself). For Python 3 plugins: 1. Make sure Python 3.4+ is available in your $PATH. 2. Install the module (try "python" if "python3" is missing): > python3 -m pip install --user --upgrade pynvim
解決方法
python3 -m pip install --user --upgrade pynvim
を実行して解決しました。 めでたし。
ghq list の 代替案
イントロ
普段 ghqとfzfを使ってリポジトリの切り替えをしています。
とても便利なのですが、最近、かなりもっさりしてきて遅いので改善を考えてみました。
改善方法
ボトルネックとしてはghq listがとても遅くなっていました。
簡易改善
ghq root 配下のディレクトリがそこまで多くない場合 git だけを対象とした改善方法をよく見かけました。
ghq list --vcs=git
こちらで改善する場合はこれだけで良さそうです。
今回実施した改善
findに置き換えて改善している記事を見たいのですが、私の場合は動作がもっさりしたままでした。
そこでRUST製のfdを使いことにしました。
バージョン管理がすべてgitで管理してるのでgitの特性から.gitファイルを探すことにしました。
ghq list
を
fd --type d --min-depth 2 --max-depth 4 --hidden --search-path $i '.git$' | sed -e "s/\/.git\$//"
に変更しています。
このコマンドでは .gitディレクトリを探して .git を削り一覧化しています。
--min-depth 2 --max-depth 4 と しているのは
ghq root を複数設定していてローカルに作成してるリポジトリのディレクトリ構造を考慮しています。
利用される方はお好みに合わせて変えるのが良いかと思います。
今回の変更のdiffは以下の様になっています.
gd configs/fish/config.fish diff --git configs/fish/config.fish configs/fish/config.fish index 9f2755c..5659e0c 100644 --- configs/fish/config.fish +++ configs/fish/config.fish @@ -210,15 +210,20 @@ function fzf_select_ghq_repository set fzf_query --query "$query" end - set -l out (ghq list --vcs=git | \ + set -l out ( + for i in (ghq root -all) + fd --type d --min-depth 2 --max-depth 4 --hidden --search-path $i '.git$' | \ + sed -e "s/\/.git\$//" + end | \ fzf $fzf_query \ --prompt='Select Repository >' \ - --preview="echo {} | cut -d'/' -f 2- | xargs -I{} gh repo view {} ") + --preview="echo {} | awk -F'/' '{ print \$(NF-1)\"/\"\$NF}' | \ + xargs -I{} gh repo view {}" + ) [ $status != 0 ] && commandline -f repaint && return if test -n $out - set -l dir_path (ghq list --vcs=git --full-path --exact $out) - commandline "cd $dir_path" + commandline "cd $out" commandline -f execute end end
これでかなり速度が改善されていて快適になりました。
もっといい方法がありそうなので、何かあればコメントないしはDMなどでご連絡いただけると嬉しいです。
参考URL
rake release で エラーがでた
イントロ
以前の記事でembed_callbacksを作成したと取り上げたのですが、
その中でRubyGemsでユーザ登録に失敗してたのですが、
サポートの人に対応していただきメールアドレスを変更していただきました。
これでやっと登録できるなと思って登録してみたのですが少しトラブルにあったのでこちらに記載しておきます。
ちなみに登録したgemのアドレスは以下になります。
これでgem install とインストール可能になるのでとてもいい気分です。
遭遇したエラー
rake releaseしたときに既存のブランチとupstream branchが違うよと指摘された内容になります。
$ rake release embed_callbacks 0.1.0 built to pkg/embed_callbacks-0.1.0.gem. Tagged v0.1.0. Untagging v0.1.0 due to error. rake aborted! Couldn't git push. `git push ' failed with the following output: fatal: The upstream branch of your current branch does not match the name of your current branch. To push to the upstream branch on the remote, use git push origin HEAD:trunk To push to the branch of the same name on the remote, use git push origin HEAD To choose either option permanently, see push.default in 'git help config'. /Users/hotoolong/.rbenv/versions/2.7.0/bin/bundle:23:in `load' /Users/hotoolong/.rbenv/versions/2.7.0/bin/bundle:23:in `<main>' Tasks: TOP => release => release:source_control_push (See full trace by running task with --trace)
git init してはじめに変更したブランチがtrunkでした。
BLM運動がきっかけてmasterはどうなのかという話がありdefault branch名をどうするか決めかねていたときに以下のコマンドでtrunkにしました。
git branch --set-upstream-to=origin/trunk
その後 github上でmainにしようという流れになっていた(以下のリンク)のでmainに変更していました。
GitHub - github/renaming: Guidance for changing the default branch name for GitHub repositories
git branch -m trunk main git push -u origin main
ただ、upstreamの設定がそのままになっていたようです。
解決方法
git config -e
してtrunkをmainに置き換えてしまいました。 これで再度rake release するとうまくいきました。 よかったです。
embed_callbacksに機能追加した
概要
前回の記事でembed_callbacksというgemを紹介しました。
こちらの機能を追加したので紹介していきます。
追加した機能
- メソッドがエラーになったときに処理を呼び出せる
- メソッドエラーになっても呼び出せる
rescue
これはその名の通りでrescueを設定するとエラー時に呼びされます。
コードを見てもらったほうがわかりやすいかと思うので下記にサンプルを記載しておきます。
require 'embed_callbacks' class Sample include EmbedCallbacks set_callback :target, :rescue, :rescue_callback def target raise 'target' end def rescue_callback puts 'rescue_callback' end end sample = Sample.new sample.target #=> rescue_callback #=> RuntimeError (target)
encure
こちらも同様にencureになります。
こちらはafterに近いかもしれないですが、
エラーが発生しても必ず呼び出されます。
require 'embed_callbacks' class Sample include EmbedCallbacks set_callback :target, :ensure, :ensure_callback def target puts 'target' end def ensure_callback puts 'ensure_callback' end end sample = Sample.new sample.target #=> target #=> ensure_callback
その他
RubyGemsへの登録
前回からの進捗はない状態ですが、
slackの#rubygemsで質問してみたところ、同様の問題質問があることを教えてもらいました。
Wrong emails when signup / Problems / Discussion Area - RubyGems.org Support
こちらを見ると SUPPORT STAFF で対応してもらい解決したようです。
一旦サポートにメールを送ってみました。
返信までは時間がかかるようなのでしばらく待ってみようと思います。
まとめ
callbackという感じではないですが、 rescue、ensureを後付で追加したいケースがあり作成してみました。
よかったらつかってみてください。
メソッドにcallbackを追加するgemをつくってみた
概要
以前からgemを作ってみたいと思いつつ作れてなかったので作成してみました。
methodにcallbackを追加するembed_callbacksというgemを作成しました。
探すと似たようなgemが出てくるので車輪の再発明的なものになりますが作成してみました.
gemの機能
まだそこまで機能はないのですが以下のようになります。
- メソッドの前に処理を追加
- メソッドの後に処理を追加
- メソッドの前後に処理を追加
上記を簡単に呼び出せるようにしています。
今後更に機能は追加する予定です。詳細はGitHubを確認していただければと思います。
gemの作り方
参考記事
https://qiita.com/coe401_/items/8e90373a76f590ef0abe
しおいさんがQiitaで取り上げてくれた記事を参考にしました。
丁寧に説明してくれていてとてもいい記事ですね。
gemの命名
https://guides.rubygems.org/name-your-gem/
こちらの記事でどのような命名するとよいか記載されている内容を参考にしました。
gem searchコマンドもしくは https://rubygems.org/ から作成するgem名を検索しておき
同じ名前にならないようにしておくのがいいかと思います。
はじめに考えていた名前はすでに登録されていたので別名を考えていた今回の命名になりました。
命名は先行優位ですね。
困ったこと
RubyGemsへの登録
RubyGemsにユーザ登録時のメールアドレスを間違ってしまい、
確認メールをチェックできなくなってしまいました。
ログインはできるのですが確認メールをチェックしてください。というような文言で確認できない状況です。
メールアドレスは一度目の登録からは変更できないようなので、
とりあえずはRubyGemsには登録しないでしばらくGitHubだけで公開しておきます。
同様の問題で困っている人は少なそうですが、解決方法がわかる方いらっしゃいましたら情報いただければと思います。
どうしようもなくなったらhotoolong2みたいなのにして登録しようと思います。
gemの作成
参考記事にはbundle gem hogehoge などすると対話式にオプションを設定できるようなものもあったのですが、私の環境ではそうならなかったので引数などを設定しました。
$ bundle gem embed_callbacks --test=rspec --coc --mit Creating gem 'embed_callbacks'... MIT License enabled in config Code of conduct enabled in config create embed_callbacks/Gemfile create embed_callbacks/lib/embed_callbacks.rb create embed_callbacks/lib/embed_callbacks/version.rb create embed_callbacks/embed_callbacks.gemspec create embed_callbacks/Rakefile create embed_callbacks/README.md create embed_callbacks/bin/console create embed_callbacks/bin/setup create embed_callbacks/.gitignore create embed_callbacks/.travis.yml create embed_callbacks/.rspec create embed_callbacks/spec/spec_helper.rb create embed_callbacks/spec/embed_callbacks_spec.rb create embed_callbacks/LICENSE.txt create embed_callbacks/CODE_OF_CONDUCT.md Initializing git repo in /Users/hotoolong/repositories/embed_callbacks Gem 'embed_callbacks' was successfully created. For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html
まとめ
比較的簡単に作成まではいけそうなので、他にもgemにしていなかったものや放置してるものを徐々にupしていければいいかなと思っています。 なにか助言やPRなど私の困ったことへの解決の糸口になるものなどアドバイスいただければとてもありがたいです。
参考にした記事
はじめての自作gem 「Hello, Tama!」を出力してみる - Qiita
RubyGemはめっちゃ簡単に作れる! | 酒と涙とRubyとRailsと
https://qiita.com/yu-croco/items/a93693d02ca39ac38f78
RubyGemsの作り方 - Qiita
Bundler: How to create a Ruby gem with Bundler
Name your gem - RubyGems Guides
GitHubリポジトリのREADMEの良さそうな書き方・テンプレート - karaage. [からあげ]
個人gemのCIをほぼ全部Travis CIからGitHub Actionsに移行した - くりにっき
GitHub Actions がローンチされたのでマイグレートしてる - HsbtDiary(2019-08-11)
GitHub - actions/setup-ruby: Set up your GitHub Actions workflow with a specific version of Ruby
今の時代だからこそオススメする車輪の再発明|erukiti