0

我是 lisp 新手,无法弄清楚如何在 emacs 中创建具有以下功能的宏:假设我厌倦了在 c++ 中为 for 循环编写模式:

for (int i = 0; i < N; i++) {

}

将此宏称为“forloop”,然后我想做以下事情:当我输入“Mx forloop”时,宏会打印出来

for (int 

在缓冲区中并等待输入。然后我输入“i”并按回车键,然后宏继续并打印

for (int i = 0; i < 

并再次等待输入。最后,在我输入“N”并点击返回后,通过打印其余部分来完成宏:

for (int i = 0; i < N; i++) {

}

经过一些广泛的阅读和测试,我能够编写简单的 lisp 函数,创建自己的宏,保存并调用它们等等......但我仍然不知道如何制作一个类似的宏我上面已经描述过了。任何想法将不胜感激!提前致谢!

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

4

4 回答 4

1

我为此使用 yasnippet ( http://www.emacswiki.org/emacs/Yasnippet ),但还有很多其他解决方案。

在 yasnippet 中,您为您的片段(例如)键入一个关键字,然后输入 yasnippet 快捷键,然后您有要填写的字段,使用制表符从一个字段转到下一个字段。

每个片段都在一些易于学习的 DSL 中定义在自己的文件中。

于 2013-08-10T06:34:34.593 回答
1

我不知道有什么比yasnippet这个问题更好的了。这是相关的片段:

# -*- mode: snippet -*-
#name : for (...; ...; ...) { ... }
# --
for (unsigned int ${1:i}=0; $1<${2:N}; ++$1)$0

请注意,有两个参数(零是退出点),都有默认值,但您只需键入即可更改它们。

键绑定yasnippet

我强烈建议绑定yas/expandC-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))
于 2013-08-10T09:36:22.180 回答
0

如果您正在阅读本文并想知道如何使用 yasnippit 执行我所要求的操作,这里是我的 yasnippit 文件:

# name: fori ... { ... }
# key: fori
# --
for (int ${1:intname} = 0; ${1:$(yas-substr text "[^: ]*")} < ${2:max}; ${1:$(yas-substr text "[^: ]*")}++) {
$0
}

请注意,yasnippit 在 c++ 模式下已经有一个用于“for”的函数,但我不喜欢它的行为方式。

结论,yasnippit 很棒而且超级简单!感谢您的建议!

于 2013-08-10T19:07:47.170 回答
0

sgml-mode.el例如,您可以在 中看到类似的宏html-href-anchor,它插入 HREF 锚点(显然 :-)。

如果您将其标记为 [elisp],您将获得更具体的答案。

于 2013-08-10T05:38:10.507 回答