merge: pull request #7739 from LemonBreezes/corfu-update-smart-tab
feat(corfu): update smart tab completion
This commit is contained in:
commit
3cb9f17132
4 changed files with 176 additions and 62 deletions
|
@ -202,6 +202,15 @@ A few variables may be set to change behavior of this module:
|
|||
- [[var:+corfu-want-minibuffer-completion]] ::
|
||||
Whether to enable Corfu in the minibuffer. See its documentation for
|
||||
additional tweaks.
|
||||
- [[var:+corfu-want-tab-prefer-expand-snippets]] ::
|
||||
Whether to prefer expanding snippets over cycling candidates when pressing
|
||||
[[kbd:][TAB]].
|
||||
- [[var:+corfu-want-tab-prefer-navigating-snippets]] ::
|
||||
Whether to prefer navigating snippets over cycling candidates when pressing
|
||||
[[kbd:][TAB]] and [[kbd:][S-TAB]].
|
||||
- [[var:+corfu-want-tab-prefer-navigating-org-tables]] ::
|
||||
Whether to prefer navigating org tables over cycling candidates when pressing
|
||||
[[kbd:][TAB]] and [[kbd:][S-TAB]].
|
||||
|
||||
** Turning off auto-completion
|
||||
To disable idle (as-you-type) completion, unset ~corfu-auto~:
|
||||
|
@ -241,6 +250,8 @@ all CAPFs are interactive to be called this way, in which case you can use
|
|||
* Troubleshooting
|
||||
[[doom-report:][Report an issue?]]
|
||||
|
||||
** Troubleshooting ~cape-dabbrev~
|
||||
|
||||
If you have performance issues with ~cape-dabbrev~, the first thing I recommend
|
||||
doing is to look at the list of buffers Dabbrev is scanning:
|
||||
|
||||
|
@ -268,6 +279,34 @@ debug the issue:
|
|||
(search-in-dabbrev-buffers "\342\200\231")
|
||||
#+end_src
|
||||
|
||||
** Fixing TAB Keybindings
|
||||
|
||||
If you encounter an issue where your ~TAB~ keybindings are not responding in Doom
|
||||
Emacs while the ~:editor evil~ module is active, it's likely caused by a conflict
|
||||
where ~<tab>~ keybindings and insert state bindings are overriding your ~TAB~ key
|
||||
assignments.
|
||||
|
||||
In Evil mode, keybinding priorities are set such that:
|
||||
1. ~<tab>~ keybindings supersede ~TAB~ keybindings and only work in GUI Emacs.
|
||||
2. Bindings in insert state take precedence whenever the insert state is active.
|
||||
|
||||
To resolve this conflict and to assign your desired command to the ~TAB~ key, you
|
||||
must redefine the keybindings with insert state set explicitly. You can do this
|
||||
by configuring your ~evil~ keybindings for the insert state as follows:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(map! :gi "TAB" #'your-command
|
||||
:gi "<tab>" #'your-command)
|
||||
#+end_src
|
||||
|
||||
Place this code in your Doom Emacs configuration file to set the function ~your-command~ as the response to pressing ~TAB~ during insert mode.
|
||||
|
||||
Remember to replace ~#'your-command~ with the actual command you wish to invoke
|
||||
with the ~TAB~ key.
|
||||
|
||||
If ever in a situation like this, use ~describe-key~ with ~C-h k~ and look at what
|
||||
command is being called as well as what keymaps the command is defined in.
|
||||
|
||||
* Frequently asked questions
|
||||
/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]]
|
||||
|
||||
|
|
|
@ -16,6 +16,18 @@ Possible values are:
|
|||
Setting this to `aggressive' will enable Corfu in more commands which
|
||||
use the minibuffer such as `query-replace'.")
|
||||
|
||||
(defvar +corfu-want-tab-prefer-expand-snippets nil
|
||||
"If non-nil, prefer expanding snippets over cycling candidates with
|
||||
TAB.")
|
||||
|
||||
(defvar +corfu-want-tab-prefer-navigating-snippets nil
|
||||
"If non-nil, prefer navigating snippets over cycling candidates with
|
||||
TAB/S-TAB.")
|
||||
|
||||
(defvar +corfu-want-tab-prefer-navigating-org-tables nil
|
||||
"If non-nil, prefer navigating org tables over cycling candidates with
|
||||
TAB/S-TAB.")
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
(use-package! corfu
|
||||
|
|
|
@ -38,38 +38,66 @@
|
|||
;;; Global keybindings
|
||||
|
||||
;; Smart tab, these will only work in GUI Emacs
|
||||
(map! :i [tab] (cmds! (and (modulep! :editor snippets)
|
||||
(yas-maybe-expand-abbrev-key-filter 'yas-expand))
|
||||
#'yas-expand
|
||||
(and (bound-and-true-p company-mode)
|
||||
(modulep! :completion company +tng))
|
||||
#'company-indent-or-complete-common
|
||||
(and (bound-and-true-p corfu-mode)
|
||||
(modulep! :completion corfu))
|
||||
#'completion-at-point)
|
||||
:m [tab] (cmds! (and (modulep! :editor snippets)
|
||||
(evil-visual-state-p)
|
||||
(map! :i [tab]
|
||||
`(menu-item "Evil insert smart tab" nil :filter
|
||||
(lambda (cmd)
|
||||
(cond
|
||||
((or (doom-lookup-key [tab] overriding-terminal-local-map)
|
||||
(doom-lookup-key (kbd "TAB") overriding-terminal-local-map))
|
||||
cmd)
|
||||
,@(when (modulep! :editor snippets)
|
||||
'(((+yas-active-p)
|
||||
#'yas-next-field-or-maybe-expand)
|
||||
((yas-maybe-expand-abbrev-key-filter 'yas-expand)
|
||||
#'yas-expand)))
|
||||
,@(when (modulep! :completion company +tng)
|
||||
'(((bound-and-true-p company-mode)
|
||||
#'company-indent-or-complete-common)))
|
||||
,@(when (modulep! :completion corfu)
|
||||
'(((bound-and-true-p corfu-mode)
|
||||
(if (derived-mode-p 'eshell-mode 'comint-mode)
|
||||
#'completion-at-point
|
||||
#'indent-for-tab-command)))))))
|
||||
:m [tab]
|
||||
`(menu-item "Evil motion smart tab" nil :filter
|
||||
(lambda (cmd)
|
||||
(cond
|
||||
((or (doom-lookup-key [tab] overriding-terminal-local-map)
|
||||
(doom-lookup-key (kbd "TAB") overriding-terminal-local-map))
|
||||
cmd)
|
||||
,@(when (modulep! :editor snippets)
|
||||
'(((and (evil-visual-state-p)
|
||||
(or (eq evil-visual-selection 'line)
|
||||
(not (memq (char-after) (list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
|
||||
#'yas-insert-snippet
|
||||
(and (modulep! :editor fold)
|
||||
(save-excursion (end-of-line) (invisible-p (point))))
|
||||
#'+fold/toggle
|
||||
(not (memq (char-after)
|
||||
(list ?\( ?\[ ?\{ ?\} ?\] ?\))))))
|
||||
#'yas-insert-snippet)))
|
||||
,@(when (modulep! :editor fold)
|
||||
'(((save-excursion (end-of-line) (invisible-p (point)))
|
||||
#'+fold/toggle)))
|
||||
;; Fixes #4548: without this, this tab keybind overrides
|
||||
;; mode-local ones for modes that don't have an evil
|
||||
;; keybinding scheme or users who don't have :editor (evil
|
||||
;; +everywhere) enabled.
|
||||
(or (doom-lookup-key
|
||||
((or (doom-lookup-key
|
||||
[tab]
|
||||
(list (evil-get-auxiliary-keymap (current-local-map) evil-state)
|
||||
(list (evil-get-auxiliary-keymap (current-local-map)
|
||||
evil-state)
|
||||
(current-local-map)))
|
||||
(doom-lookup-key
|
||||
(kbd "TAB")
|
||||
(list (evil-get-auxiliary-keymap (current-local-map) evil-state)))
|
||||
(list (evil-get-auxiliary-keymap (current-local-map)
|
||||
evil-state)))
|
||||
(doom-lookup-key (kbd "TAB") (list (current-local-map))))
|
||||
it
|
||||
(fboundp 'evil-jump-item)
|
||||
#'evil-jump-item)
|
||||
cmd)
|
||||
((fboundp 'evil-jump-item)
|
||||
#'evil-jump-item))))
|
||||
;; Extend smart tab for specific modes. This way, we process the entire
|
||||
;; smart tab logic and only fall back to these commands at the end.
|
||||
(:when (modulep! :lang org)
|
||||
(:after org :map org-mode-map
|
||||
[remap indent-for-tab-command]
|
||||
`(menu-item "Go to the next field" org-table-next-field
|
||||
:filter ,(lambda (cmd) (when (org-at-table-p) cmd)))))
|
||||
|
||||
(:after help :map help-mode-map
|
||||
:n "o" #'link-hint-open-link)
|
||||
|
|
|
@ -464,22 +464,19 @@ Continues comments if executed from a commented line. Consults
|
|||
[remap corfu-insert-separator] #'+corfu-smart-sep-toggle-escape
|
||||
"C-S-s" #'+corfu-move-to-minibuffer
|
||||
"C-p" #'corfu-previous
|
||||
"C-n" #'corfu-next
|
||||
"S-TAB" #'corfu-previous
|
||||
[backtab] #'corfu-previous
|
||||
"TAB" #'corfu-next
|
||||
[tab] #'corfu-next))
|
||||
"C-n" #'corfu-next))
|
||||
(let ((cmds-del
|
||||
`(menu-item "Reset completion" corfu-reset
|
||||
:filter ,(lambda (cmd)
|
||||
(when (and (>= corfu--index 0)
|
||||
(cond
|
||||
((and (>= corfu--index 0)
|
||||
(eq corfu-preview-current 'insert))
|
||||
cmd))))
|
||||
cmd)))))
|
||||
(cmds-ret
|
||||
`(menu-item "Insert completion DWIM" corfu-insert
|
||||
:filter ,(lambda (cmd)
|
||||
(interactive)
|
||||
(cond ((null +corfu-want-ret-to-confirm)
|
||||
(cond
|
||||
((null +corfu-want-ret-to-confirm)
|
||||
(corfu-quit)
|
||||
nil)
|
||||
((eq +corfu-want-ret-to-confirm 'minibuffer)
|
||||
|
@ -492,13 +489,51 @@ Continues comments if executed from a commented line. Consults
|
|||
((or (not (minibufferp nil t))
|
||||
(eq +corfu-want-ret-to-confirm t))
|
||||
nil)
|
||||
(t cmd)))))
|
||||
(cmds-tab
|
||||
`(menu-item "Select next candidate or expand/traverse snippet" corfu-next
|
||||
:filter (lambda (cmd)
|
||||
(cond
|
||||
,@(when (modulep! :editor snippets)
|
||||
'(((and +corfu-want-tab-prefer-navigating-snippets
|
||||
(memq (bound-and-true-p yas--active-field-overlay)
|
||||
(overlays-in (1- (point)) (1+ (point)))))
|
||||
#'yas-next-field-or-maybe-expand)
|
||||
((and +corfu-want-tab-prefer-expand-snippets
|
||||
(yas-maybe-expand-abbrev-key-filter 'yas-expand))
|
||||
#'yas-expand)))
|
||||
,@(when (modulep! :lang org)
|
||||
'(((and +corfu-want-tab-prefer-navigating-org-tables
|
||||
(featurep 'org)
|
||||
(org-at-table-p))
|
||||
#'org-table-next-field)))
|
||||
(t cmd)))) )
|
||||
(cmds-s-tab
|
||||
`(menu-item "Select previous candidate or expand/traverse snippet"
|
||||
corfu-previous
|
||||
:filter (lambda (cmd)
|
||||
(cond
|
||||
,@(when (modulep! :editor snippets)
|
||||
'(((and +corfu-want-tab-prefer-navigating-snippets
|
||||
(memq (bound-and-true-p yas--active-field-overlay)
|
||||
(overlays-in (1- (point)) (1+ (point)))))
|
||||
#'yas-prev-field)))
|
||||
,@(when (modulep! :lang org)
|
||||
'(((and +corfu-want-tab-prefer-navigating-org-tables
|
||||
(featurep 'org)
|
||||
(org-at-table-p))
|
||||
#'org-table-previous-field)))
|
||||
(t cmd))))))
|
||||
(map! :when (modulep! :completion corfu)
|
||||
:map corfu-map
|
||||
[backspace] cmds-del
|
||||
"DEL" cmds-del
|
||||
:gi [return] cmds-ret
|
||||
:gi "RET" cmds-ret))
|
||||
:gi "RET" cmds-ret
|
||||
"S-TAB" cmds-s-tab
|
||||
[backtab] cmds-s-tab
|
||||
:gi "TAB" cmds-tab
|
||||
:gi [tab] cmds-tab))
|
||||
|
||||
;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation.
|
||||
;; Pressing it again will send you to the true bol. Same goes for C-e, except
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue