2013-03-30 15 views
1

我一直在想方法來有效地保存一個程序,編譯它,然後在emacs中運行它。我只在其中部分成功。在Emacs中保存編譯 - 執行C++程序的單一快捷方式?

我使用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,智能編譯自動生成下面的編譯命令:

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

這工作只要我的.cpp沒有任何cin聲明。對於使用cin語句的代碼,控制檯窗口顯示用戶應該輸入數據的點。但是我無法輸入任何內容,編譯狀態一直處於停滯狀態。

爲了使用戶輸入工作的代碼,我必須刪除&& FILENAME部分,然後在emacs的eshell中手動運行./FILENAME

我在Windows上運行emacs 24.3。我已經安裝了Cygwin,並將其bin添加到Windows環境變量Path(這就是爲什麼g ++ -3編譯有效)。

如果有人能指導我如何使用單個命令在emacs中保存編譯運行用戶輸入所需的.cpp程序,我將不勝感激。或者至少我需要如何修改上面的g ++ - 3命令來編譯+運行用戶輸入程序。

謝謝!

回答

3

Emacs是可編程的,所以如果某件事需要兩個步驟,您可以編寫一個組合它們的命令。該simples代碼應該是這樣的:

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

該命令可以的Mxsave-compile-executeRET運行或通過綁定到一個鍵。

+0

感謝您的快速回復。我使用了你建議的功能,但它不適合我。我收到一個錯誤'錯誤的類型參數:number-or-marker-p,nil'。我對Emacs Lisp語法不熟悉,所以我會嘗試自己理解這個問題,如果該錯誤看起來很熟悉,請更新可能出錯的內容。 –

+0

謝謝!我已經嘗試過了。它幾乎可以工作。現在唯一的問題是編譯結束之前'(insert exe)'部分立即運行。函數是否有辦法等待編譯結束?另外,我必須用'「./% n」'替換'「%n」',然後工作正常。截至目前,它第一次出錯,但第二次運行'save-compile-execute'命令時,它的工作原理與上次生成的.exe文件完全相同。 –

+0

更新:我不知道如何等待編譯完成。但對於我正在練習的小碼,3秒就足夠了。所以在'(smart-compile 1)'之後加上'(sit-for 3)''就行了:) –