举例说明, 有如下三个候选项:
aaabbbaaa
aaaccc
aaaddd
输入aa aa
后, 等效于aa.*aa
, 能唯一匹配第一行, 而不是像orderless或者helm三行都匹配. 他们匹配输入的每个"component" 都是从候选字符串的开头开始, 很不方便.
期望的匹配算法如下:
比如针对第一行的aaabbbaaa
, 用户输入aa
后空格, 算法就把最左匹配(即候选项开头的aa
)去掉不再考虑, 剩余"abbbaaa", 然后用户又输入了第二个aa
, 那么就从剩余的abbbaaa
中搜索第二个aa
, 这样就唯一匹配到了第一行的候选项.
lynnux
2023 年11 月 16 日 15:03
2
consult rg默认风格不就是吗,虽然我不用,不过它是#分割
我说的不是这个搜索外部文件, 而是emacs内的补全界面, 比如切换buffer, M-x等.
helm 把输入的匹配字符串按空格分割,分成n个独立的部分,每个部分都去匹配候选项。这么做的优点是,可以忽略输入字符的顺序,例如 cc aa
可以匹配 aaaccc
,缺点是 aa aa
效果等同于 aa
,而你要得效果其实是把 aa aa
转换成 aa.*aa
,在 helm 上可以这样实现:
(cl-letf (((symbol-function 'helm-mm-3-get-patterns-internal)
(lambda (pattern)
(cl-loop for pat in (helm-mm-split-pattern pattern)
collect pat into pats
finally return (list (cons 'identity (string-join pats ".*")))))))
(completing-read "> " '("aaabbbaaa" "aaaccc" "aaaddd")))
2 个赞
fuzzy matching 的話, 我推薦 flx . magit
的維護者 @tarsius
認為這是 elisp 包裡唯一聰明的 演算法. 我自己也很喜歡用.
1 个赞
这个 flx 好像作者都不怎么维护了。能用在 Emacs 29 和 Emacs master 上吗? 和 orderless 相比有什么特点呢?
可以用啊~ 依照作者本人的意思. 這個插件已經接近完美了, 所以不需要更新! 我自己也蠻認同的!
aqua0210:
和 orderless 相比有什么特点呢?
orderless 可以配置的東西比較多. 但我怎麼配, 都沒有 flx 好用. 我因為開發 company-fuzzy 用了大概 10 幾種模糊匹配 (包含 completion-styles
) 的演算法; 最後總結, flx 比較好用.
不過這個本身就很吃使用習慣, 所以自己用的習慣就行! flx 的特色就是聰明 和短 , 但沒有配置選項.
2 个赞
flx 只支持 ido,没法和 vertico 配合。还是需要更新维护的。
还有个新的 hotfuzz, readme 中有 orderless 和 flx 的比对。这个比 orderless 多了排序,不用空格,比较像内置的 flex。
参考:https://github.com/minad/vertico/issues/177#issuecomment-1008182328
1 个赞
我用了很久的 orderless,习惯了。但最近发现左手拇指按太多 Meta 和 空格,开始痛了。所以我打算换掉 orderless。 对 fix 还是比较感兴趣的,可惜我不知道怎么让它在 Emacs 30中支持 completing-read
PS:原来可以通过 fussy 支持 flx:
用上了大佬写的 flx-rs + fussy, 体验很好。
1 个赞
xiyang
2023 年11 月 22 日 02:49
12
现在大家都用 consult
了吗?如果用的 counsel-*
,可以使用
(setq ivy-re-builders-alist
'((t . ivy--regex-plus)))
1 个赞
对, 就是这个意思, 以前用ido的时候, 就把它改成这样了, 感觉非常好用.
你这是怎么做到不高亮中间文本(abbb
)的? 中间匹配.*
的内容应该也会被高亮吧?
这个插件作者好像是国内的emacs早期玩家. 我看下这个插件能否实现我想要的功能
现在估计很多都用的virtio+consult, 我也是用的这个.
这个匹配算法接口如果遵循emacs内置的completion style, 好像是可以通用的, 类似orderless.
看了下ivy的好像不是这么设计的.
在我电脑上测试了下, 跟预期不一样, 匹配方式依然是老的方式, 可能是我的helm版本太老.
另外, 现在不怎么用helm, 主要用consult了.
@jcs090218 大佬,请问下用 fussy + flx 时下面这个结果是正常的吗?为什么 message-supersede
是第一候选,而不是 message
.
我的配置:
(use-package fussy
:custom
(completion-styles '(fussy basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles basic partial-completion))
(eglot (styles fussy basic))))
(fussy-filter-fn 'fussy-filter-default)
(fussy-use-cache t)
:config
(advice-add 'corfu--capf-wrapper :before 'fussy-wipe-cache)
(add-hook 'corfu-mode-hook
(lambda ()
(setq-local fussy-max-candidate-limit 5000
fussy-default-regex-fn 'fussy-pattern-first-letter
fussy-prefer-prefix nil))))
目前没法用 flx-rs,因为我这边开开启 flx-rs 时,有些后选会丢失。可能和下面这个 PR有关。
jojojames:main
← jimeh:clean-flx-rs-score-strings
opened 07:01PM - 20 Nov 23 UTC
When using the `flx-rs` scoring backend, we need to run given string values thro… ugh `fussy-remove-bad-char-fn` to match the behavior of using the flx scoring backend.
Without cleaning up bad characters, `flx-rs` seems like it works, but a lot of result candidates do not appear, yielding a much smaller result set compared to using `flx`. This fixes that, so results for both match.
是正常的唷!
(flx-rs-score "message-supersede" "mes") ; (220 0 1 8)
(flx-rs-score "message" "mes") ; (214 0 1 2)
flx
的首字比重比較高.
[me]ssage-[s]upersede
大於,
[mes]sage-supersede
1 个赞