abo-abo / ace-window

Quickly switch windows in Emacs
979 stars 87 forks source link

integrate with which-key? #91

Closed gongzhitaao closed 5 years ago

gongzhitaao commented 7 years ago

When I'm using the ace dispatch key, I sometimes forget which next key to use, I think it is convenient to show the available dispatch key. And emacs-which-key is a good candidate to consider.

abo-abo commented 7 years ago

Would be cool, but I have no idea how to do this.

blaenk commented 7 years ago

Yeah I came looking for this as well. I just noticed that ace window lets you do these things which is awesome, but it's easy to forget what each key does (even if you define them yourself in the alist) especially because a lot of times the key associated with an action isn't a key you would expect, to avoid clashing with the keys used to select a window (e.g. can't use "s" for swap, which is understandable).

I'm not very familiar with which-key's internals but I know it primarily works around keymaps, which this functionality doesn't use afaik (it manually reads a character and dispatches based on the alist). I see two options. One is to somehow use a keymap instead of the manual read-char dispatching, that would make which-key automatically work. Otherwise it'd entail looking at which-key internals to see if there are functions that can be used for displaying the popup directly (perhaps some function that is given an alist and presents that information in the popup).

blaenk commented 7 years ago

Even just manually displaying what each key does in the minibuffer would be very useful IMO, e.g.

v: vsplit, m: move, x: delete, etc.

The description is already stored in the alist, and we can manually edit it to be short and simple. I don't know if that description is currently being used anywhere already.

blaenk commented 7 years ago

There's also magit-popup.el as an option. It's a general library (doesn't require magit, despite the name) for showing popups. It might be very nice for this, as it handles reading and dispatching and all of that.

Docs: https://magit.vc/manual/magit-popup/ Source: https://github.com/magit/magit/blob/master/lisp/magit-popup.el

blaenk commented 7 years ago

If ace-window switched to using a transient-map instead of manually reading keys, which-key has an option to enable it to work with transient maps, so it would be automatic. I haven't looked too deeply into ace-window's internals though, so maybe there's a reason it's not already using a transient map.

abo-abo commented 7 years ago

so maybe there's a reason it's not already using a transient map.

Things become convoluted once maps come into play. The very existence of avy is due to ace-jump-mode relying on transient maps and having convoluted code as a result.

We could get a hint by passing a prompt arg to read-key:

(defun avy-read (tree display-fn cleanup-fn)
  "Select a leaf from TREE using consecutive `read-char'.

DISPLAY-FN should take CHAR and LEAF and signify that LEAFs
associated with CHAR will be selected if CHAR is pressed.  This is
commonly done by adding a CHAR overlay at LEAF position.

CLEANUP-FN should take no arguments and remove the effects of
multiple DISPLAY-FN invokations."
  (catch 'done
    (setq avy-current-path "")
    (while tree
      (let ((avy--leafs nil))
        (avy-traverse tree
                      (lambda (path leaf)
                        (push (cons path leaf) avy--leafs)))
        (dolist (x avy--leafs)
          (funcall display-fn (car x) (cdr x))))
      (let ((char (funcall avy-translate-char-function
                           (read-key
                            (format "avy(%s): "
                                    (mapconcat (lambda (x) (string (car x)))
                                               avy-dispatch-alist
                                               "")))))
            branch)
        (funcall cleanup-fn)
        (if (setq branch (assoc char tree))
            (if (eq (car (setq tree (cdr branch))) 'leaf)
                (throw 'done (cdr tree))
              (setq avy-current-path
                    (concat avy-current-path (string (avy--key-to-char char)))))
          (funcall avy-handler-function char))))))

Can you test if the above works for you?

blaenk commented 7 years ago

Insofar as it shows a prompt, yup! It's not very helpful at the moment though, but I figure you know that. I just see avy(xXtmnyi):.

blaenk commented 7 years ago

I guess making it longer would be too cluttered for a read prompt, so it's better than nothing.

EDIT: Then again, this unlike other prompts, can be longer than usual prompts since all it's reading in is one key, so it's not like it'd be taking space away from the input.

Any chance of making the prompt that shows up customizable?

abo-abo commented 7 years ago

Any chance of making the prompt that shows up customizable?

I can add this later.

rswgnu commented 5 years ago

Typing ‘?’ Shows you available commands with descriptions, so although this display is not automatic like which-key, it does the job very well. Isn’t that sufficient to close this issue?

abo-abo commented 5 years ago

@rswgnu Thanks for the comment. ? now works the same in avy as well, so I think this can be closed.