El-search -- Expression based incremental search for emacs-lisp-mode (Emacs 25+)

http://elpa.gnu.org/packages/el-search.html

用 Pattern Matching (pcase)的方式搜索 Emacs Lisp 代码,与一般搜索测试字符串或 RegExp 是否匹配不同,el-search 测试的是你给出的在 Elisp 环境下的 Pattern,比如 (pred stringp) 则会搜素到代码中的字符串。

2 个赞

有点看不懂..

的确不是很容易理解,我很早(可能有几个月)就听说过它了,一开始一点都不明白,最近学了一些 Standard ML 里的 Pattern Matching,才又想起来这个包。C-h P el-search 里有很详细的介绍,不了解 pcase 其实也是能用的,只是用法比较局限。

匹配的是代码的各个组成部分,比如假设 Buffer 中的内容为:(setq a 1),那么最多会有 4 个匹配成功:

  1. (setq a 1)
  2. setq
  3. a
  4. 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 个赞

可以简单地理解为按形状/形式匹配

模式

`(+ ,_ ,_)

结果

(+ 1 2) ;; 匹配
(+ 1 2 3) ;; 不匹配
(+ 1 (+ 2 3)) ;; 匹配
(+ (+ 1 2) 3) ;; 匹配
1 个赞

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-letpcase-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).
3 个赞

http://debbugs.gnu.org/cgi/bugreport.cgi?bug=24362

有例子果然就容易理解多了~,赞一个

能不能解释一下他的splicing-mode呢? 看说明完全看不明白. 用多个表达式来替换一个匹配项?怎么理解这句话的意思啊…

我也一点都不明白什么意思,尝试使用也总是出错,代码太复杂,一时半会也看不出个所以然来。

扫了一眼作者的答复 [1],应该就是把 replacement 去掉一层括号,原本要替换成 (a b c),开启这个 mode 的话就变成 a b c 了。目前这个功能似乎用不了,作者提供了一个临时的补丁,我试了下,确实是这样子的。


1: Re: What is “splicing mode” in el-search.el?

恩。大致明白了,就是说一般情况下使用一个表达式替换另一个表达式,但是用这种方法可以将list拆成多个表达式来替代那个被匹配出来的表达式。