I have the following function that creates a new buffer and calls a compilation watcher asynchronously in it. This means that every time I save the file I'm working on the watcher will compile it and returns the result:
(defun dune-watch (exe)
"Will call dune build -w EXE on an async process."
(interactive "sBuild name: ")
(let ((buffer (get-buffer-create "Dune watch")))
(with-current-buffer buffer (compilation-minor-mode t))
(projectile-run-async-shell-command-in-root (concat "dune build -w " exe) buffer)
;; Make this process non blocking for killing
(set-process-query-on-exit-flag (get-buffer-process buffer) nil)
(display-buffer buffer '((display-buffer-below-selected display-buffer-at-bottom)
(inhibit-same-window . t)
(window-height . 0.2)))))
A normal run will look like this (lines preceded by #
were added by me):
Success, waiting for filesystem changes...
# save file
********** NEW BUILD (src/ident.ml changed) **********
File "src/ident.ml", line 46, characters 46-48:
46 | let compare t1 t2 = String.compare t1.name t2.na
^^
Error: Unbound record field na
Had errors, waiting for filesystem changes...
# save file
********** NEW BUILD (src/ident.ml changed) **********
Success, waiting for filesystem changes...
Now, this doesn't suit me really well because it messes up with the compilation buffer regexp alist so I tried erasing the buffer any time I save a file:
(defun erase-and-fill-buffer (buffer)
"Blahblah BUFFER."
(with-current-buffer buffer
(erase-buffer)
(insert "Dune watch buffer")
))
(defun dune-watch (exe)
"Will call dune build -w EXE on an async process."
(interactive "sBuild name: ")
(let ((buffer (get-buffer-create "Dune watch")))
(add-hook 'before-save-hook (lambda () (erase-and-fill-buffer buffer)))
(with-current-buffer buffer (compilation-minor-mode t))
(projectile-run-async-shell-command-in-root (concat "dune build -w " exe) buffer)
;; Make this process non blocking for killing
(set-process-query-on-exit-flag (get-buffer-process buffer) nil)
(display-buffer buffer '((display-buffer-below-selected display-buffer-at-bottom)
(inhibit-same-window . t)
(window-height . 0.2)))))
But to my surprise, this doesn't work. Remember that dune build -w
is only executed when a file is saved and I'm hooking to before-save-hook
. Here's the whole content of the buffer:
- after first save:
Success, waiting for filesystem changes... Dune watch buffer
- after second save
********** NEW BUILD (src/ident.ml changed) ********** File "src/ident.ml", line 46, characters 46-47: 46 | let compare t1 t2 = String.compare t1.name t2.n ^ Error: Unbound record field n Had errors, waiting for filesystem changes... Dune watch buffer
My insert comes after the asynchronous call even though this call should have happened after the file was saved. I tried to output the result of the asynchronous call in another buffer but I encounter the same problem since I don't know how to copy only the last displayed message and not the whole buffer without erasing it.