Функция emacs после асинхронной команды
В настоящее время я использую emacs для создания и редактирования документов LaTeX. При компиляции я использую внешнюю программу для компиляции в pdf. Прямо сейчас со следующим кодом в моем .emacs
файл, emacs начнет компилировать документ в PDF каждый раз, когда я сохраняю файл.
(defun auto-compile-latex ()
(save-window-excursion
(async-shell-command (format "cd %s; scons -u" default-directory))))
(add-hook 'LaTeX-mode-hook '(lambda ()
(add-hook 'after-save-hook 'auto-compile-latex nil 'make-it-local)))
Я предпочитаю это M-x compile
потому что у меня больше привычка экономить, и она запускается в фоновом режиме, что позволяет мне продолжать работать. Однако я не получаю заметного уведомления о завершении процесса компиляции.
В идеале я хотел бы запускать следующую функцию всякий раз, когда завершается процесс компиляции.
(defun latex-compilation-status (exit-code)
(if (/= exit-code 0)
(setq mode-name (propertize mode-name 'face 'font-lock-warning-face))
(setq mode-name (propertize mode-name 'face 'mode-line-highlight))))
Таким образом, я могу изменить цвет строки режима в зависимости от того, была ли успешной компиляция или нет. Однако, просматривая документацию по emacs, я не нашел упоминаний о хуке, который запускается после async-shell-command
завершается. Я знаю, что в минибуфере есть сообщение о состоянии завершения подпроцесса, но если я печатаю в то время, это часто трудно заметить.
Кроме того, я мог бы дождаться завершения команды оболочки, а затем немедленно изменить цвет. Однако это приводит к зависанию emacs во время компиляции, что нежелательно.
Как бы я применил это указание в конце компиляции, не останавливая emacs во время процесса?
4 ответа
Вот еще один вариант использования set-process-sentinel
на основе предварительного полезного ответа Francesco
, Пожалуйста, будьте осторожны при использовании let
привязка, чтобы определить start-process
(что [по моему мнению, является определенным "нет, нет"), потому что это приведет к тому, что процесс начнется непосредственно перед его временем. [FYI: Nicolas
избавил меня от многих пробок в прошлом, поэтому, пожалуйста, не забудьте внимательно рассмотреть его решение.]
Emacs: если latexmk завершает нормально, тогда показывает pdf, иначе выдает ошибки
Вы просто добавили бы свою функцию к последней части функции, касающейся успеха, т.е. (when (= 0 (process-exit-status p)) . . .
:
(defun latexmk ()
".latexmkrc contains the following entries (WITHOUT the four backslashes):
$pdflatex = 'pdflatex -file-line-error -synctex=1 %O %S && (cp \"%D\" \"%R.pdf\")';
$pdf_mode = 1;
$out_dir = '/tmp';"
(interactive)
(setq tex-file buffer-file-name)
(setq pdf-file (concat "/tmp/" (car (split-string
(file-name-nondirectory buffer-file-name) "\\.")) ".pdf"))
(setq line (format "%d" (line-number-at-pos)))
(setq skim "/Applications/Skim.app/Contents/SharedSupport/displayline")
(setq tex-output (concat "*" (file-name-nondirectory buffer-file-name) "*") )
(setq latexmk "/usr/local/texlive/2012/texmf-dist/scripts/latexmk/latexmk.pl")
(setq latexmkrc "/Users/HOME/.0.data/.0.emacs/.latexmkrc")
(if (buffer-modified-p)
(save-buffer))
(delete-other-windows)
(set-window-buffer (split-window-horizontally) (get-buffer-create tex-output))
(with-current-buffer tex-output (erase-buffer))
(set-process-sentinel
(start-process "compile" tex-output latexmk "-r" latexmkrc tex-file)
(lambda (p e) (when (= 0 (process-exit-status p))
(start-process "displayline" nil skim "-b" line pdf-file tex-file)
(switch-to-buffer (get-file-buffer tex-file))
(if (get-buffer-process (get-buffer tex-output))
(process-kill-without-query (get-buffer-process (get-buffer tex-output))))
(kill-buffer tex-output)
(delete-other-windows)))))
Вы должны попробовать команду async-start
с https://github.com/jwiegley/emacs-async
Спасибо. Я закончил тем, что получил его, используя модифицированную версию кода Lawlist. Теперь это меняет цвет при начале компиляции, затем снова меняет его, чтобы указать на успех или неудачу.
;Automatically compile any latex documents when saved.
(defun auto-compile-latex ()
(setq mode-name (propertize mode-name 'face 'font-lock-string-face))
(set-process-sentinel
(start-process-shell-command "latex-compile" "latex-compile"
(format "cd %s; scons -u" default-directory))
'latex-compile-sentinel))
;Change the color after compilation. Still need to find the right hook to add it to.
(defun latex-compile-sentinel (process event)
(if (string-equal event "finished\n")
(setq mode-name (propertize mode-name 'face 'mode-line-highlight))
(setq mode-name (propertize mode-name 'face 'font-lock-warning-face))))
;Hooks for latex-mode
(add-hook 'LaTeX-mode-hook '(lambda ()
(add-hook 'after-save-hook 'auto-compile-latex nil 'make-it-local)))
Кроме того, пакет emacs-async не работал для этого использования. Я предполагаю, что это связано с тем, что emacs-async запускает вторичные функции в отдельном процессе, а некоторые переменные не передаются обратно в родительский процесс.
Вы также можете организовать auto-compile-latex
бежать compile
,