2019独角兽企业重金招聘Python工程师标准>>>

Vim 下使用 Slimv(类似Slime) 轻松调试 Common Lisp

目录

  • 前情回顾
  • 安装slimv
  • 数据配置
  • 默认快捷键
  • 实战演练

前情回顾

在上一篇文章想法验证:超轻量级全功能纯文本界面 REPL 类语言 IDE: Vim+Tmux+Slimv中我们对于在 tmux 中新建窗口运行 swank 服务端的想法经过了手工验证, 证明了我们的想法是可行的, 本文则完成实际的配置, 把所有的配置信息都写入到配置文件中.

安装slimv

如果你看过上一篇文章并且照着做了, 那你的 slimv 已经安装好了. 如果没有安装的话可以按照下面的操作来安装:

我们继续通过 pathogen 来管理 slimv 插件, 也就是说, 只要进入 .vim/bundle/ 目录下, 把 slimvgit 克隆进去, 暂时不做配置, 因为我们要手动进行试验, 安装命令如下:

cd ~/.vim/bundle/
git clone

安装就这么简单, 如果对于 pathogen 的安装有不清楚的地方可以看看本系列第一篇文章里的描述超轻量级纯文本界面 REPL 类语言 IDE.

接下来就是数据配置了.

数据配置

Linux 和 OSX 平台下的配置

主要是对 vim 的配置, 因为我们要从vim 中启动 slimvswank, 只要在你原来的 .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, sbclccl 的配置分别为:

" 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-15tmux 的显示信息; 倒数第二行 (in-package PACKAGE-NAME) 是把光标放在编辑区的 in-package 上时 vim 给出的函数参数信息提示; 倒数第三行 ~/code-staff/morse.lisp [+]vim 状态栏显示的编辑区信息.

截图如下:

文档命令

把光标移动到 defpackage 上, 进入命令模式:

  • 输入 ,s, 就可以查看 defpackage 的详细的信息;

  • 输入 ,h 打开默认浏览器, 查看 HyperSpec 中对 defpackage 的定义;

  • 输入 ,AREPL 区调用 (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-pC-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相关推荐

  1. Win32环境下轻松调试单板安全模式软件下载功能

    Win32环境下轻松调试单板安全模式软件下载功能 温辉敏(wenhm@sina.com) 摘要:本文首先提出了在单板环境下调试软件下载功能的低效率和复杂性,然后进行了Win32环境下调试软件下载功能的 ...

  2. vim 下web开发html css js插件

    Vim下的Web开发之html,CSS,javascript插件 HTML 下载HTML.zip 解压HTML.zip,然后将里面的所有文件copy到C:\Program Files\Vim\vimf ...

  3. VIM使用系列之一——配置VIM下编程和代码阅读环境

    作者:gnuhpc from http://blog.csdn.net/gnuhpc  http://gnuhpc.wordpress.com/ 本文环境:ubuntu 10.10/vim7.2 前言 ...

  4. 用vim写php,Vim/Neovim中配置PHP的代码调试

    使用了一段时间的Neovim(Vim的一个变种)之后,发现再也离不开了,目前已经把Neovim作为主力开发工具了.刚也把PHP的调试功能给配置上了,这里记录一下在Neovim中配置PHP调试的整个过程 ...

  5. 如何直接在Windows下进行ARM-Linux应用程序开发调试

    偷个懒,不安装虚拟机,直接在Windows下开发 ARM Linux应用程序. 友情提醒1:本篇适合在嵌入式软件开发已经有一定基础的读者. 1 缘由 在嵌入式行业摸爬滚打了八年有余,一直都没在Linu ...

  6. 微寻,把“线下医院”带到“线上轻松问诊”

    国内医生资源分布不均,造成人们看病难等问题,像北京.上海.广州等一线城市,医疗机构相对丰富均匀,方便当地人轻松看病,但对于以外的城市居民和城外乡民都很不利,生病了如果是小病,在当地找个医生就可以了,但 ...

  7. Ubuntu13.10下搭建emacs+sbcl+slime的lisp开发环境

    为什么80%的码农都做不了架构师?>>>    进入ubuntu软件中心 1.安装emacs24 2.安装sbcl 3.安装slime 打开emacs,按下alt+x,输入slime ...

  8. Windows-Linux:Windows系统下的命令类似Linux系统下的所有命令集合

    Windows-Linux:Windows系统下的命令类似Linux系统下的所有命令集合 目录 Windows下的命令类似Linux系统下的所有命令集合 1.基础命令 2.进阶命令 3.高级命令 Wi ...

  9. vim下更省心地用中文

    在vim下使用中文是个麻烦.除了写代码,很多时候也需要做笔记. 以下介绍rime输入法的一个功能,它可以减少vim下中文输入带来的麻烦. 在***.custom.yaml下添加代码:   " ...

最新文章

  1. java坐标点对称点的输出,编程java来确定一个对称的单词
  2. C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题
  3. 最新软件测试岗位职责大全,看看哪些你还没掌握?
  4. wps怎么投递简历发到boss直聘_BOSS直聘情色招聘:洗脑传销广告漫天飞,还陷虚假招聘...
  5. java 线程状态_浅析Java中的线程状态
  6. 小程序动态class_会后剧透!百度智能小程序的最新动态都在这儿了!
  7. java反射 动态调用_java反射拼接方法名动态执行方法
  8. 聊聊2019年的web前端
  9. 中英文对照 —— 电影与话剧、歌剧
  10. mysql服务器版本手册_MySQL中文参考手册——与MySQL服务器连接
  11. Python | 封包
  12. R语言学习之深圳市空气质量分析
  13. ubuntu下使用vscode阅读内核源码或uboot源码使用技巧——search.excludefiles.exclude
  14. 《追寻生命的意义》摘抄
  15. 终身成长----“成长型思维”
  16. 3D体验平台品牌应用——ENOVIA
  17. 夏天来了,西瓜配橙汁,来点小清新风格
  18. Oulipo---KMP
  19. 从苏宁电器到卡巴斯基第35篇:番外篇——晒一晒病毒分析师的桌面(下)
  20. win8.1 64位专业版,安装内存8G,显示3.25G可用,怎么办?

热门文章

  1. java 覆盖和隐藏_Java覆盖和隐藏2
  2. java的4种内部类
  3. mysql之存储引擎的选择
  4. 电脑内存和磁盘空间有什么区别与联系
  5. 【Leetcode】376. Wiggle Subsequence
  6. Nginx research, nginx module development
  7. 【Oracle】逻辑结构(TableSpace→Segment→Extent→Block)
  8. 优化asp.net ajax的脚本资源下载
  9. Maven Build Lifecycle
  10. html网页视频加滚动字幕,视频加一行滚动字幕