2013-07-08 77 views
4

以下是用例:我閱讀了關於C++ 的技術博客文章(多重繼承失敗和多線程等)。 通常他們會附帶一些代碼。它幾乎總是一個文件,我幾乎總是想要運行它並玩弄它。Emacs最快的C++編譯過程?

我想用Emacs做到這一點,我想快速地做到這一點, 與最少(或相當少的)擊鍵一樣。

因此,假設我已經在其自己的文件夾 中創建了一個multiple_inheritance.cc文件並粘貼了代碼。我如何快速獲得可執行文件?

這裏是我現在正在做的事情(希望有人會改善它。)

(defun cpp-generate-makefile() 
    (interactive) 
    (let* ((n-buffer (buffer-file-name)) 
     (n-file (file-name-nondirectory n-buffer)) 
     (n-target (file-name-sans-extension n-file)) 
     (n-makefile (concat (file-name-directory n-buffer) "Makefile"))) 
    (if (file-exists-p n-makefile) 
     (when (called-interactively-p 'any) 
      (message "Makefile already exists")) 
     (with-current-buffer (find-file-noselect n-makefile) 
     (insert 
     (concat n-target ": " n-file 
       "\n\tg++ -g -O2 -std=c++0x -o [email protected] $^\n\n" 
       "clean: \n\trm -f " n-target "\n")) 
     (save-buffer))))) 

(defun cpp-run() 
    (interactive) 
    (save-buffer) 
    (cpp-generate-makefile) 
    (compile "make")) 

(add-hook 'c++-mode-hook 
     (lambda() 
      ;; ... 
      (define-key c++-mode-map [f5] 'cpp-run))) 

這裏有幾件事情,我慢下來目前:

  1. compile問我是否要保存任何打開與C++完全無關的文件。
  2. 我想在*compilation*緩衝區中發生錯誤。 我查看了compile.el,其中compilation-num-errors-found已定義, 但該變量未在該文件中的任何位置使用。
  3. 另一方面,如果沒有錯誤(我只需要一個謂詞), 爲什麼不啓動term並運行該程序?
+4

你爲什麼要指向編譯緩衝區?不需要導航,只需使用'M-g n'和'M-g p'導航錯誤。你爲什麼生成一個Makefile? GNU Make至少有[隱式規則](http://www.gnu.org/software/make/manual/make.html#Implicit-Rules),它可以[編譯C++](http://www.gnu.org /software/make/manual/make.html#Catalogue-of-Rules)。只需使用'make CXXFLAGS = '其中''是您想要的編譯標誌,''是沒有要編譯的文件的擴展名。 – lunaryorn

+1

變量'compilation-ask-about-save'用於在編譯之前詢問要保存哪些緩衝區。 – juanleon

+0

@ lunaryorn,感謝您提供捷徑。我不知道他們存在。之前,我從'* compilation *'跳轉到了'C-m'的錯誤。 關於隱含規則,這很好理解,但速度不如''快。 此外,我目前的腳本添加了一個乾淨的目標,所以我可以遞歸清理我所有的源代碼。如果我想添加更多文件,這也是一個好的開始。 –

回答

0

我已經更新了代碼,我必須添加一個run目標到Makefile。 我還添加了一個擴展到C:

(defvar cpp-generate-compiler "g++ -g -O2 -std=c++0x") 

(defun cpp-generate-makefile() 
    (interactive) 
    (let* ((n-buffer (buffer-file-name)) 
     (n-file (file-name-nondirectory n-buffer)) 
     (n-target (file-name-sans-extension n-file)) 
     (n-makefile (concat 
         (file-name-directory n-buffer) 
         "Makefile"))) 
    (if (file-exists-p n-makefile) 
     (when (called-interactively-p 'any) 
      (message "Makefile already exists")) 
     (with-current-buffer (find-file-noselect n-makefile) 
     (insert 
     (concat n-target ": " n-file 
       (format "\n\t%s -o [email protected] $^" 
        cpp-generate-compiler) 
       "\n\nclean: \n\trm -f " n-target 
       "\n\nrun: " n-target "\n\t ./" n-target 
       "\n\n.PHONY: clean run\n")) 
     (save-buffer))))) 

(defun cpp-run() 
    (interactive) 
    (save-buffer) 
    (cpp-generate-makefile) 
    (compile "make run")) 

(defun c-run() 
    (interactive) 
    (let ((cpp-generate-compiler "gcc -g -O2 -std=c99")) 
    (cpp-run))) 

(add-hook 'c++-mode-hook 
     (lambda() 
      ;; ... 
      (define-key c++-mode-map [f5] 'cpp-run))) 
(add-hook 'c-mode-hook 
     (lambda() 
      ;; ... 
      (define-key c-mode-map [f5] 'c-run))) 

(setq compilation-ask-about-save nil) 
(setq compilation-finish-functions 
     (list (lambda(buffer str) 
       (unless (string= str "finished\n") 
       (push-mark) 
       (next-error))))) 

隨着(setq compilation-ask-about-save nil)有沒有關於拯救更多 警告(cpp-run自動保存)。

而我只是要記住,M-g的正M-克對 導航誤差。

現在我的過程是neary最佳:從源的一個關鍵導致的情況下,有 是沒有錯誤。

如果有錯誤,這是一個額外的M-g n。 現在,只要有對compile一個方法來調用(push-mark)(next-error) ...

UPD:

由於@juanleon的建議,這是解決了:

(setq compilation-finish-functions 
     (list (lambda(buffer str) 
       (unless (string= str "finished\n") 
       (push-mark) 
       (next-error))))) 

但由於某些原因,push-mark在這種情況下無法正常工作。

+1

關於你最近的評論......如果有錯誤,你可以使用鉤子'compilation-finish-functions'來自動調用'next-error'。 – juanleon

2

總結評論中的答案。

  1. 更改compilation-ask-about-save的值。如果您不想全局更改(使用setq),您可以通過將它包裝在(let ((compilation-ask-about-save nil)) ...function contents...)聲明中,將它改變到函數內部。
  2. 將下一個錯誤快速綁定到:(define-key c++-mode-map "\M-j" 'next-error)。我個人使用global-set-key,因爲它在一大堆模式中很有用。
  3. 用函數(compile "make && ./a.out")替換函數中的編譯命令(當然,使用可執行文件的名稱)。

希望這會有所幫助。