abo-abo / swiper

Ivy - a generic completion frontend for Emacs, Swiper - isearch with an overview, and more. Oh, man!
https://oremacs.com/swiper/
2.31k stars 338 forks source link

ivy-dispatching-done is not showing the actions menu anymore #2397

Closed iris-garcia closed 4 years ago

iris-garcia commented 4 years ago

I have just updated Emacs to the 27 version and hitting M-o is not showing the list of actions anymore.

iris-garcia commented 4 years ago

The issue is with Emacs 27, with Emacs 26 works as expected

seagle0128 commented 4 years ago

Same issue here, with 27 and 28. Why was it closed?

seagle0128 commented 4 years ago

Update: use hydra instead.

(setq ivy-read-action-function 'ivy-hydra-read-action)

aancel commented 4 years ago

I also have the same issue with emacs 28

iris-garcia commented 4 years ago

Then let's reopen the issue, I thought it was a problem with my settings.

mohkale commented 4 years ago

Here too, moved from 26.1 to 26.3. The actions menu is working for some functions, but for others it's not. eg: (ivy-read "hello: " (list "a" "b" "c" "d" "e")) doesn't show the actions menu, but (counsel-find-file) does.

Update:

running with emacs -q, it doesn't seem to work for any of the functions. How odd.

mohkale commented 4 years ago

Not sure whether it's directly related, but I found a bug in ivy-read-action-by-key introduced by 32019df7e0f5ba785051519b26173a0a3f895f49.

The result of key-description is a string, of the sort you'd pass to kbd (eg. "C-g" or "ESC"), but it's being compared against literal escape codes such as ^[ or ^G meaning those conditions are never true, meaning you can't exit a dispatch session with "C-g".

Simply changing ^[ and ^G should be sufficient.

NOTE: This won't fix issues with the dispatch menu not being visible.

mohkale commented 4 years ago

I think this issue has something to do with the number of actions, or more specifically the number of lines to be displayed in the minibuffer.

You can experiment with the following:

(defun ivy-read-action-by-key+ (actions)
  (let* ((hint (funcall ivy-read-action-format-function (cdr actions)))
         (resize-mini-windows t)
         (key "")
         action-idx)
    (read-key hint)
    nil))
(setq ivy-read-action-function 'ivy-read-action-by-key+)

this is a barebones version of ivy-read-action-by-key which simply prompts for the key and then exits as if you pressed C-g.

If I progressively change the value of (read-key hint) to (read-key "value\n"), (read-key "value\n\n"), ..., (read-key "value\n\n\n\n\n\n\n\n\n\n\n\n\n\n") I find that once the number of lines to be read reaches one less than the height of the ivy session we were just running, that the actions of the dispatch menu are shown.

eg. For example in counsel-find-file. if I navigate to a folder with 9 files, ivy shows a window with 9 files + . + .. + the prompt, which is 12 lines. If I make ivy-read-action-by-key+ output a string with 11 lines, the dispatch menu is shown. If I make it output one with 10 lines, it's hidden. You get the idea. I ask someone else to please replicate this to prove it's not simply an issue on my machine.

I think it's safe to say at this point the issue is with the resize-mini-windows assignment in ivy-read-action-by-key. Running emacs -q on a new definition after evaluating the following, does fix the issue for me:

(setq ivy-read-action-function
      (defun ivy-read-action-by-key+ (actions)
        (let* ((hint (funcall ivy-read-action-format-function (cdr actions)))
               ;; (resize-mini-windows t)
               (key "")
               action-idx)
          (while (and (setq action-idx (cl-position-if
                                        (lambda (x)
                                          (string-prefix-p key (car x)))
                                        (cdr actions)))
                      (not (string= key (car (nth action-idx (cdr actions))))))
            (setq key (concat key (key-description (string (read-key hint))))))
          (ivy-shrink-after-dispatching)
          (cond ((member key '("ESC" "C-g"))
                 nil)
                ((null action-idx)
                 (message "%s is not bound" key)
                 nil)
                (t
                 (message "")
                 (setcar actions (1+ action-idx))
                 (ivy-set-action actions))))))

NOTE: this is the exact same function, but with resize-mini-windows left with it's default value of 'grow-only.

I can only surmise somewhere between emacs 26.1 some modifications were made to something relating to the resize-mini-windows variable which is causing this issue.

Having run:

> git clone https://git.savannah.gnu.org/git/emacs.git
> git diff emacs-26.1  -- ./src/xdisp.c

I do notice some changes relating to resize-mini-windows has taken place. If someone can replicate my findings and (dumb) solution, you should make a bug request to emacs (I have no idea how to 😢) and downgrade to an earlier emacs version in the meantime, or follow @seagle0128 's advice and use one of the alternative read actions.

seagle0128 commented 4 years ago

It works for me in the latest version.

mohkale commented 4 years ago

Sorry @seagle0128 do you mean the default ivy-read-action-by-key works for you. Could you specify the version (and/or commit) of the emacs your using.

abo-abo commented 4 years ago

Thanks, please test.

mohkale commented 4 years ago

@abo-abo yep, seems to be working again. Didn't realise ivy had special behaviour for resizing the minibuffer 😅. Thnx for the stellar work.

mohkale commented 4 years ago

@abo-abo There's still the issue regarding ivy-read-action-by-key not letting you cancel the dispatch with C-g or ESC. I mentioned it in an earlier comment.

DamienCassou commented 4 years ago

The bug isn't solved for me. How to reproduce:

  1. Use Emacs 27 c134978a769a27c10de4a1c3d28c073f3de87a3c
  2. Use Swiper 47bd7b16ac7b1f95ffc808ea1dd159eb95d03056
  3. Activate counsel mode
  4. C-x C-f for counsel-find-file
  5. Highlight a file
  6. Press M-o

Expected: A list of actions Actual: The minibuffer shows "( 1/1 ) Find file: /tmp/htm"

CSRaghunandan commented 4 years ago

I'm still facing this issue on the latest version of ivy on emacs 28.0.50

abo-abo commented 4 years ago
1. Use Emacs 27 c134978a769a27c10de4a1c3d28c073f3de87a3c

Thanks. I confirm that the bug persists. I think this is due to a regression in Emacs where the hint of the call to read-key is not being displayed.

I suggest changing ivy-read-action-function to either ivy-read-action-ivy or ivy-read-action-hydra.

DamienCassou commented 4 years ago

Oleh Krehel notifications@github.com writes:

I suggest changing ivy-read-action-function to either ivy-read-action-ivy

this fixes the issue for me. Thank you.

-- Damien Cassou

"Success is the ability to go from one failure to another without losing enthusiasm." --Winston Churchill

ashiklom commented 4 years ago

(setq ivy-read-action-function #'ivy-hydra-read-action) worked for me!

(Note: ivy-hydra-read-action, not ivy-read-action-hydra).

abo-abo commented 4 years ago

There is now a bug report to core Emacs about this issue: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=39564.

Please contribute to the discussion there to fix this bug so that it doesn't make it to a stable Emacs-27 release.

mjkramer commented 4 years ago

I was able to restore the old behavior of ivy-dispatching-done by binding set-message-function to nil in the let* form at the top of ivy-read-action-by-key. See this Emacs commit from Dec 22.

(Mistakenly posted to the wrong issue earlier)

abo-abo commented 4 years ago

@mjkramer Thanks! Should be fixed now. Please test.

mjkramer commented 4 years ago

It's mostly working on 27 now, but it looks like, even when resize-mini-windows is bound to t, max-mini-window-height is being obeyed no matter what, which can prevent the full list of actions from showing up on smaller frames. Solution might be to bind max-mini-window-height to 1 within the scope of ivy-read-action-by-key. I'll try to play around with it a bit further when I have a chance.