abo-abo / avy

Jump to things in Emacs tree-style
1.72k stars 110 forks source link

Is it possible to quit avy-goto-char-timer with Esc (C-[) ? #249

Closed BooAA closed 4 years ago

BooAA commented 6 years ago

In avy-goto-char-timer, typing Esc or C-[ will be read as string " ^[ " , and then avy will search for "^[", which is very useless since it will always get zero candidates. I want to let Esc has other functionality like quitting search as C-g or maybe ending input immediately like RET. How can I implement this?

abo-abo commented 6 years ago

Should work now, thanks.

BooAA commented 6 years ago

I think maybe we can add this kind of feature to other avy command? I use avy-goto-char-2 a lot, sometimes I'll make a typo when inputting the first character, maybe we can bind backspace to restart the command(e.g. pressing backspace will restart avy-goto-char-2 when avy is waiting for the second char to be inputted), and bind C-[ to totally quit avy command like C-g (many evil-user used to press C-[ to quit)

BooAA commented 5 years ago

I make a simple change to avy-goto-char-2,C-[ for quit,and C-h for restart avy-goto-char-2 when waiting for second character to be inputted, do you think this idea will be useful or it's not worth doing it?

(defun avy-goto-char-2 (char1 char2 &optional arg beg end)
  "Jump to the currently visible CHAR1 followed by CHAR2.
The window scope is determined by `avy-all-windows'.
When ARG is non-nil, do the opposite of `avy-all-windows'.
BEG and END narrow the scope where candidates are searched."
  (interactive (list (let ((c1 (read-char "char 1: " t)))
                       (cond ((= c1 27)
                              (keyboard-quit))
                             ((= c1 8)
                              (keyboard-quit))
                             (t c1)))
                     (let ((c2 (read-char "char 2: " t)))
                       (cond ((= c2 27)
                              (keyboard-quit))
                             ((= c2 8)
                              (keyboard-escape-quit)
                              (call-interactively 'avy-goto-char-2))
                             (t c2)))
                     current-prefix-arg
                     nil nil))
  (when (eq char1 ?)
    (setq char1 ?\n))
  (when (eq char2 ?)
    (setq char2 ?\n))
  (avy-with avy-goto-char-2
    (avy--generic-jump
     (regexp-quote (string char1 char2))
     arg
     avy-style
     beg end)))
abo-abo commented 5 years ago

It's a good change, I think. But it needs to be made more generic. To make it more customizable and reduce code duplication.

amosbird commented 4 years ago

Hmm, can we also have <escape> key to quit? With this branch

          ((eq char 'escape)
           (throw 'done 'abort))
abo-abo commented 4 years ago

@BooAA I've made the change you proposed. Sorry for the delay. @amosbird Please clarify, doesn't <escape> already quit?

amosbird commented 4 years ago

@abo-abo It doesn't. I have defined "\033" to (kbd "<escape>") in key-translation-map. The received char is the 'escape symbol

abo-abo commented 4 years ago

You mean read-char produces a symbol and not a char for you?

amosbird commented 4 years ago

I'm not sure how read-char should work but when edebugging this function

(defun avy-handler-default (char)
  "The default handler for a bad CHAR."
  (let (dispatch)
    (cond ((setq dispatch (assoc char avy-dispatch-alist))
           (unless (eq avy-style 'words)
             (setq avy-action (cdr dispatch)))
           (throw 'done 'restart))
          ((memq char '(?\e ?\C-g))
           ;; exit silently
           (throw 'done 'abort))
          ((eq char ??)
           (avy-show-dispatch-help)
           (throw 'done 'restart))
          ((mouse-event-p char)
           (signal 'user-error (list "Mouse event not handled" char)))
          (t
           (message "No such candidate: %s, hit `C-g' to quit."
                    (if (characterp char) (string char) char))))))

I can see that the char argument is a symbol escape. I have to add another branch ((eq char 'escape) (throw 'done 'abort))

abo-abo commented 4 years ago

I have defined "\033" to (kbd "<escape>") in key-translation-map

@amosbird Please show the code for this.

amosbird commented 4 years ago

@abo-abo In terminal emacs, (define-key key-translation-map "\033" (kbd "<escape>"))

abo-abo commented 4 years ago

@amosbird I tried your code, but Emacs became nearly unusable: the meta key no longer works. What's key does "\033" translate to?

Anyway, you can now customize avy-escape-chars.

amosbird commented 4 years ago

What's key does "\033" translate to?

I don't know how it works either... Thanks for the commit. I'll give it a try.