orderless completion当中排序的问题

在使用orderless时,按照orderless主页的推荐设置后,排序似乎有一些不合理,如下图:

image

显然在这里最符合的是smartparens-mode,但却排在比较后面。我目前相关的配置如下:

(setq completion-styles '(orderless)
            completion-category-defaults nil
            completion-category-overrides '((file (styles partial-completion))))

该如何设置completion-stylescompletion-category-overrides?根据completion-styles-alist的描述,我感觉这里应该要加入emacs22,但是应该放在什么位置呢?

  1. 所有结果按字典序排列,当然就会这样

  2. 你这样对自己想要什么结果不是很清楚的,还不如不用 orderless 用默认的排序。

也就是 basic style。

你这个是正常的,orderless 的风格就是这样。因为你的第一个候选里面也匹配了 smartparens-mode,然后所有的候选按字母排序。

你可以试试这样设置:

(setq completion-styles '(basic partial-completion orderless)
        completion-category-overrides '((file (styles basic partial-completion))))

这样只会使用 basic,如果在minibuffer 中 用了 vertico,第一个关键字加空格后才会激活 ordeless

还有一种方法是,只在 minibuffer 中启用 orderless 比如 purcell 的配置:

如果你想在 buffer 中用 orderless,推荐你试试 corfu 这个补全前端,它可以使用 M-Space 来启动 orderless 的补全风格。

1 个赞

orderless 最近更新了一个推荐配置。 相关的讨论可以参考这里

还是有些一知半解,有几个问题需要请教一下

  1. completion-styles的配置中,是按顺序逐一尝试补全,在此过程中只要有了结果,就不再往后了吗?还是说每一个补全选项都会使用,但是按照列表中的顺序来排列?从您给的链接中的讨论来看,应该是前者。那么按照一般的输入习惯,(basic orderless)的配置似乎还是比较合理的,更重要的是可以用TAB来补全共同前缀,我的理解正确吗?
  2. minibuffer中的补全,orderless应该是必要的,那么不同于purcell的配置,能否让orderless的补全机制在不同的buffer中有不同的形式?比如在一般的buffer中采用(basic orderless),而在minibuffer中使用(orderless)
  3. completion-category-overrides的作用究竟是什么,我读它的docstring理解不了,例如((file (styles partial-completion)))的意思是,在minibuffer需要补全file名称的时候,使用partial-completion作为completion-style吗?那类似地,如果需要补全function/variable等等,应该怎样分门别类设置呢? EDIT:我这部分的理解应该是错的,如下图,顺序错误的情况下仍然可以匹配到test.org,应该对应的不是substring

对于emacs的补全机制比较晕,之前折腾company-mode的时候就云里雾里,希望趁这个机会能够搞懂相应的知识。

  1. 应该是你理解的这样
  2. purcell 的配置就是只在 minibuffer 中启用 orderless( minibuffer-setup-hook 的函数就是做这件事)。全局的你根据需要设置就好了。
  3. 这个我也不是很明白具体用途,等其他大佬给你解释吧。

第三点按我的理解就是分类,在不同情况下自动使用不同的补全风格。

以 eglot 中需要配置 orderless 风格为例,因为 eglot 会将补全风格默认设置为 flex,而需要在eglot中使用 orderless,就要进行下面的设置:

(setq completion-category-overrides '((eglot (styles orderless))))

这样不会影响其他地方。

不过我是使用另一种方案,直接在eglot 中使用我的全局设定的补全风格:

(with-eval-after-load 'eglot
   (setq completion-category-defaults nil))

参考 Home · minad/corfu Wiki · GitHub

遇到了类似的问题,似乎我这里是因为没有设置company-transformers (对补全列表进行转换或排序). 改完后似乎行为是正常的…

 :custom
 (company-transformers '(company-sort-prefer-same-case-prefix 
			             company-sort-by-occurrence
                         company-sort-by-backend-importance)) 
3 个赞