reddit / emacs

Change buffer before async call returns its result

MonsieurPi · 2022-08-01 10:10
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: ```elisp (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: ```elisp (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.
00-11 · 2022-08-01 16:55
https://stackoverflow.com/q/73186564/729907
MonsieurPi · 2022-08-01 16:56
Yep, I cross-posted ;-)