以前寫過一篇文章超輕量級純文本界面 REPL 類語言 IDE, 介紹了在純粹文本界面下如何用 Vim + Tmux + vim-slime
搭建一個超輕量級的 REPL
類語言開發環境, 配置步驟很簡單, 初學者使用起來也很容易上手, 不過用過幾回後發現缺憾: 這個開發環境是否是太簡陋了點? 也就是比語言自帶的 REPL
稍微多了個編輯區的功能, 尤爲是使用過 Emacs + Slime
環境的朋友, 多麼但願能在 vi
下用到相似的功能啊!vim
好消息是, 如今 slimv
出現了--(其實它早就出現了,只不過剛剛進入本文做者視野), 它整合了 slime
的大多數功能, 能夠用於 vim
環境. 不過初步閱讀文檔後發現, 幫助文檔裏介紹的 Linux
環境下的例子都要用到 XWindows
下的 XTerm
或者 KDE
下的 konsole
, 這有點背離咱們但願使用純文本界面的初衷, 畢竟咱們的目標是打造一款在流暢運行在樹莓派上的超輕量級開發環境, 並不但願啓動笨重龐大的視窗系統來浪費資源.sass
怎麼辦? 先進行理論分析, 看看 slimv
的原理, 它其實跟 Emaca
下的 slime
同樣, 使用 XTerm
的目的是爲了啓動一個 swank
服務端, 可是 swank
服務端是不須要視窗系統的, 能夠直接在純文本界面下用腳原本啓動, 只要保持 slimv
和 swank
版本一致, 端口號使用 slimv
默認值, 那麼咱們在純文本界面下啓動的 swank
服務端照樣能夠爲 slimv
提供鏈接服務. 並且, Emacs + slime + Common Lisp
是能夠運行於純文本界面的, 說明從理論上講, slimv
也應該具有這個能力.網絡
先試驗一下, 由於 slimv
中服務端的程序是這個 ~/.vim/bundle/slimv/slime/start-swank.lisp
因此咱們能夠用任意一個 Common Lisp
實現來執行這個腳本, 這裏咱們先試試 CLISP
, 命令爲:app
clisp -i ~/.vim/bundle/slimv/slime/start-swank.lisp
刷過一堆信息, 最後顯示:ide
;; Swank started at port: 4005.
很好,說明咱們經過命令行成功地啓動了 swank
服務端函數
這個服務端口能夠經過 slimv
或者 telnet
登陸上去, 先說說 telnet
怎麼連, 另外開一個終端窗口, 輸入學習
telnet 127.0.0.1 4005
就會顯示鏈接成功:測試
Air:slime admin$ telnet 127.0.0.1 4005 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'.
而後第一個啓動 CLISP
的終端窗口就會出現一個 REPL
提示符 CL-USER
, 變爲以下界面:ui
;; Swank started at port: 4005. CL-USER>
這裏其實就是通過 swank
包裝的 REPL
接口, 是能夠直接輸入表達式求值的lua
CL-USER> (+ 12 34) (+ 12 34) 46 CL-USER>
好玩吧, :)
好了, 言歸正傳, 繼續咱們的試驗.
在 slimv
的文檔中, 默認使用了 XTerm
來啓動 swank
, 可是通過上面的理論分析和動手試驗, 咱們清楚地瞭解到 swank
服務端並不須要一個圖形界面下的程序來啓動, 那麼咱們但願把 swank
服務端啓動在一個 tmux
的窗口中, 這樣咱們使用 vim + tmux
的組合時能夠很方便地經過快捷鍵來切換, 固然, 也能夠啓動在同一個 tmux
窗口的不一樣面板內, 可是鑑於咱們屏幕面積有限, 並且通常狀況下不須要太多關注這個 swank
服務端的狀態, 因此仍是另外啓動一個新窗口好了.
這裏由於以前對 tmux
主要是使用一些快捷鍵, 具體經過腳本如何調用的知識基本沒查過, 因此稍微花了點時間去研究, 最終經過網絡學習到了如何在 tmux
的窗口裏啓動程序, 其實就是一句腳本的正確格式,
tmux new-window -d -n REPL9 "clisp -i ~/.vim/bundle/slimv/slime/start-swank.lisp"
這行命令告訴 tmux
新建一個窗口(參數 new-window
), 後臺運行(參數 -d
), 名字叫REPL9(參數 -n REPL9
), 而後在這個窗口內執行雙引號裏的命令(參數 "clisp -i ~/.vim/bundle/slimv/slime/start-swank.lisp"
)
很好, 在顯示一大堆信息後 swank
服務端成功啓動了, 執行結果
;; Swank started at port: 4005.
那咱們試着從 vim
中用 slimv
鏈接一下, 用 vim
打開一個測試用的 test.lisp 文件, 進入命令狀態, 按下快捷鍵 逗號 小寫英文字母c
,c
因而在 vim
的編輯窗口上方新開了一個 REPL
窗口, 顯示以下:
24 CLISP 2.49 (2010-07-07) (built on air.local [192.168.0.2]) Port: 4005 Pid: 68955 25 ; SWANK 2014-10-10 26 CL-USER>
再去看看 swank 服務端, 顯示以下:
;; Swank started at port: 4005. CL-USER> ;; Loading file /Users/admin/.vim/bundle/slimv/slime/contrib/swank-asdf.lisp ... ;; Loading file /Users/admin/.slime/fasl/2014-10-10/clisp-2.49-unix-unknown/contrib/swank-repl.fas ... WARNING: The generic function #<STANDARD-GENERIC-FUNCTION THREAD-FOR-EVALUATION> is being modified, but has already been called. WARNING: Replacing method #<STANDARD-METHOD (#<STRUCTURE-CLASS MULTITHREADED-CONNECTION> (EQL :FIND-EXISTING))> in #<STANDARD-GENERIC-FUNCTION THREAD-FOR-EVALUATION> ;; Loaded file /Users/admin/.slime/fasl/2014-10-10/clisp-2.49-unix-unknown/contrib/swank-repl.fas
很顯然, 鏈接成功了! 試着在 REPL
區對錶達式求值:
注意, 由於 vim
區分命令模式和編輯模式, 而咱們的 REPL
區其實就是一個 vim
編輯緩衝區(相似於 Emacs
下的 buffer
的概念), 所以, 若是咱們想要在 REPL
區輸入什麼表達式, 須要先切換到插入模式(按 i
), 而後再輸入要求值的表達式,顯示以下:
26 CL-USER> (+ 123 345) 27 468 28 CL-USER>
很好, 成功了,很是漂亮, 先切換回命令狀態(快捷鍵 Esc
), 再切換回代碼編輯區(C-w w
), 試試看能不能把代碼編輯區的代碼片斷經過快捷鍵發送到 REPL
區求值, 把光標挪到一個表達式上, 而後按下快捷鍵: 逗號 小寫英文字母e
(,e
), 很好, 發送過去了,求值成功了!
28 CL-USER> (print "hh") 29 "hh" 30 CL-USER> REPL ----------------------- 1 (+ 1 2) 2 3 (format t "hello") 4 5 (print "hh") 6 7 (make-hash-table) 8 9 (defun hello () 10 (print "hello,world") 11 )
上半部分是 REPL
區,下半部分是代碼編輯區
再試試對函數定義的求值, 快捷鍵 逗號 小寫英文字母d
(,d
), 繼續成功,以下:
30 CL-USER> (defun hello () 31 (print "hello,world") 32 ) 33 HELLO 34 CL-USER> REPL ------------------------- 1 (+ 1 2) 2 3 (format t "hello") 4 5 (print "hh") 6 7 (make-hash-table) 8 (defun hello () 9 (print "hello,world") 10 )
slimv
號稱是世界上對 slime
函數支持最全面的 vim
實現, 沒有之一, 那麼咱們看看它究竟支持哪些 slime
的函數:
注意:
slimv
默認設置vim
的<leader>
鍵爲逗號
(,
), 因此你的.vimrc
中就不要對<leader>
另外定義了.
---- *slimv-keyboard* The default keybindings (|g:slimv_keybindings|=1) and another easy to remember built-in keybinding set (|g:slimv_keybindings|=2) for Slimv are the following. Please note that the leading ',' key below refers to <Leader>, which is set by Slimv to ',' by default (see |g:slimv_leader|). In the graphical menu the currently active keyboard shortcuts are displayed beside the menu item names, so one can refer to the GUI menu as a quick reference for the keymappings. Vim defines timeout values for mapped key sequences. If you find that Vim does not allow you enough time between pressing ',' and the last key(s) of the sequence, then you may want to fine tune these Vim options: |timeout|, |ttimeout|, |timeoutlen|, |ttimeoutlen|. Set#1 Set#2 Command --------------------------------------------------- ,, ,, Slimv Menu Edit commands (Insert mode): <C-X>0 Close Form <Tab> Complete Symbol <Space> Function Arglist Edit commands (Normal mode): ,) ,tc Close Form ,( ,(t Paredit Toggle Evaluation commands: ["x],d ["x],ed Eval Defun (current top level form) [put in register x] ["x],e ["x],ee Eval Current Expression (current subform) [put in reg. x] ["x],r ["x],er Eval Region (visual selection) [or text from register x] ,b ,eb Eval Buffer ,v ,ei Interactive Eval (evaluates in frame when in SLDB) ,u ,eu Undefine Function Debug commands: ,1 ,m1 Macroexpand-1 ,m ,ma Macroexpand All ,t ,dt Toggle Trace ,T ,du Untrace All ,B ,db Set Breakpoint ,l ,dd Disassemble ,i ,di Inspect (inspects in frame when in SLDB) ,a ,da Abort ,q ,dq Quit to Toplevel ,n ,dc Continue ,H ,dl List Threads ,K ,dk Kill Thread ,G ,dg Debug Thread Compile commands: ,D ,cd Compile Defun ,L ,cl Compile and Load File ,F ,cf Compile File ["x],R ["x],cr Compile Region [or text from register x] Cross Reference commands ,xc ,xc Who Calls ,xr ,xr Who References ,xs ,xs Who Sets ,xb ,xb Who Binds ,xm ,xm Who Macroexpands ,xp ,xp Who Specializes ,xl ,xl List Callers ,xe ,xe List Callees Profile commands: ,p ,pp Toggle Profile ,B ,pb Profile by Substring ,U ,pa Unprofile All ,? ,ps Show Profiled ,o ,pr Profile Report ,x ,px Profile Reset Documentation commands: ,s ,ds Describe Symbol ,A ,da Apropos ,h ,dh Hyperspec ,] ,dt Generate Tags Repl commands: ,c ,rc Connect to Server ,y ,ri Interrupt Lisp Process Set#1 Set#2 Command --------------------------------------------------- ,\ ,\ REPL Menu (separate menu, valid only for the REPL buffer) REPL menu commands: ,. ,rs Send Input ,/ ,ro Close and Send Input ,g ,rp Set Package <C-C> <C-C> Interrupt Lisp Process ,<Up> ,rp Previous Input ,<Down> ,rn Next Input ,- ,- Clear REPL Note: Some mappings accept an optional "x prefix (where x is a register name) similarly to Vim's p (put) and y (yank) commands. These commands may additionally use the given Vim register to store or retrieve text. Commands "Eval Defun" and "Eval Current Expression" also store the form being evaluated in the given register. When using uppercase register name, the current form is appended to the contents of the register. Commands "Eval Region" and "Compile Region" use the contents of the given register (instead of the selected region) for evaluation or compilation. This feature may be used for remembering and recalling a test form used for testing parts of the code.
洋洋灑灑真是很多, 稍微試驗幾個, 發現確實支持, 簡直太好了, 看來咱們想在純文本界面的 vim
下使用全功能的 slime
大有但願!
目前爲止, 咱們已經完美驗證了原先的想法: 在純文本界面下用 tmux
啓動 swank
服務端, 並經過 slimv
鏈接到 swank
, 而後對新建的 REPL
區進行求值試驗, 一切都很完美, 剩下的就工做是把咱們的驗證成果轉化爲配置文件, 讓它們應用起來!
明天繼續...