想法驗證:超輕量級全功能純文字介面 REPL 類語言 IDE: Vim+Tmux+Slimv
想法驗證:超輕量級全功能純文字介面 REPL 類語言 IDE: Vim+Tmux+Slimv
前言
之前寫過一篇文章超輕量級純文字介面 REPL 類語言 IDE, 介紹了在純粹文字介面下如何用 Vim + Tmux + vim-slime
搭建一個超輕量級的 REPL
類語言開發環境, 配置步驟很簡單, 初學者使用起來也很容易上手, 不過用過幾次後發現缺憾: 這個開發環境是不是太簡陋了點? 也就是比語言自帶的 REPL
稍微多了個編輯區的功能, 尤其是使用過 Emacs + Slime
環境的朋友, 多麼希望能在 vi
下用到類似的功能啊!
好訊息是, 現在 slimv
出現了--(其實它早就出現了,只不過剛剛進入本文作者視野), 它整合了 slime
的大多數功能, 可以用於 vim
環境. 不過初步閱讀文件後發現, 幫助文件裡介紹的 Linux
環境下的例子都要用到 XWindows
下的 XTerm
或者 KDE
下的 konsole
, 這有點背離我們希望使用純文字介面的初衷, 畢竟我們的目標是打造一款在流暢執行在樹莓派上的超輕量級開發環境, 並不希望啟動笨重龐大的視窗系統來浪費資源.
怎麼辦? 先進行理論分析, 看看 slimv
的原理, 它其實跟 Emaca
下的 slime
一樣, 使用 XTerm
的目的是為了啟動一個 swank
服務端, 但是 swank
服務端是不需要視窗系統的, 可以直接在純文字介面下用指令碼來啟動, 只要保持 slimv
和 swank
版本一致, 埠號使用 slimv
預設值, 那麼我們在純文字介面下啟動的 swank
服務端照樣可以為 slimv
提供連線服務. 而且, Emacs + slime + Common Lisp
是可以執行於純文字介面的, 說明從理論上講, slimv
也應該具備這個能力.
試驗1: 純手工啟動 swank.lisp 並連線
先試驗一下, 因為 slimv
中服務端的程式是這個 ~/.vim/bundle/slimv/slime/start-swank.lisp
所以我們可以用任意一個 Common Lisp
實現來執行這個指令碼, 這裡我們先試試 CLISP
, 命令為:
clisp -i ~/.vim/bundle/slimv/slime/start-swank.lisp
刷過一堆資訊, 最後顯示:
;; 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
, 變為如下介面:
;; Swank started at port: 4005.
CL-USER>
這裡其實就是經過 swank
包裝的 REPL
介面, 是可以直接輸入表示式求值的
CL-USER> (+ 12 34)
(+ 12 34)
46
CL-USER>
好玩吧, :)
好了, 言歸正傳, 繼續我們的試驗.
試驗2: 試驗在 tmux 不同的視窗啟動 swank
在 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 函式以及預設快捷鍵
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 , 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
區進行求值試驗, 一切都很完美, 剩下的就工作是把我們的驗證成果轉化為配置檔案, 讓它們應用起來!
明天繼續...
相關文章
- 超輕量級純文字介面 REPL 類語言 IDEIDE
- 輕量級標記語言
- 輕量級超級 css 工具CSS
- 輕量級多級選單控制框架程式(C語言)框架C語言
- 超輕量級PHP框架BroPHPPHP框架
- ThinkGo:一個輕量級的 Go 語言 MVC 框架GoMVC框架
- easyhttp——輕量級、語義化、 對 IDE 友好的 HTTP 客戶端HTTPIDE客戶端
- zinc:替代elasticsearch的輕量級Go語言搜尋引擎ElasticsearchGo
- Go 語言編寫輕量級網路庫,GrapeNetGo
- looter——超輕量級爬蟲框架爬蟲框架
- 超輕量級反爬蟲方案爬蟲
- wangEditor——輕量級web富文字框Web
- JetBrains總算推出了輕量級IDE: FleetAIIDE
- [譯]HAL-超文字應用語言
- 《自然》證實:計算機語言更類似人類語言計算機
- PhalApi(π框架) - PHP輕量級開源介面框架API框架PHP
- 使用純資源DLL檔案實現多語言選單、介面文字、Tooltips等 (轉)
- 知物由學 | 更適合文字分類的輕量級預訓練模型文字分類模型
- 如果程式語言是超級英雄……
- 基於Mono和VSCode打造輕量級跨平臺IDEMonoVSCodeIDE
- 免費實名認證介面python語言-身份核驗-身份證二、三要素Python
- 一個輕量級的引數校驗框架框架
- 輕量級表單校驗模組(ES6)
- 超輕量級MP4封裝方法介紹封裝
- go語言簽發和驗證licenseGo
- PHP語言呼叫翔雲身份證實名認證介面PHP
- 可識別影象中100種人類語言文字的純Javascript OCR庫包:Tesseract.jsJavaScriptJS
- 可識別影像中100種人類語言文字的純Javascript OCR庫包:Tesseract.jsJavaScriptJS
- Multipass,多平臺本地輕量級Linux體驗!Linux
- 輕量級超級簡單的element的layout柵格化佈局
- Linux下C語言驗證多程式LinuxC語言
- 一鍵生成!輕量級 AI 證件照製作工具!AI
- 6. 自定義容器型別元素驗證,類級別驗證(多欄位聯合驗證)型別
- Rust為何無法成為超級語言?Rust
- DevOps專題|Lua引擎打造超輕量級客戶端dev客戶端
- 純CSS實現表單驗證CSS
- 利用C語言驗證哥德巴赫猜想C語言
- 使用 React + Koa 打造一個輕量級的部落格系統,呼叫語雀API介面實現ReactAPI