如何为文本模板创建emacs宏

时间:2013-08-10 05:06:20

标签: c++ emacs elisp

我是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函数,创建自己的宏,保存它们并调用它们等等......但我仍然无法弄清楚如何制作一个宏像我上面描述的那样。任何想法将不胜感激!提前谢谢!

像这样的宏对于加速任何语言的编码都非常好。我希望宏在描述的方式中是动态的,这样你就不必记住它需要多少个参数以及它们在调用它时的顺序。

4 个答案:

答案 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很棒,非常容易!谢谢你的建议!