在Emacs中保存编译执行C ++程序的单一快捷方式?

时间:2013-03-30 21:49:47

标签: c++ windows emacs g++ user-input

我一直试图找到一种方法来有效地保存程序,编译它然后在emacs中运行它。我只是部分成功了。

我使用smart-compile.el来简化工作(http://emacswiki.org/emacs/smart-compile.el)。 我已经编辑了下面的C ++相关部分,以便在我键入M-x smart-compile RET后跟RET时编译并运行程序。

(defcustom smart-compile-alist '(
  ;; g++-3 is used instead of g++ as the latter does not
  ;; work in Windows. Also '&& %n' is added to run the
  ;; compiled object if the compilation is successful
  ("\\.[Cc]+[Pp]*\\'" . "g++-3 -O2 -Wall -pedantic -Werror 
  -Wreturn-type %f -lm -o %n && %n")
  ..

举一个例子,对于一个程序sqrt.cpp,smart-compile auto会生成以下编译命令:

g++-3 -O2 -Wall -pedantic -Werror -Wreturn-type sqrt.cpp -lm -o sqrt && sqrt

只要我的.cpp没有任何cin语句,这就有效。对于具有cin语句的代码,控制台窗口显示用户应输入数据的点。但我无法输入任何内容,而且Compilations状态仍然停留在运行状态。

为了使用户输入的代码生效,我必须删除&& FILENAME部分,然后在emacs'./FILENAME中手动运行eshell

我在Windows中运行emacs 24.3。我安装了Cygwin并将其bin添加到Windows环境变量Path(这就是为什么g ++ - 3编译有效)。

如果有人可以指导我如何使用单个命令在emacs中保存编译运行用户输入所需的.cpp程序,我将不胜感激。或者至少我如何修改上面的g ++ - 3命令以使编译+运行工作用于用户输入程序。

谢谢!

1 个答案:

答案 0 :(得分:3)

Emacs是可编程的,因此如果需要两个步骤,您可以编写一个组合它们的命令。简单代码如下所示:

(defun save-compile-execute ()
  (interactive)
  (smart-compile 1)                          ; step 1: compile
  (let ((exe (smart-compile-string "%n")))   ; step 2: run in *eshell*
    (with-current-buffer "*eshell*"
      (goto-char (point-max))
      (insert exe)
      (eshell-send-input))
    (switch-to-buffer-other-window "*eshell*")))

上面的代码很简单,但它有一个缺陷:它不等待编译完成。由于smart-compile不支持同步编译的标志,因此必须通过暂时挂钩compilation-finish-functions来实现,这会使代码更复杂:

(require 'cl)  ; for lexical-let

(defun do-execute (exe)
  (with-current-buffer "*eshell*"
    (goto-char (point-max))
    (insert exe)
    (eshell-send-input))
  (switch-to-buffer-other-window "*eshell*"))

(defun save-compile-execute ()
  (interactive)
  (lexical-let ((exe (smart-compile-string "./%n"))
                finish-callback)
    ;; when compilation is done, execute the program
    ;; and remove the callback from
    ;; compilation-finish-functions
    (setq finish-callback
          (lambda (buf msg)
            (do-execute exe)
            (setq compilation-finish-functions
                  (delq finish-callback compilation-finish-functions))))
    (push finish-callback compilation-finish-functions))
  (smart-compile 1))

该命令可以使用 M-x save-compile-execute RET 运行,也可以将其绑定到密钥。