【傻瓜教程】Emacs 定身术之 consult+embark+wgrep 跨文件批量搜索替换

:joy:我也是才知道原来 wgrep 居然有个单独的包

猛一看这个名字我还以为和 wdired 一样是内置插件,后来看到它近两年没更新就不太想用它,没想到刚装上还没用起来它就更新了,所以我就照着坛里几个帖子把 wgrep 用了起来。

如果不是你,我真没注意原来 rg 和 deadgrep 已经集成了这些功能。

我再试试 color-rg,多搞几套方案。 :stuck_out_tongue_closed_eyes:

我想起来为啥我没第一时间研究 deadgrep 是不是有高级功能了:我的 test.eltest.org 都 gitignore 了,deadgrep 默认不搜索被 ignore 的文件……

回头我看看有没有切换搜索被 ignore 的文件的功能。

我挺喜欢deadgrep的,因为它的界面上端把查询条件都做成了交互式,可以很方便的切换,文件目录、case insensitive 之类的… 唯一缺点是界面太素了 :joy:

加张图:上面是交互式的,任意更改。modeline圆圈里 == 其实是指示查询状态的,一直在滚动。

2 个赞

关于二次输入查询语句的问题:

  1. 使用consult内置的查询当前光标所在symbol的功能,但不够智能。
  2. 使用 更通用的xxx-thing-at-point 的方案。自动把xx-at-point/或region 作为查询词,任意输入的时候会自动抹掉自选词,输入自己的词。

方案二挺牛掰的。

更正:会错意了,以上无法解决二次输入问题。

方案二的思路确实很智能,非常棒的思路,也可以用在别的场景里(比如翻译单词/句子/段落、选区)。

是的,非常舒服,因为那些自动选择到minibuffer里的的文字有自删功能。只要不是指定command, 就会自动销毁。

另外说到替换,还有个功能很棒:project-query-replace-regexp。 比如emacs.d有很多子目录子文件,我有个自定义命令叫custom-command分散到各个文件里, 想统一换成my-custom-command, 这个命令可以很方便替换所有。

我很不解的一点就是 Emacs 自己的 rename-visited-file 居然没有自动填写当前文件名+文件扩展名并提前选中文件名的功能,而是默认完全从零重命名。

macOS 的访达只需要按回车就自动选中文件名(开启了显示文件扩展名功能),这一点非常人性化。

哈哈我也不李姐。

所以我用protesilaos方案:

2 个赞

感谢感谢 :pray: 又抄到一个实用配置。

今天遇到了一个可以用类似思路解决的情景,假如我有这样一个 org:

* 1
afaf a
* 2
adfadf
* 3
adfa
* 4
afaf
* 5
afasdf
* 6
adsf
* 7
sfasdf
* 8
adsfa
* 9
* 10

想要在 1-9 编号的 headline 中补 0 以实现对齐。这时没法直接用块编辑,可以通过 consult-outline 过滤出 headline 结构,然后用 embark export 出 occur buffer, 然后按 e 进入编辑模式,这样就可以使用块编辑实时修改了。

1 个赞

感谢分享。

我发的第一个帖子就是问的类似问题:多个文件多个区域的文本 narrow 到一个单独 buffer 中编辑(yode.nvim)

这种两个或多个插件协同实现 1+1+… > (1+1+…)^(1+1+…) 的体验真的爽!

ivy swiper 和vertico emark consult

整合利用rg +wgrep

doom都支持了这样的操作,这两个抄过来,一直是用的最爽的功能了,特别是重构的时候。

实现批量编辑功能的是 wgrepivyhelmconsultrg 都基于 wgrep,也有插件独立实现了 wgrep 的功能,比如 helm-ag

批量搜索替换不需要 wgrep 以外的第三方插件:

  1. M-x grep RET
  2. C-a C-k rg -n -H --no-heading XXX RET
  3. C-c C-p

前两步可以简单包装一下:

(defvar rg-command-prompt "rg -n -H --no-heading ")

(defun rg ()
  (interactive)
  (require 'grep)
  (grep--save-buffers)
  (compilation-start
   (read-shell-command "command: "
                       rg-command-prompt
                       'grep-history)
   'grep-mode))
  1. M-x rg RET XXX RET
  2. C-c C-p

这种场景很适合用 replace-regexpC-M-% \* \([0-9]\)$ RET * 0\1 RET。vim/evil 用户::%s/\* \([0-9]\)$/* 0\1/gc

:sweat_smile: 正则还是太麻烦了,每次都得在脑子里先绕一会儿,不如块编辑直观

是的。要是规则能抽象出来,直接sed完事,比什么都快。这个定身术就强在不需要写规则,直接把搜索出来的结果具体情况具体分析,一个一个改就好了,交互式操作。

前几天刚装了rg.el ,搜索替换比这个好。

但是rt el修改完搜索结果后。对应的文件没有自己保存。需要到buff中按 C x C s 不知道是我没弄明白还是它只能如此。

按 C-x s 可以批量保存所有 buffer

:+1: 了解。那就没问题了。