0

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.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.