http://elpa.gnu.org/packages/el-search.html
用 Pattern Matching (pcase
)的方式搜索 Emacs Lisp 代码,与一般搜索测试字符串或 RegExp 是否匹配不同,el-search
测试的是你给出的在 Elisp 环境下的 Pattern,比如 (pred stringp)
则会搜素到代码中的字符串。
http://elpa.gnu.org/packages/el-search.html
用 Pattern Matching (pcase
)的方式搜索 Emacs Lisp 代码,与一般搜索测试字符串或 RegExp 是否匹配不同,el-search
测试的是你给出的在 Elisp 环境下的 Pattern,比如 (pred stringp)
则会搜素到代码中的字符串。
有点看不懂..
的确不是很容易理解,我很早(可能有几个月)就听说过它了,一开始一点都不明白,最近学了一些 Standard ML 里的 Pattern Matching,才又想起来这个包。C-h P el-search
里有很详细的介绍,不了解 pcase
其实也是能用的,只是用法比较局限。
匹配的是代码的各个组成部分,比如假设 Buffer 中的内容为:(setq a 1)
,那么最多会有 4 个匹配成功:
(setq a 1)
setq
a
1
其中 1 是 list,2 和 3 是 symbol,4 是个 number。匹配的规则在 Elisp manual 中有介绍。
(pcase '(setq a 1) ; 代码
(`(setq ,name ,val) ; 搜索词
(message "%s = %s" name val) ; 动作
))
=> "a = 1"
可以简单地理解为按形状/形式匹配
模式
`(+ ,_ ,_)
结果
(+ 1 2) ;; 匹配
(+ 1 2 3) ;; 不匹配
(+ 1 (+ 2 3)) ;; 匹配
(+ (+ 1 2) 3) ;; 匹配
pcase-let 和 pcase-let* 我到现在都还没看懂怎么用的,求说明,求举例
;; 匹配一切,比如数字
(pcase-let ((x 123))
x)
==> (let* ((x 123)) x)
=> 123
;; 匹配 cons cell
(pcase-let ((`(,car . ,cdr) (cons 'one 1)))
(cons car cdr))
=> (one . 1)
;; 匹配长度至少为 2 的列表
(pcase-let ((`(,first . (,second . ,rest)) (list 1 2 4 5 5)))
(list first second rest))
=> (1 2 (4 5 5))
;; 我搜索了下下 Emacs 自身的代码,也差不多都是非常简单的应用
(pcase-let ((`(,beg . ,end) (bounds-of-thing-at-point 'sexp)))
(buffer-substring-no-properties beg end))
=>
"(pcase-let ((`(,beg . ,end) (bounds-of-thing-at-point 'sexp)))
(buffer-substring-no-properties beg end))"
上面的 pcase-let
都只写了一个 binding,但是与 let
相似,可以接受多个 binding,但后面的 binding 不能用到前面 binding。
(pcase-let ((a 1)
(b a))
(+ a b))
error--> (void-variable a)
而 pcase-let*
可以
(pcase-let* ((a 1)
(b a))
(+ a b))
=> 2
pcase-let
和 pcase-let*
的 docstring 似乎有一点不一致,不清楚是不是值得 M-x report-emacs-bug
。
(pcase-let* BINDINGS &rest BODY)
Like `let*' but where you can use `pcase' patterns for bindings.
BODY should be an expression, and BINDINGS should be a list of bindings
^^^^^^^^^^^^^
of the form (PAT EXP).
(pcase-let BINDINGS &rest BODY)
Like `let' but where you can use `pcase' patterns for bindings.
BODY should be a list of expressions, and BINDINGS should be a list of bindings
^^^^^^^^^^^^^^^^^^^^^
of the form (PAT EXP).
有例子果然就容易理解多了~,赞一个
能不能解释一下他的splicing-mode呢? 看说明完全看不明白. 用多个表达式来替换一个匹配项?怎么理解这句话的意思啊…
我也一点都不明白什么意思,尝试使用也总是出错,代码太复杂,一时半会也看不出个所以然来。
扫了一眼作者的答复 [1],应该就是把 replacement 去掉一层括号,原本要替换成 (a b c)
,开启这个 mode 的话就变成 a b c
了。目前这个功能似乎用不了,作者提供了一个临时的补丁,我试了下,确实是这样子的。
恩。大致明白了,就是说一般情况下使用一个表达式替换另一个表达式,但是用这种方法可以将list拆成多个表达式来替代那个被匹配出来的表达式。