使用Emacs,是否可以将编译命令固定到特定的缓冲区/目录?

时间:2011-10-06 16:53:54

标签: emacs compilation keyboard-shortcuts

现在我正在使用以下代码进行编译,当时我正在使用main.cpp

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

我实际上有M-x编译作为键盘快捷键,但问题是我真的不想通过简单地运行我的Makefile来解决所有麻烦。

我需要访问Makefile以确保使用相同的目录执行编译命令。有没有办法固定目录,所以我可以简单地去M-x compile RET RET

祝你好运

3 个答案:

答案 0 :(得分:4)

请改用recompileC-u M-x recompile将允许您首先编辑编译命令。无论哪种方式,编译都将在最后一次编译完成的目录之外。

答案 1 :(得分:2)

请参阅我的回答here

目录本地变量提供了一种从子目录中任何源文件的父目录触发编译的简便方法。

答案 2 :(得分:1)

我主要在windows上运行emacs 当我有一个位于C模块父目录中的makefile时,我将其用作编译命令:

  

cd ..&& nmake< arguments here>

例如:

  

cd ..&& nmake CONFIG = Debug PLATFORM = x64 target

除此之外,我发现指定我想为各种模块运行的make命令行是一种痛苦。我想要一种方法将默认编译命令附加到正在编辑的缓冲区。所以我写了一个小小的elisp来处理那份工作。我想在每个缓冲区的标题注释中插入一条规定我首选编译命令的行,如下所示:

  

编译:cd ..&& nmake CONFIG = Debug PLATFORM = x64 target

然后有一段elisp运行,然后我调用抓取该行的M-x compile并将其作为我想要运行的编译命令提出。

这个defun从标题注释中拉出一行:

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

好的,现在我需要在调用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:

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

最后一点是将通常绑定到C-x C-e的{​​{1}}绑定到包装器defun:

compile

现在,当我在缓冲区中执行(global-set-key "\C-x\C-e" 'cheeso-invoke-compile-interactively) 时,它会搜索编译命令,并向我建议它找到的命令。我可以编辑建议的编译命令,然后按ENTER键并运行它。