使用consult搜索时,输入中文后结果无法实时更新,但输入英文可以

在linux emacs中使用consult搜索中文时,搜索结果无法实时反馈,需要按下方向键、空格键才刷新,但是输入英文就可以实时刷新。大家知道如何解决吗?

相关信息:

  • Emacs版本:GNU Emacs 30.2 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.51, cairo version 1.18.4) of 2025-12-07
  • 配置用的是Purcell的,作了一点点小修改,如下:
     ;;; init-minibuffer.el --- Config for minibuffer completion       -*- lexical-binding: t; -*-
     ;;; Commentary: 迷你缓冲区补全配置
     ;;; Code:

  (when (maybe-require-package 'vertico)
  (add-hook 'after-init-hook 'vertico-mode)

  (when (maybe-require-package 'embark)
    (with-eval-after-load 'vertico
      (define-key vertico-map (kbd "C-c C-o") 'embark-export) 
      (define-key vertico-map (kbd "C-c C-c") 'embark-act))) 

  (with-eval-after-load 'embark
    (push 'embark--mark-target
          (alist-get 'whole-line-or-region-delete-region
                     embark-around-action-hooks)))

  (when (maybe-require-package 'consult)
    (defmacro sanityinc/no-consult-preview (&rest cmds) 
      `(with-eval-after-load 'consult
         (consult-customize ,@cmds :preview-key "M-P"))) 

    (sanityinc/no-consult-preview
     consult-ripgrep
     consult-git-grep consult-grep
     consult-bookmark consult-recent-file consult-xref
     consult--source-recent-file consult--source-project-recent-file consult--source-bookmark) 

    (defun sanityinc/consult-ripgrep-at-point (&optional dir initial)
      (interactive (list current-prefix-arg
                         (if (use-region-p)
                             (buffer-substring-no-properties
                              (region-beginning) (region-end))
                           (if-let ((s (symbol-at-point)))
                               (symbol-name s)))))
      (consult-ripgrep dir initial))
    (sanityinc/no-consult-preview sanityinc/consult-ripgrep-at-point)
    (when (and (executable-find "rg"))
      (global-set-key (kbd "M-?") 'sanityinc/consult-ripgrep-at-point))

    (global-set-key [remap switch-to-buffer] 'consult-buffer)
    (global-set-key [remap switch-to-buffer-other-window] 'consult-buffer-other-window)
    (global-set-key [remap switch-to-buffer-other-frame] 'consult-buffer-other-frame)
    (global-set-key [remap goto-line] 'consult-goto-line)

    ;;; 以下为自己添加的设置

    (global-set-key (kbd "C-s") 'consult-line)
    (global-set-key (kbd "M-s") 'consult-line-multi)
    (global-set-key (kbd "C-c r") 'consult-history)
    ;; ;; ;; ;; (global-set-key (kbd "C-y") 'consult-yank-from-kill-ring)
    (global-set-key (kbd "M-y") 'consult-yank-pop)
    ;; ;; (global-set-key (kbd "C-x M-:") 'consult-complex-command)
    (global-set-key (kbd "C-x p b") 'consult-project-buffer)
    ;; (global-set-key (kbd "M-g o") 'consult-outline)
    ;; (global-set-key (kbd "M-g m") 'consult-mark)
    ;; (global-set-key (kbd "M-g k") 'consult-global-mark)
    ;; (global-set-key (kbd "M-g i") 'consult-imenu)
    ;; (global-set-key (kbd "M-g I") 'consult-imenu-multi)
    ;; (global-set-key (kbd "M-s f") 'consult-find)
    ;; (global-set-key (kbd "M-s l") 'consult-locate)
    ;; (global-set-key (kbd "M-s g") 'consult-grep)
    ;; (global-set-key (kbd "M-s r") 'consult-ripgrep)

    ;; (setq xref-show-xrefs-function #'consult-xref
    ;;       xref-show-definitions-function #'consult-xref)
  ;;; 以上为自己添加的设置

    (when (maybe-require-package 'embark-consult)
      (require 'embark-consult))))

  (when (maybe-require-package 'marginalia)
      (add-hook 'after-init-hook 'marginalia-mode))


  (provide 'init-minibuffer)
;;; init-minibuffer.el ends here

动图如下: consult-line

你确定是输入了三个字符?没看懂,来个动图啥的。

是最小搜索字符限制的原因?

(setq consult-async-min-input 2)

试试这个

是的,输入多少个字符都不更新,必须要敲下方向键或空格键才行,晚上我截个动图上传下

这个是默认值3,没改。在Windows也是这个值,但Windows上就不存在这个问题,调用 consult-line命令后,输入一个汉字立马实时更新只显示包含了该汉字的行。

emacs in termux, centuar emacs. consult-grep 英文正常响应,中文无响应的说(゜゜) 可能是编码问题?windows上不是utf

是windows下没问题,在Gentoo GNU/Linux下有问题 :joy:

我知道你说的什么意思了,就是consult-line 这个命令吧。我尝试找找问题哈,不一定能解决。

编辑:我用AI查到 minibuffer 对 IME preedit 的支持 (特别是在 macOS 和 GTK) 有问题。可能性高,但是我没啥证据。

再编辑:假如你用复制粘贴的方式,你会看到只有一个字也能触发。也就是跟汉字文本没关系,问题出在深层的地方,也许真的是输入法的问题。。。那这个问题就过于难为我了。又是corfu那个作者,他不用中文输入法,测试直接复制一个字来测试也不管用。我给他报问题他可能又会直接关闭。。。让我直接上报emacs。妈蛋。。。。

感谢呀。解决不了也没啥关系,其实不太影响使用,敲个空格或其他键其实就行了。只是在迷你缓冲区里不实时更新,感觉有些不习惯和不方便 :rofl: 。反而在windows下没啥问题,也可能问题是出在配置上。

我在 macOS / linux 上不能复现。不管是使用 consult-ripgrep 还是 consult-line,敲完中文都能够立即刷新。我使用的是 squirrel / fcitx5+rime 输入法。

不过我是把 fcitx5 的 preedit 给关掉了。但是 macOS 的我 preedit 我没关。

大概率是我配置的问题。

我使用的也是fcitx5,用的是五笔拼音。

昨天研究了好长一段时间gif图生成,没能搞定,安装的peek不知道为啥生成的图全是黑屏,ffmpeg转的动图又非常大。

我能复现,不过我给不出问题的原因。录屏然后ffmpeg -i test.mp4 test.gif 就好。

编辑:只在gui下生效,terminal中没问题。

(defun my-consult-line-chinese-fix ()
  (when (minibufferp)
    (let ((last-input ""))
      (add-hook 'post-command-hook
                (lambda ()
                  (when (minibufferp)
                    (let ((input (minibuffer-contents-no-properties)))
                      (unless (equal input last-input)
                        (setq last-input input)
                        ;; 输入变化后,强制延迟刷新
                        (run-with-idle-timer 
                         0.05 nil
                         (lambda ()
                           (when (active-minibuffer-window)
                             (with-selected-window (active-minibuffer-window)
                               (setq vertico--input t)
                               (vertico--exhibit)))))))))
                nil t))))

(add-hook 'minibuffer-setup-hook #'my-consult-line-chinese-fix)	

暂时用这个方法可以解决。AI 确实判断的很准,就是真判断解决问题有些麻烦。

我用的gnome自带的录屏程序录的,格式是webm,就3M多,但是用 ffmpeg -i consult-line.webm consult-line.gif 之后,动图有300多兆 :face_with_crossed_out_eyes:

我也gnome,但是录视频也就一百多kb,五秒钟搞定。你先试试这个方法能解决吗?我测试没问题。我用的vertico,如果和你的不一致,也许得做其他修改。

嗯嗯,好的,感谢,我晚上试试

(defun my-consult-line-chinese-fix ()
  "Fix input delay for Vertico completion."
  (when (and (minibufferp) (boundp 'vertico-mode) vertico-mode)
    (let ((timer nil))
      (add-hook 'post-command-hook
                (lambda ()
                  (when timer (cancel-timer timer))
                  (setq timer
                        (run-with-idle-timer
                         0.05 nil
                         (lambda ()
                           (when (and (active-minibuffer-window)
                                      (window-live-p (active-minibuffer-window)))
                             (with-current-buffer (window-buffer (active-minibuffer-window))
                               (when (bound-and-true-p vertico--candidates-ov)
                                 (setq vertico--input t)
                                 (vertico--exhibit))))))))
                nil t)
      (add-hook 'minibuffer-exit-hook
                (lambda () (when timer (cancel-timer timer)))
                nil t))))

(add-hook 'minibuffer-setup-hook #'my-consult-line-chinese-fix)

修正。

感谢感谢,我学习下 :grin:

我又改了下,期待某个大神发现并解决这个问题,我做的这个其实是个临时措施。我描述不出问题到底出在哪里。

gif 就是个非常简陋的多帧图像存储格式,压缩率远远比不上正经视频格式。降分辨率和帧率应该能压缩到合适的大小。