abo-abo / avy

Jump to things in Emacs tree-style
1.71k stars 109 forks source link

avy-isearch returns nil regardless of a C-g quit #281

Closed cyberthal closed 4 years ago

cyberthal commented 5 years ago

Avy commands such as avy-isearch do not indicate that the user quit with C-g. This makes it difficult for other elisp authors who use avy functions in their code to distinguish between a user selecting the current location and the user quitting. In the latter case, the program should respond to the user's desire to abort.

I made a workaround to detect a quit within avy-isearch:

#+begin_src elisp
  ;; Run Avy if multiple isearch matches.
  ;; Avy doesn't signal a quit, so it is inferred from point.
  (let ((avy-all-windows nil)
        (avy-case-fold-search nil))
    (unless (eq 1 (length (avy--regex-candidates (regexp-quote isearch-string))))
      (goto-char (point-min))
      (avy-isearch)
      (if (eq (point) (point-min))
          (user-error "Quit Avy"))))
#+end_src
abo-abo commented 4 years ago

Thanks, please test.

cyberthal commented 4 years ago

I don't understand what you mean. I am using the code block successfully for personal use, and plan to submit it as part of a MELPA package within a month.

abo-abo commented 4 years ago

I meant that this code now works:

(let ((avy-all-windows nil)
      (avy-case-fold-search nil)
      (isearch-string "avy"))
  (unless (eq 1 (length (avy--regex-candidates (regexp-quote isearch-string))))
    (goto-char (point-min))
    (let ((res (avy-isearch)))
      (message "res: %S" res))))

In case there's a C-g, res will be nil.

cyberthal commented 4 years ago

(avy-isearch) always returned nil before, so it was impossible to tell whether the nil was the result of a C-g or not. It still does the same thing, in my test. Call (avy-isearch) with eval-expression and it will return "nil" to the minibuffer.

abo-abo commented 4 years ago

But now, when you don't press C-g, res will store the point position. So you can detect C-g.

cyberthal commented 4 years ago

That was the first time I'd tested someone's fix of an issue I opened on their package, and I didn't do it correctly. Your fix definitely works, thanks.

Instead of always returning nil, it returns e.g. "res: (69 . 72)" for a successful invocation and "res: nil" for a C-g quit.