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

1 Answer 1

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.

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.

Not the answer you're looking for? Browse other questions tagged or ask your own question.