我是lisp的新手,我无法弄清楚如何在emacs中创建一个具有以下功能的宏:假设我厌倦了用c ++编写for循环中的模式:
for (int i = 0; i < N; i++) {
}
将此宏称为“forloop”,然后我想执行以下操作:当我输入“M-x forloop”时,宏打印出来
for (int
在缓冲区中并等待输入。然后我输入“i”并点击返回,之后宏继续并打印
for (int i = 0; i <
再次等待输入。最后,在我输入“N”并点击返回后,宏通过打印其余部分完成:
for (int i = 0; i < N; i++) {
}
经过一些广泛的阅读和测试后,我能够编写简单的lisp函数,创建自己的宏,保存它们并调用它们等等......但我仍然无法弄清楚如何制作一个宏像我上面描述的那样。任何想法将不胜感激!提前谢谢!
像这样的宏对于加速任何语言的编码都非常好。我希望宏在描述的方式中是动态的,这样你就不必记住它需要多少个参数以及它们在调用它时的顺序。
答案 0 :(得分:1)
我使用yasnippet(http://www.emacswiki.org/emacs/Yasnippet),但还有很多其他解决方案。
在yasnippet中,为你的代码段(比如说)和yasnippet键快捷键输入一个关键字,然后你要填充字段,使用tab从一个字段转到下一个字段。
每个片段都是在自己的文件中定义的一些易于学习的DSL。
答案 1 :(得分:1)
对于这个问题,我不知道比yasnippet
更好的事情。
这是相关的片段:
# -*- mode: snippet -*-
#name : for (...; ...; ...) { ... }
# --
for (unsigned int ${1:i}=0; $1<${2:N}; ++$1)$0
请注意,有两个参数(零是退出点), 两者都有默认值,但您只需输入即可更改它们。
yasnippet
我强烈建议将yas/expand
绑定到 C-o ,这样它
与auto-complete-mode
没有冲突。
此快捷方式的默认绑定几乎没用,但它已经进入
一个很好的位置:
(global-set-key "\C-o" 'aya-open-line)
(defun aya-open-line ()
(interactive)
(cond ((expand-abbrev))
((yas/snippets-at-point)
(yas/next-field-or-maybe-expand-1))
(((yas/expand)))))
这样,扩展和移动到下一个字段的快捷方式
是一样的,这让你很快。
另请注意,expand-abbrev
优先:您可以填写
c++-mode
的缩写表,用于您使用的内容。
简称不参加辩论,但他们都住在一张桌子上,
而不是每个yasnippet都存在于自己的文件中,所以它就是这样
很容易编辑缩写。
我不建议把括号放在yasnippet
中,
因为有时你需要它们,有时你不需要它们。
我改用这个函数:
(defun ins-c++-curly ()
"Insert {}."
(interactive)
(if (looking-back "\\()\\|try\\|else\\|const\\|:\\)$")
(progn
(insert " {\n\n}")
(indent-according-to-mode)
(forward-line -1)
(indent-according-to-mode))
(insert "{}")
(backward-char))
答案 2 :(得分:0)
您可以在sgml-mode.el
中看到类似的宏,例如html-href-anchor
,它会插入一个HREF锚点(显然: - )。
如果您将此标记为[elisp],您将获得更具体的答案。
答案 3 :(得分:0)
如果您正在阅读本文并想知道如何使用yasnippit执行我所要求的操作,那么这是我的yasnippit文件:
# name: fori ... { ... }
# key: fori
# --
for (int ${1:intname} = 0; ${1:$(yas-substr text "[^: ]*")} < ${2:max}; ${1:$(yas-substr text "[^: ]*")}++) {
$0
}
请注意,yasnippit已经具有&#34; for&#34;的功能。在c ++模式下,但我不喜欢它的表现方式。
结论,yasnippit很棒,非常容易!谢谢你的建议!