1

I'm trying to make use of the fzf fuzzy finder to search through a list via a term process. The way I do this is very similar to fuzzy-finder.el or fzf.el. This is by launching fzf with:

(progn
  (advice-add 'term-handle-exit :after #'after-term-handle-exit)
  (switch-to-buffer
   (make-term "*fzf*" shell-file-name nil shell-command-switch
          "fzf"))
  (term-char-mode))

This allows the user to type normally as if they were working with the fzf process directly. When the process exits, the selected value is parsed using the term-exit-handler by looking for the first line in the buffer beginning with " >":

(defun after-term-handle-exit (proc-name msg)
  (let* ((lines (split-string (buffer-string) "\n"))
     (selects (-filter (lambda (s) (string-match-p "\s*>\s+" s)) lines))
     (choice (string-trim-left (car selects) "\s*>\s+")))
    (setq fzf-result choice)))

This all works fine and sets the variable fzf-result just fine but what I would like to do is make the progn wait for the process to finish and then return the result. Normally I think this would be fine because I could just spin until fzf-result is non-nil but in this case fzf needs input from the user (via emacs) and so such a method just results in a freeze.

I know I could use a callback but I want to avoid this if at all possible. I was wondering if there is a way this could be achieved with threads? Or by explicitly passing keyboard inputs to the process?

Thanks for any advice

Muihlinn
  • 2,576
  • 1
  • 14
  • 22
MHilton
  • 131
  • 5

1 Answers1

2

I think I have found a solution, although It's quite hacky. Basically, I use the following loop to pass key presses to the fzf process:

(while (null fzf-result)
  (command-execute (read-key-sequence nil)))

In the term exit handle I then set this variable, fzf-result, kill the buffer, and add one last key to the unread command events (this is to finally get it out of the loop):

(setq fzf-result choice)
(kill-buffer)
(setq unread-command-events (listify-key-sequence "\n"))

I can then return fzf-result as I like. Remembering to set it back to nil.

MHilton
  • 131
  • 5