Waiting on compilation to finish

2019-07-25 12:18发布

I am using compile to pull new files from source tree using mercurial "hg pull". I am performing a save of all buffers before the pull and would like to "refresh all opened buffers" after the compilation "pulling" finishes. I tried experimenting with compilation-finish-functions but found out that the functions added to the list will be executed after "every" compilation. Since I use compile to search IDs "gid" I don't want to refresh opened files on every search. How can I wait on compilation to finish before refreshing opened files "only" while inside a command and not on every compile outside of the command. Here is the code:

; From http://www.emacswiki.org/emacs/CompileCommand
(defun compile-pkg (&optional command startdir)
  "Compile a package, moving up to the parent directory
  containing configure.ac, if it exists. Start in startdir if defined,
  else start in the current directory."
  (interactive)
  (let ((dirname) (dir-buffer nil))
    (setq startdir (expand-file-name (if startdir startdir ".")))
    (setq command  (if command command compile-command))
    (setq dirname (upward-find-file "Makefile" startdir))
;    (setq dirname (if dirname dirname (upward-find-file "Makefile" startdir)))
;    (setq dirname (if dirname dirname (expand-file-name ".")))
    ; We've now worked out where to start. Now we need to worry about
    ; calling compile in the right directory
    (save-excursion
      (setq dir-buffer (find-file-noselect dirname))
      (set-buffer dir-buffer)
      (compile command)
      (kill-buffer dir-buffer)
      )))

(defun upward-find-file (filename &optional startdir)
  "Move up directories until we find a certain filename. If we
  manage to find it, return the containing directory. Else if we
  get to the toplevel directory and still can't find it, return
  nil. Start at startdir or . if startdir not given"
  (let ((dirname (expand-file-name
                  (if startdir startdir ".")))
        (found nil) ; found is set as a flag to leave loop if we find it
        (top nil))  ; top is set when we get
                    ; to / so that we only check it once
    ; While we've neither been at the top last time nor have we found
    ; the file.
    (while (not (or found top))
      ; If we're at / set top flag.
      (if (string= (expand-file-name dirname) "/")
          (setq top t))
      ; Check for the file
      (if (file-exists-p (expand-file-name filename dirname))
          (setq found t)
        ; If not, move up a directory
        (setq dirname (expand-file-name ".." dirname))))
    ; return statement
    (if found (concat dirname "/") nil)))

(defun compile-hgpull ()
  (interactive)
  (save-all-buffers)
  (compile-pkg "hg pull -u")
; if (compile finished) -> (revert-all-buffers)
  )

(global-set-key [f1]    'compile-hgpull) 

标签: emacs elisp
2条回答
太酷不给撩
2楼-- · 2019-07-25 13:14

If you want to run a shell-command synchronously, and then see its output, it might be easier to use shell-command-to-string than compile.

查看更多
Viruses.
3楼-- · 2019-07-25 13:24

compile is async. So, you have two choices.

One, don't use compile. Instead use one of the other ways to invoke a shell command, like shell-command or start-process or call-process. I think this is probably preferred; I don't see why you'd need to use compile here.

Two, set compilation-finish-function.

查看更多
登录 后发表回答