2

我一直在尝试找出一种方法来有效地保存程序,编译它然后在 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语句的代码,控制台窗口会显示用户应该输入数据的位置。但是我无法输入任何内容,并且编译状态一直停留在运行状态。

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

我在 Windows 中运行 emacs 24.3。我安装了 Cygwin 并将它的 bin 添加到 Windows 环境变量 Path 中(这就是 g++-3 编译工作的原因)。

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

谢谢!

4

1 回答 1

3

Emacs is programmable, so if something requires two steps, you can write a command that combines them. The simples code would look like this:

(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*")))

The above code is simple, but it has one flaw: it doesn't wait for the compilation to finish. Since smart-compile doesn't support a flag for synchronous compilation, this must be achieved by temporarily hooking into the compilation-finish-functions, which makes the code more complex:

(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))

The command can be run with M-x save-compile-execute RET or by binding it to a key.

于 2013-03-30T22:21:22.000 回答