7

When editing TeX files, programming, upgrading packages, etc. we often need to perform tasks - such as compiling code or downloading files from internet - that take a long time to achieve. We can do all of them in Emacs, however executing such commands freezes the session: is there a way to execute heavy commands in the background, for example using another thread ?

Dan
  • 32,584
  • 6
  • 98
  • 168
Spirine
  • 153
  • 1
  • 8
  • 1
    See the manual node on [asynchronous processes](https://www.gnu.org/software/emacs/manual/html_node/elisp/Asynchronous-Processes.html). – Dan Feb 09 '17 at 15:48
  • @Dan You could create an answer from your comment. This would mark this question solved. – Tobias Feb 09 '17 at 16:52
  • Note, that you should also follow the links at https://www.gnu.org/software/emacs/manual/html_node/elisp/Asynchronous-Processes.html. In my opinion the infos on filters and process sentinels are important. I almost always used `start-process` and never `make-process` until now. But, `make-process` definitively looks very interesting! – Tobias Feb 09 '17 at 16:52
  • @Tobias -- `start-process` is 6 lines long, excluding the doc-string, and it uses `make-process` as its main ingredient. So the comment about potentially using `make-process` in lieu of `start-process` is somewhat confusing (absent some explanation). – lawlist Feb 13 '17 at 20:03
  • @lawlist: With "**looks** very interesting" I meant that one has to look at the linked description. One has a lot of more fine control with `make-process`. One can give a sentinel, filter functions and so on. – Tobias Feb 14 '17 at 08:28

1 Answers1

1

You need to use process sentinels. Try for example this:

(require 'tex-site)
(defun build-view ()
  "Build LaTeX and view if file is dirty. View only otherwise."
  (interactive)
  (if (buffer-modified-p)
      (let (build-proc
        (TeX-save-query nil)
        (LaTeX-command-style '(("" "%(PDF)%(latex) -shell-escape -file-line-error %S%(PDFout)"))))
    (TeX-save-document (TeX-master-file))
    (setq build-proc (TeX-command "LaTeX" 'TeX-master-file -1))
    (set-process-sentinel  build-proc  'build-sentinel))
    (TeX-view)))

(defun build-sentinel (process event)
"Sentinel to run viewer after successful LaTeXing"
  (if (string= event "finished\n")
      (TeX-view)
    (message "Errors! Check with C-c `")))

In this case, when the LaTeX buffer has been modified, (set-process-sentinel build-proc 'build-sentinel) runs the build process (TeX-command "LaTeX" 'TeX-master-file -1) in the background. Sentinel functions, here build-sentinel, monitor a process running in the background without blocking Emacs. In this case, when build-sentinel detects the build process is finished, it starts the PDF viewer.

There are other functions involved, for example LaTeX-command-style defines what flavour of LaTeX command you will actually run; but the main point to craft an asynchronous process is in the function setting the sentinel.

antonio
  • 1,762
  • 12
  • 24