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

发布于 2024-12-08 22:09:10 字数 269 浏览 1 评论 0原文

现在我正在使用以下内容进行编译,例如,当我在 main.cpp

Cx b Makefile RET Mxcompile RET RET

中时,我实际上将 Mxcompile 作为键盘快捷键,但问题是我我真的很希望不必经历所有这些麻烦来简单地运行我的 Makefile。

我需要访问 Makefile 以确保使用同一目录执行编译命令。有什么方法可以固定目录,以便我可以简单地进行Mx编译RET RET

此致

Right now I am using the following to compile, when I'm in for example main.cpp

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

I actually have M-x compile as a keyboard shortcut, but the problem is I would really like not having to go through all that trouble to simply run my Makefile.

I need to visit Makefile to make sure the compile command is executed using the same directory. Is there any way to pin the directory so I can simply go M-x compile RET RET?

Best regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

時窥 2024-12-15 22:09:10

请改用重新编译Cu Mx recompile 将让您首先编辑编译命令。无论哪种方式,编译都会在上次编译完成的目录中进行。

Use recompile instead. C-u M-x recompile will let you edit the compile command first. Either way the compile will work out of the directory the last compile was done in.

萌梦深 2024-12-15 22:09:10

请参阅我的答案此处

目录局部变量提供了一个简单的方法从子目录中任何源文件的父目录触发编译的方法。

See my answer here

Directory local variables provide an easy way to trigger the compile from a parent directory of any source file in a subdirectory.

記柔刀 2024-12-15 22:09:10

我主要在 Windows 上运行 emacs。
当我的 makefile 位于 C 模块的父目录中时,我使用它作为编译命令:

cd ..&& nmake <此处的参数>

例如:

cd ..&& nmake CONFIG=调试平台=x64 目标

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

编译:cd .. && nmake CONFIG=调试平台=x64 目标

然后运行一段 elisp,然后调用 Mxcompile 来获取该行并将其建议为我想要运行的编译命令。

这个 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 "))))

最后一点是将通常绑定到 compileCx Ce 绑定到包装器 defun:

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

现在,当我这样做时Cx Ce 在缓冲区中,它搜索编译命令,并向我建议它找到的命令。我可以编辑建议的编译命令,然后按 ENTER 并运行它。

I run emacs primarily on windows.
When I have a makefile that is in a parent directory of a C module, I use this as the compile command:

cd .. && nmake <arguments here>

for example:

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

Beyond that, I find that specifying the make command line that I want to run for various modules is sort of a pain. I wanted a way to attach the default compile command to the buffer being edited. So I wrote a little elisp to handle that job. I figured to insert into the header comments of each buffer a line that would stipulate my preferred compile command, like this:

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

And then have a piece of elisp run, before I invoke M-x compile that grabs the line and proposes it as the compile command I would like to run.

This defun pulls a line out of the header comments:

(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, now I need something to invoke that before I invoke 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))

Then of course, the defun that guesses the compile command:

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

The final bit is to bind C-x C-e , normally bound to compile, to the wrapper defun:

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

Now, when I do C-x C-e in the buffer, it searches for the compile command, and proposes to me the command that it finds. I can edit the proposed compile command, then press ENTER and run it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文