去掉 helm/ivy/selectrum 使用原生的 completions buffer

我直接试用了solatle的配置(卸载了vertico),也感觉差不多,补全非常的“aggressive”,操作必须得非常快,稍一停顿,就会把第一个选项作为过滤条件了。而且选好了以后,需要多一次确认。

如果直接从ivy/vertico的逻辑转到aggressive-completion来看确实如楼上二位所说。C-n和C-p是我没用ac之前的配置(纯原生手动toggle completion buffer)保留下来的,用了ac就不经常用了,直接用输入过滤。如果不想那么aggressive可以M-t关闭,比如新建文件的时候,但是C-n C-p还是会像二位所说过滤其它选项,这个确实可以提交改进。

原生的补全机制还在慢慢完善,目前从效果来看肯定没用其它的第三方成熟。但选择原生的人就是喜欢少一点的弹出干扰和简单一致的minibuffer体验,跟ivy/vertico的出发点还是不太一样的,如果没有这方面的偏好,vertico功能性是更完善的,突然变到ac的逻辑肯定不习惯

需设置 aggressive-completion-auto-completenil,我只使用 M-<数字> 来选择候选项.

(defun my/completion-goto-line (n)
  "Select candidate by M-<number> or input a line number.
Just insert selection with prefix argument."
  (interactive
   (list (let* ((type (event-basic-type last-command-event))
                (char (if (characterp type)
                          ;; Number on the main row.
                          type
                        ;; Keypad number, if bound directly.
                        (car (last (string-to-list (symbol-name type))))))
                (n (- char ?0)))
           (if (zerop n) 10 n))))
  (switch-to-completions)
  (let ((line (if (<= n 10) n
                (read-number "Select line: ")))
        (completion-no-auto-exit (equal current-prefix-arg '(4))))
    (goto-line (- line display-line-numbers-offset))
    (choose-completion)))

(defun my/completion-goto-line-define-keys (maps)
  "Setup M-<number> key to select Nth candidate."
  (dolist (map maps)
    (dotimes (i 10)
      (define-key map (read-kbd-macro (format "M-%d" i)) 'my/completion-goto-line))))

  ;; M-<number> to select Nth candidate.
  (my/completion-goto-line-define-keys (list minibuffer-local-completion-map
                                             completion-in-region-mode-map
                                             completion-list-mode-map))

(defun my/completion-list-mode-hook-function ()
    (setq-local mode-line-format nil
                track-eol nil)
    (display-line-numbers-mode +1)
    (hl-line-mode -1)
    (rainbow-mode +1)
    (face-remap-add-relative 'line-number :background 'unspecified :foregound 'unspecified :inherit 'default)
    (face-remap-add-relative 'line-number-current-line :background 'unspecified :foregound 'unspecified :inherit 'default))
  (add-hook 'completion-list-mode-hook #'my/completion-list-mode-hook-function)

Completions buffer + aggressive-completion 补全非常丝滑。 分享下我的配置:

(use-package minibuffer
  :init
  (keymap-unset minibuffer-local-completion-map "SPC")
  :bind
  (:map completion-list-mode-map
	    ("z" . switch-to-minibuffer))
  :custom
  (isearch-allow-scroll t)
  ;(enable-recursive-minibuffers t)
  (minibuffer-depth-indicate-mode t)
  (minibuffer-electric-default-mode t)
  ;; Don't insert completion at point into minibuffer
  (minibuffer-completion-auto-choose nil)
  ;; One frame one minibuffer.
  (minibuffer-follows-selected-frame nil)
  (read-buffer-completion-ignore-case t)
  (read-file-name-completion-ignore-case t)
  (minibuffer-default-prompt-format " [%s]")
  (minibuffer-prompt-properties
   '(read-only t cursor-intangible t face minibuffer-prompt))
  (resize-mini-windows t)
  (completion-auto-help t)
  (completion-show-help nil)
  ;(completion-show-inline-help nil)
  (completion-cycle-threshold nil)
  ;; `t' `second-tab' `nil'
  (completion-auto-select 'seond-tab)
  (completions-detailed t)
  ;; Ignore cases when complete
  (completion-ignore-case t)
  ;; vertical display
  (completions-format 'one-column)
  (completions-max-height 7)
  (completions-sort #'completion:list-sort)
  :config
  ;; Hide the mode line of the Completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Completions\\*"
                 nil
                 (window-parameters (mode-line-format . none))))

  (defun completion:list-sort (all)
    "对 `Completions-buffer' 中的补全项进行排序"
    (let ((hist (minibuffer-history-value)))
      (thread-first all
                    (sort (lambda (c1 c2) (< (length c1) (length c2))))
                    (sort (lambda (c1 c2) (> (length (member c1 hist))
                                        (length (member c2 hist)))))))))

(use-package all-the-icons-completion
  :straight t
  :hook (after-init-hook . all-the-icons-completion-mode))

(use-package aggressive-completion
  :straight t
  :bind
  (:map aggressive-completion-minibuffer-map
         ("TAB" . completion:auto-select))
  :hook
  (after-init-hook . aggressive-completion-mode)
  :config
  (add-hook 'aggressive-completion-mode-hook #'completion:disable-auto-select)
  (defun completion:disable-auto-select ()
    ;; 避免自动切换至 `Completions-buffer' 中的补全项
    (setq completion-auto-select nil
    ;; 禁止 `minibuffer' 中的补全     
          completion-cycle-threshold nil))
  
  (defun completion:auto-select ()
    "`TAB' 键可切换至 `Completions-buffer' 中的补全项"
    (interactive)
    (let ((completion-auto-select t))
      (minibuffer-complete))))

(use-package orderless
  :straight t
  :custom
  (completion-styles '(orderless basic))
  (completion-category-defaults nil)
  (completion-category-overrides '((file (styles basic partial-completion)))))
1 个赞

能有个视频或者动图展示下有多丝滑就更好了

原生补全保姆级教程来了

4 个赞