举个例子(let):
(let ((${1:var1} ${2:exp1}))
${0:body})
当你打完第一个var-exp对之后,怎么跳到外层打第二个var-exp对?
一种解决方法是:
(let ((${1:var1} ${2:exp1})
(${3:var2} ${4:exp2}))
${0:body})
这种方法只能打两个var-exp对,如果你刚好只有一个var-exp对,或者有3个及以上var-exp对则无能为力(成为多余代码)。
你们是怎么处理这种情况的?(注意:exp本身还可能嵌套)
PS:我知道可以使用paredit(我自己也在用),但感觉paredit还是容易导致思维打断,特别是在写算法的时候希望能一气呵成。
zw963
2
理论上, yasnippet 可以使用任何 LISP 代码来做需要的事,但是你这个需求, 我反正是不知道该怎么搞,
换做是我,会多写 let1 let2 let3 几个 snippet …
1 个赞
snippet 状态很容易遭到干扰/破坏,一旦中断就无法继续,所以不适合做太复杂的事。
如果只有一个 TAB
键,如何区分跳到 $N
还是 $0
?这是必须要解决的问题:
(let ((${1:var-val)
(${2:var-val)
(${3:var-val)
...
(${N:var-val))
(${0:body))
嗯,我也是问一下大家有什么好办法。
zw963的方法很不错,我已经写了几个let,目前感觉良好。
我写了一个 letn
# -*- coding: utf-8; mode: snippet -*-
# contributor: [email protected]
# name: let with N var-val forms
# key: letn
# type: command
# --
(let ((yas-good-grace nil)
(forms '()))
(while (let ((form (read-string (format "form%d (RET to submit): " (1+ (length forms))))))
(unless (string-blank-p form)
(push form forms))))
(yas-expand-snippet
(concat "(let ("
(s-join "\n" (reverse forms))
")\n$0)")))
在 minibuffer 输入不定个 var-val
对,每输入一对,以回车作为结束,开始输入下一对,最后回车提交空白,跳转光标到 body。
相关帖子 请教一个关于yasnippet模板制作的问题 - #11,来自 twlz0ne
试试匿名 snippet ,ultisnips 就是这么实现的。
不过你这个方法没有let1 let2 let3好用,因为在代码里不会出现let的部分形式。
但是还是谢谢你:我原来不知道yasnippent还能用elisp和交互。
我做了一点小小改进:
# -*- coding: utf-8; mode: snippet -*-
# contributor: [email protected]
# name: let with N var-val forms
# key: letn
# type: command
# --
(let ((yas-good-grace nil)
(forms '())
(beg (point))
ov)
(insert "(let ())")
(setq ov (make-overlay beg (point) nil nil t))
(backward-char 2)
(while (let ((form (read-string
(format "Input FORM%d (RET to submit): "
(1+ (length forms))))))
(unless (string-blank-p form)
(insert form)
(insert "\n")
(indent-for-tab-command)
(push form forms))))
(yas-expand-snippet (concat "(let ("
(mapconcat 'identity (reverse forms) "\n")
")\n$0)")
(overlay-start ov)
(overlay-end ov))
(delete-overlay ov))
我后来发现了一个新的方法,能够解决变长参数
比方说:我现在的let-1
# -*- mode: snippet -*-
# name: (let ([name e]+) e)
# key: let
# --
(let ((${1:var exp})$2)
${3:body})
注意里面的$2,在写好第1个var-exp对之后,可以TAB到$2的位置,这个地方你可以打回车。
然后再配合 company-yasnippet-autoparens 就可以很方便的输入第2个var-exp对,然后tab出来(因为第2个var-exp对现在也是snippet,而不是像原来那样自己打的括号,所以可以TAB出来)
确实。每个人都习惯自己的方式。
比如我用 snippet 是为了生成那些我记不住的代码/结构,比如在写 elisp 的时侯 doc<TAB>
帮我生成文档骨架,省得我去翻以前的文件复制粘贴。
而相 let 这样的基本结构,我通常直接手打,因为情急之下,根本不会去想是否有 snippet 可用。只有想不起来怎么写,才会去找 snippet。
另一个我不太使用 snippet 的原因是,它的状态容易被破坏。只有当我编辑 field-n
无误(甚至一些快捷键也会打断展开过程)的情况下,才能顺利跳至 field-n+1
。
3 个赞
费这么多劲最后成果只是少打几个括号么……是这样的话,你需要改键软件/键盘固件来把左右shift改成“短点输出左右括号,长按/组合按还是shift”