如何获得基本的App< - > Emacs集成?

时间:2009-03-30 22:45:13

标签: emacs elisp

有很多应用程序将Emacs与外部进程集成在一起。 GDB是我想到的。我可以通过emacs控制GDB,然后在屏幕上获得反馈。

我希望通过我的申请在这方面做点什么。

这就是我想要的:

  • 在我和emacs之间建立联系。我可能会开始一个新的emacs进程并将其插入我的GUI
  • 告诉emacs显示文件。 (易于使用emacsclient)
  • 告诉emacs滚动到特定行号和hilite的中心,或者只是将光标移动到那里。
    • 可能真正的问题是如何从外部应用程序发送任意elisp代码以便执行emacs。
    • 我不会说elisp,但这是学习
    • 的一个很好的借口
  • 在emacs缓冲区中提供一些可点击区域,当触发时,它会将消息发送回我的应用程序。
    • 即使缺乏可点击性,发送消息的密钥绑定也是一个开始。 (但我知道可点击的东西是可能的,所以我在问)

我知道这一切都是可能的(emacs中不可能做到的?),但我不知道从哪里开始谷歌搜索。

7 个答案:

答案 0 :(得分:5)

您可能希望查看Distel(Emacs与Erlang的消息系统的集成)和SLIME(Emacs与Common Lisp之间的接口)。这是两种Emacs模式,它们通过异步对话来实现另一个系统非常令人印象深刻的集成。特别是关于Distel如何实施的paper以及其如何运作的其他一些好信息here

答案 1 :(得分:5)

这取决于你想要如何设置。绝对是关于流程的手册部分值得一读。阅读'comint包的代码是一个很好的起点。

您已经列出了一组非常有限的功能,可以通过直接连接解决。您可以通过查看'net-utils(M-x find-library net-utils RET)中提供的内容找到有用的实用程序函数。

如果您尝试连接的应用程序具有解释语言,我将连接到该应用程序,而不是在应用程序端编写自定义解析器。

从App

启动Emacs

由于你是从应用程序启动Emacs(而不是另一种方式(这可能使这项工作更容易)),这就是我可能会做的事情:

  • 写一些小的perl脚本来打开一个套接字并读/写它
  • 在解释器中设置'(read(eval(print)))循环(或编写自定义循环)并将其连接到套接字/端口
  • 使用指定套接字
  • 的函数调用(--eval或--execute)启动Emacs
  • 启动perl脚本作为子进程和端口(请参阅 inferior-lisp inferior-tcl 如何执行此操作)

此时,Emacs中的任何内容都可以发送到perl子进程('comint-send-string),然后传递给你的REPL并在那里产生预期的效果。同样,您可以通过发送字符串将命令发送回emacs,并将它们解析为您在'comint-output-filter-functions中停留的函数。

然后你会编写两个小库,一个在你的APP解释语言中,一个在Emacs中,来做任何有意义的功能。 emacs库可能应该打包为主要(或次要)模式,具体取决于文件的类型。如果他们只是与应用程序一起使用,这是一种主要模式,如果他们是(例如)C ++文件,那么你可能想要利用c ++模式更好的模式。

我在perl中编写了一个小的perl脚本,而不是elisp,只是b / c我知道如何与'comint进行交互。如果小的perl脚本可以用一大块elisp替换,并且仍然使用comint获得好处,那将是一个额外的奖励。

我对Tcl / Tk有相同的设置,只有连接内容由Tk的send命令处理。它的效果非常好。

从Emacs启动应用程序

现在,如果您可以从Emacs启动应用程序,上面仍然适用,只有您可以摆脱小perl脚本并只通过'comint界面进行交互。不需要插座。

  • 你仍然需要'repl循环(如果应用程序不能将stdin / stdout与解释器绑在一起
  • 图书馆将保持不变

这样会更容易,但只有在用户流程允许您朝这个方向前进时才有效。 (我有一种预感,你写的不仅仅是你的用途。)

话虽如此,以这种方式开发/测试可能更容易(从Emacs启动)。您可以稍后添加套接字通信作为增强功能。无论哪个更具激励性......

答案 2 :(得分:5)

可点击区域

窗口小部件库可让您将缓冲区的一部分放入按钮(也包括单选框,复选框,列表),这些按钮将在您单击它们时执行。例如:

    (require 'widget)

(defun simple-widget-example ()
   (interactive)
  (switch-to-buffer "*Simple widget example*")

  (let ((inhibit-read-only t))
    (erase-buffer))

  (let ((all (overlay-lists)))
    ;; Delete all the overlays.
    (mapcar 'delete-overlay (car all))
    (mapcar 'delete-overlay (cdr all)))

  (widget-insert "Sample button\n")
  (widget-create 'push-button
         :notify (lambda (&rest ignore) 
               (message "Poop! Ha Ha!"))
         "Press Me")

  (use-local-map widget-keymap)

  (widget-setup))

请参阅Emacs Widget Library

答案 3 :(得分:3)

您需要与Emacs对话的异步进程。查看section on processes中的Emacs手册。一个好的起点可能是start-processstart-process-shell-command函数。

例如,您可以查看使用emacs分发的man命令的源代码或vc-do-command的源代码。 (要查看源代码,请键入C-h f然后键入函数名称,然后在帮助窗口中单击该函数的名称。)

答案 4 :(得分:1)

一般情况下,您应该在emacs manual中查看。

对于您的第三个项目,请查看emacs的命令行选项。特别是--eval和-f。

答案 5 :(得分:0)

使emacs执行lisp代码只需创建一个交互式的函数,然后你可以使用M-x函数名称来调用它。以下是将重新打开文件的基本功能。

    (defun na-reopen-file ()
  "Reopen file in buffer."
  (interactive)
  (let ((p (point)))
    (progn
      (find-alternate-file buffer-file-name)
      (goto-char p) ) ) )

要与您的应用程序进行交互,您可以运行异步进程并使用缓冲区与其进行通信。检查手册中的启动过程功能。

要创建可点击链接,您可以使用以下功能

  (make-button beg end 'action 'nmap-clear-buffer 'follow-link t)
  ;;for color
  (put-text-property beg end 'face nmap-active-button )

答案 6 :(得分:0)

我不确定它会有多大帮助,但你可能想看看SLIME的实现,虽然面向lisp,但它有一些非常好的功能。例如,您可以将其设置为轻松附加到正在运行的进程。不完全是你想要的,但它有所有的部分并且很漂亮。