遇到一个tab绑定的问题

最近想把tab绑定到tempel-next 在snippets的placeholder 之间跳转,但是gui下是失败的

但是我在tui上试了一下,结果成功了,就很蒙。

(after! tempel
  (use-package! tempel
    :bind (("M-y" . tempel-complete)
            :map tempel-map
            ("M-j" . tempel-next)
            ("M-k" . tempel-previous)
            ("TAB" . tempel-next)
            ("S-TAB" . tempel-previous))
    :init
    ;; Setup completion at point
    (defun tempel-setup-capf ()
      ;; Add the Tempel Capf to `completion-at-point-functions'.
      ;; `tempel-expand' only triggers on exact matches. Alternatively use
      ;; `tempel-complete' if you want to see all matches, but then you
      ;; should also configure `tempel-trigger-prefix', such that Tempel
      ;; does not trigger too often when you don't expect it. NOTE: We add
      ;; `tempel-expand' *before* the main programming mode Capf, such
      ;; that it will be tried first.
      (setq-local completion-at-point-functions
        (cons #'tempel-complete
          completion-at-point-functions)))

    (add-hook 'conf-mode-hook 'tempel-setup-capf)
    (add-hook 'prog-mode-hook 'tempel-setup-capf)
    (add-hook 'text-mode-hook 'tempel-setup-capf)))

在gui下,tab总是触发indent-for-tab-command。用的doom emacs 开启evil。各位大佬有何见解

我估计你要查一下 TAB 默认被什么绑定了,先解绑,再重新绑

试过了,但是这个地方有点让我懵的是。即使我把TAB从global-map中unset了,并检查了evil-insert-state-map中也没有TAB的绑定了。tab任然可以触发indent-for-tab-command。 而且我describe-key 得到的信息却是 tab是在evil-insert-state-map中绑定的。但是我前面提到,evil-insert-state-map已经没有这个tab绑定了

我查了一下我的 TAB 定义,在 Source Code 里发现这样的描述,不知道是否对你有用:

;; Defined in /opt/homebrew/Cellar/emacs-plus@30/30.0.91/share/emacs/30.0.91/lisp/indent.el
(defun indent-for-tab-command (&optional arg)
  "Indent the current line or region, or insert a tab, as appropriate.
This function either inserts a tab, or indents the current line,
or performs symbol completion, depending on `tab-always-indent'.
The function called to actually indent the line or insert a tab
is given by the variable `indent-line-function'.

If a prefix argument is given (ARG), after this function indents the
current line or inserts a tab, it also rigidly indents the entire
balanced expression which starts at the beginning of the current
line, to reflect the current line's indentation.

In most major modes, if point was in the current line's
indentation, it is moved to the first non-whitespace character
after indenting; otherwise it stays at the same position relative
to the text.

If `transient-mark-mode' is turned on and the region is active,
this function instead calls `indent-region'.  In this case, any
prefix argument is ignored."
Functions called by indent-for-tab-command:

  completion-at-point
  forward-sexp
  indent--default-inside-comment
  indent--funcall-widened
  indent-region
  indent-rigidly
  insert-tab
  syntax-after
  syntax-class
  use-region-p
Primitives called by indent-for-tab-command:

  -
  <
  <=
  >
  buffer-chars-modified-tick
  current-column
  current-indentation
  default-value
  eolp
  eq
  eql
  forward-line
  memq
  not
  point
  point-marker
  region-beginning
  region-end
  save-excursion

感觉可能不是一个问题,因为问题是TAB为何一直触发indent-tab-for-command 的问题

还有个奇怪的点,即使我不unset TAB, TAB也没有出现在 evil-insert-state-map中。但是 describe-key 任然显示TAB来自于evil-insert-state-map

大哥,C-i是有用的

为何describe-key的描述中是这样的

<tab> runs the command indent-for-tab-command (found in evil-insert-state-map),
which is an interactive native-compiled Lisp function in ‘indent.el’.

It is bound to TAB.

(indent-for-tab-command &optional ARG)

为何 It is bound to TAB

在gui下按键盘上的tab键对应的键码是<tab>,默认会被转译成TAB,如果<tab>已经被劫持了,你只改TAB是没用的。

但是我绑在<tab>上也没用,<tab>和TAB都绑上也没用

(after! tempel
  (use-package! tempel
    :bind (:map tempel-map
            ("M-j" . tempel-next)
            ("M-k" . tempel-previous)
            ("<tab>" . tempel-next)
            ("TAB" . tempel-next)
            ("<backtab>" . tempel-previous))
    :init
    ;; Setup completion at point
    (defun tempel-setup-capf ()
      ;; Add the Tempel Capf to `completion-at-point-functions'.
      ;; `tempel-expand' only triggers on exact matches. Alternatively use
      ;; `tempel-complete' if you want to see all matches, but then you
      ;; should also configure `tempel-trigger-prefix', such that Tempel
      ;; does not trigger too often when you don't expect it. NOTE: We add
      ;; `tempel-expand' *before* the main programming mode Capf, such
      ;; that it will be tried first.
      (setq-local completion-at-point-functions
        (cons #'tempel-complete
          completion-at-point-functions)))

    (add-hook 'conf-mode-hook 'tempel-setup-capf)
    (add-hook 'prog-mode-hook 'tempel-setup-capf)
    (add-hook 'text-mode-hook 'tempel-setup-capf)))

你尝试过在运行时查看<tab>的绑定吗?我怀疑它被另一个keymap劫持了

我只会describe-key

还有,你确定tempel-map已经按正确的顺序被绑定了吗

插入snippet 之后,describe-key tab 显示是这样的

<tab> runs the command indent-for-tab-command (found in evil-insert-state-map),
which is an interactive native-compiled Lisp function in ‘indent.el’.

(indent-for-tab-command &optional ARG)

tempel-map is a variable defined in tempel.el.

Value
           tempel-kill
<backtab>  tempel-previous
<tab>      tempel-next
M-<        tempel-beginning
M-<down>   tempel-next
M-<up>     tempel-previous
M->        tempel-end
M-ESC ESC  tempel-abort
M-RET      tempel-done
M-j        tempel-next
M-k        tempel-previous
M-{        tempel-previous
M-{        tempel-previous
M-}        tempel-next
M-}        tempel-next
TAB        tempel-next

describe-mode找一下

<remap> <beginning-of-defun>	treesit-beginning-of-defun
<remap> <end-of-defun>			treesit-end-of-defun

<normal-state> C-t		better-jumper-jump-backward

C-M-q			prog-indent-sexp

<normal-state> M-n		my/eldoc-box-scroll-down
<normal-state> M-p		my/eldoc-box-scroll-up

只有这些按键绑定

漏了一些,但是我用consult搜了一下,没有关于tab的绑定

Persp minor mode (indicator #ngcft):
Toggle the persp-mode.

When active, keeps track of multiple 'perspectives',
named collections of buffers and window configurations.
Here is a keymap of this minor mode:

Key             Binding

C-x 0			+workspace/close-window-or-workspace
  (Remapped via <remap> <delete-window>)
C-x 0			+workspace/close-window-or-workspace
  (Remapped via <remap> <evil-window-delete>)

C-c p C			persp-kill
C-c p I			persp-import-win-conf
C-c p K			persp-kill-buffer
C-c p L			persp-load-from-file-by-names
C-c p S			persp-window-switch
C-c p W			persp-save-to-file-by-names
C-c p a			persp-add-buffer
C-c p b			persp-switch-to-buffer
C-c p c			persp-copy
C-c p i			persp-import-buffers
C-c p k			persp-remove-buffer
C-c p l			persp-load-state-from-file
C-c p n			persp-next
C-c p o			[byte-code]
C-c p p			persp-prev
C-c p r			persp-rename
C-c p s			persp-frame-switch
C-c p t			persp-temporarily-display-buffer
C-c p w			persp-save-state-to-file
C-c p z			persp-save-and-kill

这是另一段关于按键绑定的描述