vlime 導入
common lispvim
2023-4-7 10:50 JST

neovim と vlime の環境をとりあえず作った。

vlime と slimv

もともと Emacs ように slime の環境があったようだが、それをもとに slimv が出来たらしい。ただ、slimv は Python ベースなので「なんで Python 何や?」と思った人がいるらしくLisp ベースの vlime が出来たらしい。

SLIMV was written in Python on the Vim side, but I think a Lisp-and-Vimscript implementation would be awesome.

slimv は vim で動く。vlime は vim あるいは neovim で動く。neovim なら vlime 一択。

vlime install via dein

neovim のプラグインのマネジャーというのがあるらしく、deinを使った。プラグインの管理でプラグインの uninstall をしたいのだが、どうやってやるかは不明だった。なので、そのたびに、全部削除!!という作業をしている(非効率!!)。FAQ にもその方法はなかった。どうやら toml で管理すればいいらしい。そのうちやる。

dein の install

dein 自身の install の方法は歴史的に何度か変わっているらしく詳細は最新の情報を参照したほうが良い。私の取った方法は単純に installer.sh を実行して、1 (~/.cache) と 2 (~/.config/nvim/init.vim) を選択した。

vlime の install

vlime の install は dein を使う。本家Quickstartに各 plugin でのインストール方法が書いてある。それに従う。

call dein#add('vlime/vlime', {'rtp': 'vim/'})

を追加して init.vim の dein の最後のコメントを有効にしてcall dein#install()を有効にするか(そのあと nvim を立ち上げた時にインストールされる)、あるいは手動で同様に:call dein#install()するとインストールされる。

vlime つかう

ここまでできると、あとは vi を立ち上げるだけ。<なんとか>.lisp みたいな lisp ファイルを開くと lisp モードになっているはず。そこで \rrを叩くと vlime が立ち上がる。\を入力した後にぼや〜と待っていると \モードが消えてしまいその後 r を叩くと replace モードになってしまうので注意。

うまく立ち上がればその後 \ssでカーソル位置の評価が出来たり\lでファイルを読み込んだり出来る。

Enjoy common lisp life with vlime!!

vlime たちあがらず

ちゃんと quicklisp を設定していないと vlime は立ち上がらない。立ち上がらないときは単体でチェック。

$ sbcl --load ~/.cache/dein/repos/github.com/vlime/vlime/lisp/start-vlime.lisp
This is SBCL 2.0.1.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as iswith absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
WARNING:
   redefining EMACS-INSPECT (#) in DEFMETHOD
*   <INFO> [12:11:01] vlime-usocket - Server created: (#(127 0 0 1) 7002)

エラーになるのは quicklisp をインストールしていないからかもしれない

$ cat ~/.sbclrc
#-quicklisp
  (let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                         (user-homedir-pathname))))
    (when (probe-file quicklisp-init)
      (load quicklisp-init)))

sytanx on

どうも、私の使っている環境ではエスケープシーケンスがみだれるみたいで余計な文字が入ってしまう。普段、そもそも sytanx off なので、現在は sytanx off で使ってます。sytanx on って便利?私にとっては色がつき過ぎで集中できない。

roswell を起動

roswell の記述を書いておくと ros run の延長で立ち上がるよ。

let g:vlime_cl_impl = "ros"
let g:vlime_cl_use_terminal = v:true
let g:vlime_window_settings = {
    \ 'server': {'pos''botright''size': v:null, 'vertical': v:true}
    \ }

function! VlimeBuildServerCommandFor_ros(vlime_loader, vlime_eval)
    return ["ros""run""--load", a:vlime_loader, "--eval", a:vlime_eval]
endfunction

asciinema

前から気になっていた ASCII の録画システム。折角だからインストールする。

$ sudo pip3 install asciinema 
$ asciinema rec ~/tmp/

asciinema rec ファイル名で録画。asciinema play ファイル名で再生。簡単だ。再生時に -i 0.5とかしておくと間延びしなくて良い。

ついでにサイトに sign up して(メール登録だけ!)、ユーザ名を決めて、そしてasciinema auth。これで rec したのが登録される。なんか簡単。

ユーザ情報を集めようとしていないところが良い。

fukamachi/vlime

インストールしたが単純にはうまく動かなかった。vlime/vlime をごっそり fukamachi/vlime に変えることで動作したが(この方法は良くない)、パッと使った感じ特別にに vlime/vlime との差は見られなかった(インデントの処理が違うらしいが)、ので選り好みしないなら本家の vlime/vlime を使うのが良さそう。

今思えば dein#add の引数に {'rtp': 'vim/'}を追加しておけばよかったのかも。

mondo 再び

neovim のなかの mondo

mondo 自身は単体で使うのは非常に便利。キーワードを補完してくれるし。ただ vlime の延長での mondo は動きが変(設定の問題の可能性はあるが)なので(REPL Buffer に結果が出ない。mondo が立ち上がっている Buffer に結果が出る)、使うのはやめました。

mondo 単体 + neovim で使う

mondo もうすこし使えないか?とおもい、vim の外側で起動。mondo --server vlimeそして \ccでコネクト。ポート番号をちゃんと指定すると、、、なんだ使えるじゃん。この使い方が私が求めていたものだった。

REPL Buffer 抑制

とはいえ、なぜか無駄に REPL Buffer に--が出る。これ抑制できないのかな(調査中だがなさそうよ)。

仕方がないので、ソース読んで修正。

vim/autoload/vlime/plugin.vim を修正。SendToREPLInputComplete の最初の行をコメントアウト(うわぁ〜)

--- a/vim/autoload/vlime/plugin.vim
+++ b/vim/autoload/vlime/plugin.vim
@@ -1483,7 +1483,8 @@ function! s:ShowAsyncResult(conn, result)
 endfunction

 function! s:SendToREPLInputComplete(conn, content)
-    call a:conn.ui.OnWriteString(a:conn, "--\n", {'name''REPL-SEP''package''KEYWORD'})
+
+    "call a:conn.ui.OnWriteString(a:conn, "--\n", {'name': 'REPL-SEP', 'package': 'KEYWORD'})
     call a:conn.WithThread({'name''REPL-THREAD''package''KEYWORD'},
                 \ function(a:conn.ListenerEval, [a:content, function('s:OnListenerEvalComplete')]))
 endfunction

mondo の uitls.lisp のポートを最初に 7002 を試すように修正(うわぁ〜)

--- a/src/utils.lisp
+++ b/src/utils.lisp
@@ -72,11 +72,13 @@
         (usocket:socket-close socket)
         t))))

-(defun random-port ()
+(defun random-port (&optional (port-7002 7002))
   "Return a port number not in use from 50000 to 60000."
-  (loop for port from (+ 50000 (random 1000)) upto 60000
-        if (port-available-p port)
-          return port))
+  (if (and port-7002 (port-available-p port-7002))
+      port-7002
+      (loop for port from (+ 50000 (random 1000)) upto 60000
+            if (port-available-p port)
+            return port)))

 (defun data-directory ()
   (let* ((data-home (uiop:getenv-absolute-directory "XDG_DATA_HOME"))

こんな強烈な変更をしてしまっていいのかなぁ。後で嵌りそう。

リンク集