2011-10-06 13 views
4

今私は例のmain.cppにEmacsを使用すると、コンパイルコマンドを特定のバッファ/ディレクトリに固定することはできますか?

C-x b Makefile RET M-x compile RET RET

のためにいるとき、私は実際にはMxは、キーボードショートカットとしてコンパイルしていますが、問題は、私は本当にない希望で、コンパイルするには、次のように使用しています単に私のMakefileを実行するためにそのすべての問題を通過する必要があります。

コンパイルコマンドが同じディレクトリを使って実行されていることを確認するには、Makefileにアクセスする必要があります。私は単にM-x compile RET RETに行くことができるようにディレクトリをピンで固定する方法はありますか?

敬具

+0

私は分かりません。 .cppファイルがMakefileと同じディレクトリにないと言っていますか?それは問題ですか? – Cheeso

+0

@Cheesoまあ問題ではない*。 .cppファイルを別のディレクトリに置くのはかなり賢明だと思います。問題は、emacsが現在のバッファディレクトリを使用してコンパイルコマンドを実行していることです... – Max

答えて

4

代わりに使用recompileC-u M-x recompileを使用すると、まずコンパイルコマンドを編集できます。いずれにせよ、最後のコンパイルが行われたディレクトリからコンパイルが正常に機能します。

1

私は主にWindows上でemacsを実行します。ここ>

& & NMAKE <引数たとえば...

CD:私はCモジュールの親ディレクトリにあるMakefileを持っている場合は
、私はコンパイルコマンドとしてこれを使用します:

CD .. & & NMAKE CONFIG =は、debug platform = x64のターゲット

それ以外にも、さまざまなモジュールで実行したいmakeコマンドラインを指定するのは苦痛です。私は、編集中のバッファにデフォルトのコンパイルコマンドを付加する方法を望んでいました。だから私はその仕事を処理するために少しelispを書いた。

コンパイル:CONFIG =デバッグPLATFORMのnmake CD .. & & = x64のターゲット

私はこのように、それぞれのコメントが私の優先コンパイルコマンドを規定うラインをバッファヘッダに挿入するために考え出し

そして、私がM-x compileを呼び出す前にelispを実行して、それを実行したいコンパイルコマンドとして提案します。

この関数定義は、ヘッダコメントのラインアウトを引っ張る:

(defun cheeso-c-get-value-from-comments (marker-string line-limit) 
    "gets a string from the header comments in the current buffer. 

This is used to extract the compile command from the comments. It 
could be used for other purposes too. 

It looks for \"marker-string:\" and returns the string that 
follows it, or returns nil if that string is not found. 

eg, when marker-string is \"compile\", and the following 
string is found at the top of the buffer: 

    compile: cl.exe /I uthash 

...then this command will return the string 

    \"cl.exe /I uthash\" 

It's ok to have whitespace between the marker and the following 
colon. 

" 
    (let (start search-limit found) 
    ;; determine what lines to look in 
    (save-excursion 
     (save-restriction 
     (widen) 
     (cond ((> line-limit 0) 
       (goto-char (setq start (point-min))) 
       (forward-line line-limit) 
       (setq search-limit (point))) 
       ((< line-limit 0) 
       (goto-char (setq search-limit (point-max))) 
       (forward-line line-limit) 
       (setq start (point))) 
       (t      ;0 => no limit (use with care!) 
       (setq start (point-min)) 
       (setq search-limit (point-max)))))) 

    ;; look in those lines 
    (save-excursion 
     (save-restriction 
     (widen) 
     (let ((re-string 
       (concat "\\b" marker-string "[ \t]*:[ \t]*\\(.+\\)$"))) 
      (if (and start 
        (< (goto-char start) search-limit) 
        (re-search-forward re-string search-limit 'move)) 

       (buffer-substring-no-properties 
       (match-beginning 1) 
       (match-end 1)))))))) 

[OK]を、今私はcompileを起動する前に、それを呼び出すために何かを必要としています。

(defun cheeso-invoke-compile-interactively() 
    "fn to wrap the `compile' function. This simply 
checks to see if `compile-command' has been previously set, and 
if not, invokes `cheeso-guess-compile-command' to set the value. 
Then it invokes the `compile' function, interactively." 
    (interactive) 
    (cond 
    ((not (boundp 'cheeso-local-compile-command-has-been-set)) 
    (cheeso-guess-compile-command) 
    (set (make-local-variable 'cheeso-local-compile-command-has-been-set) t))) 
    ;; local compile command has now been set 
    (call-interactively 'compile)) 

そしてもちろん、コンパイルコマンドを推測関数定義:

(defun cheeso-guess-compile-command() 
    "set `compile-command' intelligently depending on the 
current buffer, or the contents of the current directory." 
    (interactive) 
    (set (make-local-variable 'compile-command) 
     (cond 
     (buffer-file-name 
     (let ((filename (file-name-nondirectory buffer-file-name))) 
      (cond 
      ;; editing a C-language source file - check for an 
      ;; explicitly-specified command 
      ((string-equal (substring buffer-file-name -2) ".c") 
      (let ((explicit-compile-command 
        (cheeso-c-get-value-from-comments "compile" 34))) 
       (or explicit-compile-command 
        (concat "nmake " ;; assume a makefile exists 
          (file-name-sans-extension filename) 
          ".exe")))) 

      ;; editing a makefile - just run nmake 
      ((string-equal (substring buffer-file-name -8) "makefile") 
      "nmake ") 

      ;; something else - do a typical .exe build 
      (t 
      (concat "nmake " 
        (file-name-sans-extension filename) 
        ".exe"))))) 
     (t 
     ;; punt 
     "nmake ")))) 

は、最終的なビットは、ラッパー関数定義に、通常compileに結合C-x C-eを結合することである。

(global-set-key "\C-x\C-e" 'cheeso-invoke-compile-interactively) 

今、バッファーにC-x C-eを実行すると、コンパイルコマンドが検索され、見つかったコマンドが表示されます。私は、提案されたコンパイルコマンドを編集し、次にENTERを押して実行することができます。

+0

好奇心の声から、適切な 'compile-command'をディレクトリローカル変数として設定してみませんか? – db48x

+0

それについて考えなかった。たぶんそれはフォールバックアプローチとしての良い考えです。ヘッダーにコメントがない場合、私はディレクトリローカル変数を探すことができます。 – Cheeso

+0

その場合、ディレクトリローカルバージョンを上書きするファイルローカル変数として 'compile-command'を設定してみませんか? 'mode-compile'パッケージも参照してください。 –

2

は私の答えを参照してくださいhere

ディレクトリのローカル変数は、サブディレクトリ内のすべてのソースファイルの親ディレクトリからコンパイルをトリガーするための簡単な方法を提供します。

関連する問題