branch: master commit 00f08f74f1568b6f835abadecff32cd7c9a7a556 Author: Oleh Krehel <ohwoeo...@gmail.com> Commit: Oleh Krehel <ohwoeo...@gmail.com>
Improve Ivy documentation UI * ivy.el (ivy-minibuffer-map): Bind "C-h m" to `ivy-help'. (ivy-help-file): New defvar, pointing to the ivy-help.org file. (ivy-help): New command. * ivy-hydra.el (hydra-ivy): Update the layout, give the columns more meaningful names, bind "D" to go to this hydra's definition. * doc/ivy.org: Fix a few typos. * doc/ivy-help.org: New file. Fixes #376 --- doc/ivy-help.org | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/ivy.org | 14 +++--- ivy-hydra.el | 15 +++--- ivy.el | 24 ++++++++++ swiper.el | 22 ++++----- 5 files changed, 188 insertions(+), 25 deletions(-) diff --git a/doc/ivy-help.org b/doc/ivy-help.org new file mode 100644 index 0000000..989c0e4 --- /dev/null +++ b/doc/ivy-help.org @@ -0,0 +1,138 @@ +* Ivy Generic Help + +=ivy= is an Emacs incremental completion framework. + +- Narrow the list by typing some pattern, +- Multiple patterns are allowed by separating with a space, +- Select with ~C-n~ and ~C-p~, choose with ~RET~. + +** Help + +- ~C-h m~ :: Pop to this generic help buffer. + +** Basic Operations +*** Key bindings for navigation + +- ~C-n~ (=ivy-next-line=) :: next candidate. +- ~C-p~ (=ivy-previous-line=) :: previous candidate. +- ~C-v~ (=ivy-scroll-up-command=) :: next page. +- ~M-v~ (=ivy-scroll-down-command=) :: previous page. +- ~M-<~ (=ivy-beginning-of-buffer=) :: first candidate. +- ~M->~ (=ivy-end-of-buffer=) :: last candidate. + +*** Key bindings for single selection + +When selecting a candidate, an action is called on it. You can think +of an action as a function that takes the selected candidate as an +argument and does something with it. + +Ivy can offer several actions from which to choose. This can be +independently composed with whether you want to end completion when +the action is called. Depending on this, the short term is either +"calling an action" or "exiting with action". + +~C-m~ or ~RET~ (=ivy-done=) - exit with the current action. + +~M-o~ (=ivy-dispatching-done=) - select an action and exit with it. + +~C-j~ (=ivy-alt-done=) - when the candidate is a directory, enter +it. Otherwise, exit with the current action. + +~TAB~ (=ivy-partial-or-done=) - attempt partial completion, extending +the current input as much as possible. ~TAB TAB~ is the same as ~C-j~. + +~C-M-j~ (=ivy-immediate-done=) - exit with the current action, calling +it on the /current input/ instead of the current candidate. This is +useful especially when creating new files or directories - often the +input will match an existing file, which you don't want to select. + +~C-'~ (=ivy-avy=) - select a candidate from the current page with avy +and exit with the current action. + +** Advanced Operations +*** Key bindings for multiple selection + +For repeatedly applying multiple actions or acting on multiple +candidates, Ivy does not close the minibuffer between commands. It +keeps the minibuffer open for applying subsequent actions. + +Adding an extra meta key to the normal key chord invokes the special +version of the regular commands that enables applying multiple +actions. + +~C-M-m~ (=ivy-call=) is the non-exiting version of ~C-m~ (=ivy-done=). + +~C-M-n~ (=ivy-next-line-and-call=) combines ~C-n~ and ~C-M-m~. + +~C-M-p~ (=ivy-previous-line-and-call=) combines ~C-p~ and ~C-M-m~. + +~C-M-o~ (=ivy-dispatching-call=) is a non-exiting version of ~M-o~ +(=ivy-dispatching-done=). + +*** Key bindings that alter the minibuffer input + +~M-n~ (=ivy-next-history-element=) select the next history element or +symbol/URL at point. + +~M-p~ (=ivy-previous-history-element=) select the previous history +element. + +~C-r~ (=ivy-reverse-i-search=) start a recursive completion session to +select a history element. + +~M-i~ (=ivy-insert-current=) insert the current candidate into the +minibuffer. Useful for copying and renaming files, for example: ~M-i~ +to insert the original file name string, edit it, and then ~C-m~ to +complete the renaming. + +~M-j~ (=ivy-yank-word=) insert the sub-word at point into the +minibuffer. + +~S-SPC~ (=ivy-restrict-to-matches=) deletes the current input, and +resets the candidates list to the currently restricted matches. This +is how Ivy provides narrowing in successive tiers. + +*** Other key bindings + +~M-w~ (=ivy-kill-ring-save=) copies the selected candidates to the +kill ring; when the region is active, copies the active region. + +*** Saving the current completion session to a buffer + +~C-c C-o~ (=ivy-occur=) saves the current candidates to a new buffer; +the list is active in the new buffer. + +~RET~ or ~mouse-1~ in the new buffer calls the appropriate action on +the selected candidate. + +Ivy has no limit on the number of active buffers like these. + +Ivy takes care of making these buffer names unique. It applies +descriptive names, for example: =*ivy-occur counsel-describe-variable +"function$*=. + +*** Global key bindings + +=ivy-resume= recalls the state of the completion session just before +its last exit. Useful after an accidental ~C-m~ (=ivy-done=). +Recommended global binding: ~C-c C-r~. + +*** Hydra in the minibuffer + +~C-o~ (=hydra-ivy/body=) invokes Hydra menus with key shortcuts. + +When in Hydra, ~C-o~ or ~i~ resumes editing. + +Hydra reduces key strokes, for example: ~C-n C-n C-n C-n~ is ~C-o +jjjj~ in Hydra. Besides certain shorter keys, Hydra shows useful info +such as case folding and the current action. + +Additionally, here are the keys that are otherwise not bound: + +- ~<~ and ~>~ adjust the height of the minibuffer. +- ~c~ (=ivy-toggle-calling=) - toggle calling the current action each + time a different candidate is selected. +- ~m~ (=ivy-toggle-fuzzy=) - toggle regex matcher. +- ~w~ and ~s~ scroll the actions list. + +Minibuffer editing is disabled when Hydra is active. diff --git a/doc/ivy.org b/doc/ivy.org index b26b00e..68c045e 100644 --- a/doc/ivy.org +++ b/doc/ivy.org @@ -274,9 +274,7 @@ when applying multiple actions. Multiple actions and multiple selections as covered in the next section of this manual. ~TAB~ (=ivy-partial-or-done=) attempts partial completion, extending -current input as much as possible. - -~TAB TAB~ is the same as ~C-j~. +current input as much as possible. ~TAB TAB~ is the same as ~C-j~. ~C-M-j~ (=ivy-immediate-done=) is useful when there is no match for the given input. Or there is an incorrect partial match. ~C-M-j~ with @@ -290,7 +288,7 @@ on the /current input/. #+BEGIN_TEXINFO Invoking avy completion with @kbd{C-'} (@code{ivy-avy}). #+END_TEXINFO -~C-`~ uses avy's visible jump mechanism, which can further reduce +~C-'~ uses avy's visible jump mechanism, which can further reduce Ivy's line-by-line scrolling that requires multiple ~C-n~ or ~C-p~ keystrokes. @@ -330,7 +328,7 @@ action on each successive element of the list. the same as above except that it moves through the list in the other direction. -*** Key bindings that alter minibuffer input +*** Key bindings that alter the minibuffer input ~M-n~ (=ivy-next-history-element=) and ~M-p~ (=ivy-previous-history-element=) cycle through the Ivy command @@ -343,9 +341,9 @@ minibuffer. Useful for copying and renaming files, for example: ~M-i~ to insert the original file name string, edit it, and then ~C-m~ to complete the renaming. -~M-j~ (=ivy-yank-word=) inserts sub-word at point into minibuffer. This -is similar to ~C-s C-w~ with =isearch=. Ivy reserves ~C-w~ for -=kill-region=. +~M-j~ (=ivy-yank-word=) inserts the sub-word at point into the +minibuffer. This is similar to ~C-s C-w~ with =isearch=. Ivy reserves +~C-w~ for =kill-region=. ~S-SPC~ (=ivy-restrict-to-matches=) deletes the current input, and resets the candidates list to the currently restricted matches. This diff --git a/ivy-hydra.el b/ivy-hydra.el index 63755da..44f8754 100644 --- a/ivy-hydra.el +++ b/ivy-hydra.el @@ -53,11 +53,11 @@ (defhydra hydra-ivy (:hint nil :color pink) " -^^^^^^ ^Yes^ ^^ ^No^ ^Maybe^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^Action^ ^ -^^^^^^^^^^^^^^^----------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------- -^ ^ _k_ ^ ^ _f_ollow occ_u_r _i_nsert _c_: calling %-5s(if ivy-calling \"on\" \"off\") _w_/_s_/_a_: %-14s(ivy-action-name) -_h_ ^+^ _l_ _d_one ^ ^ _o_ops _m_: matcher %-5s(ivy--matcher-desc)^^^^^^^^^^^^ _C_ase-fold: %-10`ivy-case-fold-search -^ ^ _j_ ^ ^ _g_o ^ ^ ^ ^ _<_/_>_: shrink/grow^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _t_runcate: %-11`truncate-lines +^ ^ ^ ^ ^ ^ | ^Call^ ^ ^ | ^Cancel^ | ^Options^ | Action _w_/_s_/_a_: %-14s(ivy-action-name) +^-^-^-^-^-^-+-^-^---------^-^--+-^-^------+-^-^-------+-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------- +^ ^ _k_ ^ ^ | _f_ollow occ_u_r | _i_nsert | _c_: calling %-5s(if ivy-calling \"on\" \"off\") _C_ase-fold: %-10`ivy-case-fold-search +_h_ ^+^ _l_ | _d_one ^ ^ | _o_ops | _m_: matcher %-5s(ivy--matcher-desc)^^^^^^^^^^^^ _t_runcate: %-11`truncate-lines +^ ^ _j_ ^ ^ | _g_o ^ ^ | ^ ^ | _<_/_>_: shrink/grow^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _D_efinition of this menu " ;; arrows ("h" ivy-beginning-of-buffer) @@ -83,7 +83,10 @@ _h_ ^+^ _l_ _d_one ^ ^ _o_ops _m_: matcher %-5s(ivy--matcher-desc)^^ ("a" ivy-read-action) ("t" (setq truncate-lines (not truncate-lines))) ("C" ivy-toggle-case-fold) - ("u" ivy-occur :exit t)) + ("u" ivy-occur :exit t) + ("D" (ivy-exit-with-action + (lambda (_) (find-function 'hydra-ivy/body))) + :exit t)) (provide 'ivy-hydra) diff --git a/ivy.el b/ivy.el index 887d50c..82e5d37 100644 --- a/ivy.el +++ b/ivy.el @@ -236,6 +236,7 @@ Example: (define-key map (kbd "C-'") 'ivy-avy) (define-key map (kbd "C-M-a") 'ivy-read-action) (define-key map (kbd "C-c C-o") 'ivy-occur) + (define-key map (kbd "C-h m") 'ivy-help) map) "Keymap used in the minibuffer.") (autoload 'hydra-ivy/body "ivy-hydra" "" t) @@ -2716,6 +2717,29 @@ EVENT gives the mouse position." (run-at-time 0.5 nil 'swiper--cleanup)) (pulse-momentary-highlight-one-line (point))))))) +(defvar ivy-help-file (expand-file-name + "doc/ivy-help.org" + (file-name-directory load-file-name)) + "The file for `ivy-help'.") + +(defun ivy-help () + "Help for `ivy'." + (interactive) + (let ((buf (get-buffer "*Ivy Help*"))) + (unless buf + (setq buf (get-buffer-create "*Ivy Help*")) + (with-current-buffer buf + (insert-file-contents ivy-help-file) + (org-mode) + (view-mode) + (goto-char (point-min)))) + (if (eq this-command 'ivy-help) + (switch-to-buffer buf) + (with-ivy-window + (pop-to-buffer buf))) + (view-mode) + (goto-char (point-min)))) + (provide 'ivy) ;;; ivy.el ends here diff --git a/swiper.el b/swiper.el index c5c4a1f..7f8d255 100644 --- a/swiper.el +++ b/swiper.el @@ -153,17 +153,17 @@ (forward-line)) cands))))) (candidate (unwind-protect - (prog2 - (avy--make-backgrounds - (append (avy-window-list) - (list (ivy-state-window ivy-last)))) - (if (eq avy-style 'de-bruijn) - (avy-read-de-bruijn - candidates avy-keys) - (avy-read (avy-tree candidates avy-keys) - #'avy--overlay-post - #'avy--remove-leading-chars)) - (avy-push-mark)) + (prog2 + (avy--make-backgrounds + (append (avy-window-list) + (list (ivy-state-window ivy-last)))) + (if (eq avy-style 'de-bruijn) + (avy-read-de-bruijn + candidates avy-keys) + (avy-read (avy-tree candidates avy-keys) + #'avy--overlay-post + #'avy--remove-leading-chars)) + (avy-push-mark)) (avy--done)))) (if (window-minibuffer-p (cdr candidate)) (progn