Vim 下使用 Slimv(类似Slime) 轻松调试 Common Lisp
2019独角兽企业重金招聘Python工程师标准>>>
Vim 下使用 Slimv(类似Slime) 轻松调试 Common Lisp
目录
- 前情回顾
- 安装slimv
- 数据配置
- 默认快捷键
- 实战演练
前情回顾
在上一篇文章想法验证:超轻量级全功能纯文本界面 REPL 类语言 IDE: Vim+Tmux+Slimv中我们对于在 tmux
中新建窗口运行 swank
服务端的想法经过了手工验证, 证明了我们的想法是可行的, 本文则完成实际的配置, 把所有的配置信息都写入到配置文件中.
安装slimv
如果你看过上一篇文章并且照着做了, 那你的 slimv
已经安装好了. 如果没有安装的话可以按照下面的操作来安装:
我们继续通过 pathogen
来管理 slimv
插件, 也就是说, 只要进入 .vim/bundle/
目录下, 把 slimv
用 git
克隆进去, 暂时不做配置, 因为我们要手动进行试验, 安装命令如下:
cd ~/.vim/bundle/
git clone
安装就这么简单, 如果对于 pathogen
的安装有不清楚的地方可以看看本系列第一篇文章里的描述超轻量级纯文本界面 REPL 类语言 IDE.
接下来就是数据配置了.
数据配置
Linux 和 OSX 平台下的配置
主要是对 vim
的配置, 因为我们要从vim
中启动 slimv
和 swank
, 只要在你原来的 .vimrc
配置文件中加入如下内容即可:
"Set mapleader
let mapleader = ","" slimv for clisp
let g:slimv_swank_cmd = '! tmux new-window -d -n REPL-CLISP "clisp -i ~/.vim/bundle/slimv/slime/start-swank.lisp"'
上面的配置调用了 clisp
, sbcl
和 ccl
的配置分别为:
" slimv for sbcl
let g:slimv_swank_cmd = '! tmux new-window -d -n REPL-SBCL "sbcl --load ~/.vim/bundle/slimv/slime/start-swank.lisp"'
" slimv for ccl
let g:slimv_swank_cmd = '! tmux new-window -d -n REPL-CCL "ccl -l ~/.vim/bundle/slimv/slime/start-swank.lisp"'
Win32 平台下的配置
在 Win32
下不使用 tmux
, 直接按照官方配置文档的配置方法配置就可以了, 需要正确指定两个目录, 一个是 Common Lisp
安装目录, 一个是 slimv
安装目录
- Common Lisp 安装目录:
c:/Program Files/Lisp Cabinet/bin/ccl/
- Slimv 安装目录:
c:/Program Files/Lisp Cabinet/site/lisp/slime
配置命令如下:
let g:slimv_swank_cmd = '!start "c:/Program Files/Lisp Cabinet/bin/ccl/wx86cl.exe" -l "c:/Program Files/Lisp Cabinet/site/lisp/slime/start-swank.lisp"'
还有一个好消息就是我们对 slimv
的数据配置跟原来的 vim-slime
的配置不冲突, 所以这两个插件的功能你可以同时使用, 只要通过不同的快捷键调用即可.
默认快捷键
官网的文档里给出了如下快捷键:
---- *slimv-keyboard*
有两套快捷键可供选择, 默认快捷键绑定第一套, 设置变量为:g:slimv_keybindings=1第二套设置变量为: g:slimv_keybindings=2注意前导键 <leader> 默认设置为逗号(,), 当然你可以改为其他键, 设置全局变量为:g:slimv_leader在图形界面下每个菜单项都会列出对应的快捷键, 不过我们是文本界面, 就没有这个福利了.vim 定义了快捷键序列的超时值, 如果你觉得自己手速慢, 来不及在规定的超时时间内输完长长的快捷键序列, 那么你也可以自己设置一下相关的超时时间, 直接设置 vim 里对应的这几个参数好了:timeout
ttimeout
timeoutlen
ttimeoutlen下面就是具体的快捷键了, Set#1 代表第一套, Set#2 代表第二套, Command 代表该快捷键对应的命令.Set#1 Set#2 Command---------------------------------------------------,, ,, Slimv 菜单编辑命令 (Insert 模式):<C-X>0 关闭形式<Tab> 自动补全输入的符号<Space> 函数参数列表编辑命令 (Normal 模式):,) ,tc 关闭形式,( ,(t 括号自动成对开关求值命令:
["x],d ["x],ed 求值 Defun (当前顶层) [放到寄存器 register x]
["x],e ["x],ee 求值当前表达式 (当前子形式) [放到寄存器 reg. x]
["x],r ["x],er 求值区域 (visual 选择) [或者来自 register x 的文本],b ,eb 求值缓冲区内所有内容,v ,ei 交互求值 (evaluates in frame when in SLDB),u ,eu 未定义函数求值调试命令:,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编译命令:,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]交叉引用命令:,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性能测量命令:,p ,pp Toggle Profile,B ,pb Profile by Substring,U ,pa Unprofile All,? ,ps Show Profiled,o ,pr Profile Report,x ,px Profile Reset文档命令:,s ,ds Describe Symbol,A ,da Apropos,h ,dh Hyperspec,] ,dt Generate TagsRepl 命令:,c ,rc Connect to Server,y ,ri Interrupt Lisp ProcessSet#1 Set#2 Command---------------------------------------------------,\ ,\ REPL 菜单 (独立菜单, 仅在 REPL 缓冲区有效)REPL 菜单命令:,. ,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
这些命令确实丰富, 基本上调试程序是够用了, 实在不够用的话也可以在 REPL
区自己手动输入相关的调试命令, 稍微麻烦一些而已.
剩下的部分我们用一个实例研演示一下这个超轻量级全功能纯文本界面的 REPL
开发环境有哪些功能, 主要参考自 slimv
的官方教程一, 二, 三:
Slimv Tutorial - Part One Slimv Tutorial - Part Two Slimv Tutorial - Part Three
实战演练
REPL 区基本操作
首先要说说 paredit
这个插件的效果, 它默认是打开的, 最简单就是自动为你补全括号, 比如你输入一个左括号 (
, 它会自动补全一个右括号 )
, 控制开关在这里, .vimrc
中增加:
let g:paredit_mode=0
它还有个功能叫 electric return
, 当你输入回车时, 会插入新行, 控制开关如下:
let g:paredit_electric_return=0
其次是 Common Lisp
中的几个快捷键, 在 REPL
区使用:
*
, **
, ***
:
可以得到 REPL
区上一次对象求值结果
+
, ++
, +++
:
可以得到 REPL
区上一次求值的形式(表达式)
效果如下:
90 CL-USER> (+ 123 345)91 46892 CL-USER> *93 46894 CL-USER> **95 46896 CL-USER> ***97 46898 CL-USER> +99 ***
100 CL-USER> ++
101 ***
102 CL-USER> (+ 123 345)
103 468
104 CL-USER> +
105 (+ 123 345)
106 CL-USER> ++
107 (+ 123 345)
108 CL-USER>
REPL =============
另外也支持历史命令查看: 可以在 Insert
模式下使用上下键
编辑源文件
开启彩虹括号
先在 ~/.vimrc
配置文件中打开 rainbow-parentheses
, 用下面这条语句:
let g:lisp_rainbow=1
这样你在编辑 lisp
文件时就会发现你的不同层次的括号对会呈现不同的颜色, 同一层次的括号对会使用相同的颜色, 效果是这样:
开始编辑代码
用 vim
建立一个新文件, 命令如下:
vi ~/code-staff/morse.lisp
下面这是一个典型的显示界面, 上半部分是 REPL
区, 下半部分是编辑区:
3 CL-USER>
~
~
~
REPL 1 (defpackage :morse2 (:use :common-lisp)3 )4 5 (in-package :)
~
~
~/code-staff/morse.lisp [+]
(in-package PACKAGE-NAME)
[0] 1:bash 2:vim* 3:bash 4:bash 5:bash- 6:REPL-CLISP "Air.local" 19:45 31- 8-15
最下面一行[0] 1:bash 2:vim* 3:bash 4:bash 5:bash- 6:REPL-CLISP "Air.local" 19:45 31- 8-15
是 tmux
的显示信息; 倒数第二行 (in-package PACKAGE-NAME)
是把光标放在编辑区的 in-package
上时 vim
给出的函数参数信息提示; 倒数第三行 ~/code-staff/morse.lisp [+]
是 vim
状态栏显示的编辑区信息.
截图如下:
文档命令
把光标移动到 defpackage
上, 进入命令模式:
输入
,s
, 就可以查看defpackage
的详细的信息;输入
,h
打开默认浏览器, 查看HyperSpec
中对defpackage
的定义;输入
,A
在REPL
区调用(apropos "defpackage")
;输入
,]
增加标签(需要事先安装好ctags
插件)
执行 ,A
的结果:
10 CL-USER> (apropos "defpackage")11 DEFPACKAGE macro12 COMMON-LISP::DEFPACKAGE-MODERNIZE13 COMMON-LISP::DEFPACKAGE-RECORD-SYMNAME14 ; No value15 CL-USER>
执行 ,s
的结果:
~/code-staff/morse.lisp [+]
DEFPACKAGE is the symbol DEFPACKAGE, lies in #<PACKAGE COMMON-LISP>, is accessible in 19 packages CLOS, COMMON-LISP, COMMON-LISP-USER,
EXPORTING, EXT, POSIX, PXREF, REGEXP, SCREEN, SWANK, SWANK-LOADER, SWANK-MONITOR, SWANK-REPL, SWANK/BACKEND, SWANK/CLISP, SWANK/GRAY,
SWANK/MATCH, SWANK/RPC, SYSTEM, names a macro, has 1 property SYSTEM::DOCHTTP/1.1 404 Not FoundHTTP/1.1 200 OK
.
ANSI-CL Documentation is at
"http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/mac_defpackage.html"HTTP/1.1 301 Moved PermanentlyHTTP/1.1 200 OKCLISP Documentation is at
"http://clisp.cons.org/impnotes/pack-intro.html#defpack"
For more information, evaluate (SYMBOL-PLIST 'DEFPACKAGE).#<PACKAGE COMMON-LISP> is the package named COMMON-LISP. It has 2 nicknames LISP, CL.It imports the external symbols of 1 package CLOS and exports 978 symbols to 18 packages SWANK-REPL, SWANK, SWANK/RPC, SWANK/MATCH,SWANK/GRAY, SWANK/CLISP, SWANK-MONITOR, PXREF, SWANK/BACKEND, SWANK-LOADER, REGEXP, POSIX, EXPORTING, SCREEN, CLOS, COMMON-LISP-USER, EXT,SYSTEM.#<MACRO #<COMPILED-FUNCTION DEFPACKAGE> (&WHOLE SYSTEM::WHOLE-FORM SYSTEM::PACKNAME &REST SYSTEM::OPTIONS)> is a macro expander.Argument list: (&WHOLE SYSTEM::WHOLE-FORM SYSTEM::PACKNAME &REST SYSTEM::OPTIONS)For more information, evaluate (DISASSEMBLE (MACRO-FUNCTION 'DEFPACKAGE)).Documentation:
SYSTEM::IMPNOTES:
"pack-intro.html#defpack"
CLHS:
"Body/mac_defpackage.html"
SYSTEM::FILE:
((SYSTEM::DEFUN/DEFMACRO#P"/opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_tarballs_ports_lang_clisp/clisp/work/clisp-2.49/s
rc/defpackage.fas"11 202))
Press ENTER or type command to continue
求值命令
现在开始调试我们的小程序, 先求值第一个形式, 把光标放在 (defpackage ...)
形式体内任何地方, 然后输入 ,d
, 我们的这个形式体就被发送到 REPL
并且完成求值, 这个命令会求值顶层的形式, 结果如下:
15 CL-USER> (defpackage :morse16 (:use :common-lisp)17 )18 #<PACKAGE MORSE>19 CL-USER>
现在再把光标移到 (in-package ...)
内并且输入 ,e
, 这个命令将会在 REPL
缓冲区求值当前的 S-表达式
, 结果如下:
19 CL-USER> (in-package :morse)20 #<PACKAGE MORSE>21 CL-USER>
我们可以在 REPL
输入 (find-package :morse)
来检查是否生效, 还可以输入 ,g
把当前包设置为 :morse
并且进入该包, 这个改变会通过 REPL
提示符的变化(变为 morse
)以及变量 *package*
反映出来:
30 #<PACKAGE MORSE>31 CL-USER> 32 MORSE>*package* 33 #<PACKAGE MORSE>34 MORSE>
现在让我们加入莫尔斯码映射函数, 在我们输入 defparameter
和 空格
后, 函数参数列表会出现在状态栏. 这个功能对于所有用户定义的函数也有效, 不仅仅是那些内建函数.
5 (in-package :morse)6 (defparameter )
~
~
~/code-staff/morse.lisp [+]
(defparameter &WHOLE WHOLE-FORM SYMBOL INITIAL-VALUE &OPTIONAL DOCSTRING)
[0] 1:bash 2:vim* 3:bash 4:bash 5:bash- 6:REPL-CLISP
现在开始填充莫尔斯映射表, 可以从网络上搜索到, 这里可以对代码进行自动缩进, 选择好区域后按 =
(貌似这里我的表现跟教程的不太一致,先写, 后面再找原因)
5 (in-package :morse)6 (defparameter *morse-mapping*7 '((#\A ".-")8 (#\B "-...")9 (#\C "-.-.")10 (#\, "--..--")11 (#\? "..--..")12 )13 )14 15 (defun character-to-morse (character)16 (assoc character *morse-mapping* :test #'char-equal)17 )18
~
输入单独的左括号
然后我们意识到我们只需要返回值的第二部分, 所以我们需要把 cdr
放在 (assoc ...)
前面,但是因为有 paredit
的缘故,我们无法输入一个单独的左括号 (
, 因为它会自动输入成对的括号 ()
, 把光标移到最前面的左括号, 也就是这个 (assoc
, 然后按下 ,w
或 ,W
(在我们的环境下大写 W
有效, 小写无效), 它会在 S-表达式
外面用一对新括号把表达式括起来(paredit wrap
), 现在我们就可以输入 cdr
了:
13 (defun character-to-morse (character)14 (cdr (assoc character *morse-mapping* :test #'char-equal)))
paredit wrap
的相反操作是 splice
, 通过按下 ,s
, 它会删除掉最外层的括号, 还有一些类似的命令:
- 输入
,o
切分S-表达式 Split S-expression - 输入
,J
加入S-表达式 Join S-expression - 输入
,I
提升子形式 Raise subform - 输入
,<
括号左移 Move left - 输入
,>
括号右移 Move right
编译
现在编译我们的代码, 输入 ,D
, 我们还可以编译和加载整个代码源文件:
,F
编译整个文件,L
编译并且加载整个文件
结果如下:
42 MORSE>43 44 Compilation finished. (No warnings) [0.003131000092253089 secs]45 46 MORSE>47 48 Compilation finished. (No warnings) [0.002271000063046813 secs]49 50 MORSE> ;; Compiling file /Users/admin/code-staff/morse.lisp ...51 ;; Wrote file /Users/admin/code-staff/morse.fas52 0 errors, 0 warnings53 MORSE>54 55 Compilation finished. (No warnings) [0.03273700177669525 secs]56 57 MORSE>
自动补全
现在是时候测试一下我们的 character-to-morse
函数了, 输入 C-w w
从代码编辑区切换到 REPL
缓冲区, 输入 char
接着按下 Tab
键, 你将会看到弹出一个可能的自动完成列表, 截图如下:
如果你继续输入更多字符, 弹出菜单中的选项会自动缩小范围匹配, 截图如下:
默认调用的方法是模糊补全 fuzzy completion
, 因此你甚至可以输入 ctm
再按 Tab
(ctm 是 character-to-morse 的首字母)
这种补全方法在 REPL
缓冲区也不受限制, 在代码编辑区它以同样的方式工作, 直到 slimv
连接到 swank
服务器上.
顺便说一句, 还有另一种 vim
的自动补全, 通过按 C-p
和 C-n
, 这种补全方式会在当前缓冲区查找相同的单词前缀, 这种方式对于补全那些不是符号名的单词比较有用, 比如注释或者字符串里的某些文本.
- 输入
Ctrl p
向前查找 - 输入
Ctrl n
向后查找
我们选择了正确的补全完成函数调用:
98 MORSE> (character-to-morse #\a)99 (".-")
100 MORSE> (character-to-morse #\b)
101 ("-...")
102 MORSE> (character-to-morse #\c)
103 ("-.-.")
104 MORSE>
我们得到的是一个列表, 里面包含一个字符串, 但是我们需要的结果是一个字符串, 我们意识到我们应该用 second
来代替函数中的 cdr
, 因此我们相应地修改代码并且按下 ,d
重新求值这个 defun
13 (defun character-to-morse (character)14 (second (assoc character *morse-mapping* :test #'char-equal)))
切换回 REPL
缓冲区, 在 Insert
模式下按下 向上
箭头来重新调用最后一条命令, 然后输入回车求值:
104 MORSE> (defun character-to-morse (character)
105 (second (assoc character *morse-mapping* :test #'char-equal)))
106 CHARACTER-TO-MORSE
107 MORSE> (character-to-morse #\c)
108 "-.-."
109 MORSE>
好极了, character-to-morse
现在返回了作为参数输入的字符的莫尔斯代码串.
截图不完整, 后面补
转载于:https://my.oschina.net/freeblues/blog/500069
Vim 下使用 Slimv(类似Slime) 轻松调试 Common Lisp相关推荐
- Win32环境下轻松调试单板安全模式软件下载功能
Win32环境下轻松调试单板安全模式软件下载功能 温辉敏(wenhm@sina.com) 摘要:本文首先提出了在单板环境下调试软件下载功能的低效率和复杂性,然后进行了Win32环境下调试软件下载功能的 ...
- vim 下web开发html css js插件
Vim下的Web开发之html,CSS,javascript插件 HTML 下载HTML.zip 解压HTML.zip,然后将里面的所有文件copy到C:\Program Files\Vim\vimf ...
- VIM使用系列之一——配置VIM下编程和代码阅读环境
作者:gnuhpc from http://blog.csdn.net/gnuhpc http://gnuhpc.wordpress.com/ 本文环境:ubuntu 10.10/vim7.2 前言 ...
- 用vim写php,Vim/Neovim中配置PHP的代码调试
使用了一段时间的Neovim(Vim的一个变种)之后,发现再也离不开了,目前已经把Neovim作为主力开发工具了.刚也把PHP的调试功能给配置上了,这里记录一下在Neovim中配置PHP调试的整个过程 ...
- 如何直接在Windows下进行ARM-Linux应用程序开发调试
偷个懒,不安装虚拟机,直接在Windows下开发 ARM Linux应用程序. 友情提醒1:本篇适合在嵌入式软件开发已经有一定基础的读者. 1 缘由 在嵌入式行业摸爬滚打了八年有余,一直都没在Linu ...
- 微寻,把“线下医院”带到“线上轻松问诊”
国内医生资源分布不均,造成人们看病难等问题,像北京.上海.广州等一线城市,医疗机构相对丰富均匀,方便当地人轻松看病,但对于以外的城市居民和城外乡民都很不利,生病了如果是小病,在当地找个医生就可以了,但 ...
- Ubuntu13.10下搭建emacs+sbcl+slime的lisp开发环境
为什么80%的码农都做不了架构师?>>> 进入ubuntu软件中心 1.安装emacs24 2.安装sbcl 3.安装slime 打开emacs,按下alt+x,输入slime ...
- Windows-Linux:Windows系统下的命令类似Linux系统下的所有命令集合
Windows-Linux:Windows系统下的命令类似Linux系统下的所有命令集合 目录 Windows下的命令类似Linux系统下的所有命令集合 1.基础命令 2.进阶命令 3.高级命令 Wi ...
- vim下更省心地用中文
在vim下使用中文是个麻烦.除了写代码,很多时候也需要做笔记. 以下介绍rime输入法的一个功能,它可以减少vim下中文输入带来的麻烦. 在***.custom.yaml下添加代码: " ...
最新文章
- java坐标点对称点的输出,编程java来确定一个对称的单词
- C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题
- 最新软件测试岗位职责大全,看看哪些你还没掌握?
- wps怎么投递简历发到boss直聘_BOSS直聘情色招聘:洗脑传销广告漫天飞,还陷虚假招聘...
- java 线程状态_浅析Java中的线程状态
- 小程序动态class_会后剧透!百度智能小程序的最新动态都在这儿了!
- java反射 动态调用_java反射拼接方法名动态执行方法
- 聊聊2019年的web前端
- 中英文对照 —— 电影与话剧、歌剧
- mysql服务器版本手册_MySQL中文参考手册——与MySQL服务器连接
- Python | 封包
- R语言学习之深圳市空气质量分析
- ubuntu下使用vscode阅读内核源码或uboot源码使用技巧——search.excludefiles.exclude
- 《追寻生命的意义》摘抄
- 终身成长----“成长型思维”
- 3D体验平台品牌应用——ENOVIA
- 夏天来了,西瓜配橙汁,来点小清新风格
- Oulipo---KMP
- 从苏宁电器到卡巴斯基第35篇:番外篇——晒一晒病毒分析师的桌面(下)
- win8.1 64位专业版,安装内存8G,显示3.25G可用,怎么办?
热门文章
- java 覆盖和隐藏_Java覆盖和隐藏2
- java的4种内部类
- mysql之存储引擎的选择
- 电脑内存和磁盘空间有什么区别与联系
- 【Leetcode】376. Wiggle Subsequence
- Nginx research, nginx module development
- 【Oracle】逻辑结构(TableSpace→Segment→Extent→Block)
- 优化asp.net ajax的脚本资源下载
- Maven Build Lifecycle
- html网页视频加滚动字幕,视频加一行滚动字幕