这个函数可以加个选项
感谢大佬!但是我个人能力有限,还是没太研究明白!
目前的困惑是,具体不知道该把 “python c:/py-rg.py” 这样的调用脚本命令加在哪!
目前我先大概参考了一下大佬的 color-rg 整体功能思路,自己写了一个丐版的先暂时在 windows 上用着!等腾出时间再仔细研究 ,以 color-rg 为基础写入自己的一些想要的功能!
;;;
;;; ~ rg for ZH-CN | Eng | Korean ~
;;;
(defun blove/make-rg-open-f-link (label link line)
"click, open the fiel, goto the line"
(insert-button label
'action (lambda (_) (find-file link)(goto-line (string-to-number line)))
'follow-link t
)
(insert "\n")
)
(defun blove/open-rg-ret-in-buffer (item-list)
"popup a buffer, list the results & file-open-link"
(let ((buf (get-buffer-create "*RipGrep Blove Buffer*")))
(with-current-buffer buf
(erase-buffer)
(mapcar (lambda (item)
(setq label (concat item " " "ﰺ"))
(setq dest-line (nth 2 (split-string item ":")))
(blove/make-rg-open-f-link label (concat (nth 0 (split-string item ":")) ":" (nth 1 (split-string item ":"))) dest-line)
)
item-list))
(pop-to-buffer buf t)
)
)
(defun blove/rg-search-by-sel-region (py-script path-or-file)
"main function for sel-region"
(interactive)
(let* (
(selection
(if (memq window-system '(w32 pgtk))
(url-encode-url (buffer-substring-no-properties (region-beginning) (region-end)))
(buffer-substring-no-properties (region-beginning) (region-end))
)
)
(rg-cmd (concat py-script " \"" selection "\" \"" path-or-file "\""))
(item-list (split-string (shell-command-to-string rg-cmd) "\n" "\n" "0"))
)
(if (not (= (string-to-number (car item-list)) 1))
(blove/open-rg-ret-in-buffer item-list)
(message "No matches were found!!!")
)
)
)
(defun blove/rg-search-by-word-point (py-script path-or-file)
"main function for word-at-point"
(interactive)
(let* (
(keywd
(if (memq window-system '(w32 pgtk))
(url-encode-url (word-at-point))
(word-at-point)
)
)
(rg-cmd (concat py-script " \"" keywd "\" \"" path-or-file "\""))
(item-list (split-string (shell-command-to-string rg-cmd) "\n" "\n" "0"))
)
(if (not (= (string-to-number (car item-list)) 1))
(blove/open-rg-ret-in-buffer item-list)
(message "No matches were found!!!")
)
)
)
python 脚本
import os,sys
import platform
from urllib.parse import unquote
if platform.system() == "Windows":
cmd = "rg -E utf-8 -H --no-heading -n " + unquote(sys.argv[1]) + " " + sys.argv[2]
else:
cmd = "rg -E utf-8 " + sys.argv[1] + " " + sys.argv[2]
if __name__ == "__main__":
print(os.system(cmd))
调用方式
(global-set-key (kbd "C-c C-g") (lambda () (interactive) (blove/rg-search-by-sel-region "c:/py-rg.py" "c:/rg-search-path")))
(global-set-key (kbd "C-x C-g") (lambda () (interactive) (blove/rg-search-by-word-point "c:/py-rg.py" "c:/rg-search-path")))
你其实就想加一个 -E utf-8 的参数给rg撒?
不是的!如果那样就简单了! 因为我发现即使在 color-rg.el 中的 775 行,加 -E utf-8 也是无法搜索到韩文的
也就是说,目前在windows上经由 emacs 调用 powershell、cmd 运行 rg 搜索韩文都是不能获得有效结果的!系统会将关键字变成空格!即使大佬根据系统判断,设置了 (when (memq system-type '(cygwin windows-nt ms-dos))
(setq command-line (encode-coding-string command-line locale-coding-system)))
也只是对搜索中文有效、结果正确!但对于搜索韩文是无效的!
而且我发现,在 828 和 877 行都已经设定了使用 powershell
现在我所能实现的唯一有效办法是绕开 windows的 powershell、cmd,借助 python 脚本运行 rg 进行搜索:
1-将需要搜索的 韩文关键字 通过 url-encode-url 转码出去(这可以保证关键字能被搜索到) →
2-将其作为参数传递给 python,并在python脚本中使用 unquote 解码,供 rg 搜索 →
import os,sys
from urllib.parse import unquote
cmd = "rg -E utf-8 -H --no-heading -n " + unquote(sys.argv[1]) + " " + "rg-search-path"
os.system(cmd)
3-然后使用 shell-command-to-string 命令调用 python 脚本去运行 rg 搜索(而不是用 powershell 运行 rg),就能正确搜索到韩文了
(setq rg-cmd (concat "c:/py-rg.py" " \"" keywd "\" \"" path-or-file "\""))
(shell-command-to-string rg-cmd)
经过 url-encode-url 转码和 python中介执行,似乎在 windows 就绕开了 gbk 虽然不懂其原理,也许有点绕、有点麻烦,但目前只知道这个方法而且也实现了想要的效果!
不懂韩文,我测试了一下,windows cmd中运行rg搜索韩文,发现能搜索到
但以前应该确实不能,甚至连cmd rg里搜索中文都有问题,应该可能是因为我把 系统语言设成了英文 ,然后各种gbk问题我好像都没有在遇到过了
是我没有描述清楚!
如果直接使用 powershell 或 cmd, 用 rg 搜索韩文,即使系统语言是中文,我这边也是可以有正确结果的!
我这边是通过 emacs 调用 powershell rg … 这样的命令时, 不管系统语言是中文或英文,都无法得到正确的结果!就是经由emacs 运行 rg 搜索 韩文 无效!
所以我感觉,可能还是从emacs中,抓取、输出的韩文 编码 无法被 powershell 正确识别!
有时,搜索到结果后,打开文件时,因为文件很大又或是windows平台会卡顿!所以根据我自己的需要,简单改写了 color-rg 的
color-rg-open-file (&optional stay)
函数。并配合 python 脚本,读取文件的指定部分内容(根据设定的数值,只选择匹配行的前几行和后几行),打印在 buffer 中!不再直接打开整个文件。
;;;
;;; dec line-thr, the lines of the match_line + -
;;;
(setq line-thr 5)
;;;
;;; def my match-hl-face
;;;
(defface blove-rg-match-hl-face
'((t (
:underline nil
:foreground "#FF0000"
:background "#000000"
:bold t :height 1.2)))
"for rg-match-hl"
)
;;;
;;; fork original-function
;;;
(defun color-rg-open-file (&optional stay)
"Open file, but read part of the file only, in a buffer."
(interactive)
;; (setq color-rg-window-configuration-before-open (current-window-configuration))
(let* ((match-file (color-rg-get-match-file))
(match-line (color-rg-get-match-line))
(buf (get-buffer-create "**Part Of the File**"))
)
(with-current-buffer buf
(erase-buffer)
(insert (shell-command-to-string (concat "python ~/tmp/read-part-of-the-file.py " "\"" match-file "\" " (int-to-string match-line) " " (int-to-string line-thr))))
(beginning-of-buffer)
(while (re-search-forward the-keywd nil t)
(let ((ov (make-overlay (match-beginning 0) (match-end 0))))
(overlay-put ov 'face 'blove-rg-match-hl-face))
)
)
(switch-to-buffer buf)
))
;;;
;;; use
;;;
(defun color-rg-search-eng-symbol-in-dest-path ()
(interactive)
(setq the-keywd (word-at-point))
(color-rg-search-input (color-rg-pointer-string) "~/to-search-path")
)
python 脚本
import sys
def ReadFilePart(f,match_line,line_thr):
with open(f,"r",encoding="utf-8") as fr:
lines = fr.readlines()
all_lines = len(lines)
match_line = int(match_line)
line_thr = int(line_thr)
if (match_line - line_thr) <= 0:
start_line = 0
else:
start_line = match_line - line_thr
if (match_line + line_thr) > all_lines:
end_line = all_lines - 1
else:
end_line = match_line + line_thr
for i in range(start_line,end_line + 1):
print(lines[i].split("\n")[0])
if __name__ == "__main__":
ReadFilePart(sys.argv[1],sys.argv[2],sys.argv[3])
color-rg 的很多实现,都是很实用的,成为了我使用 rg 搜索的基础依赖!
而且在 linux 上可以开心得搜索 中 英 韩 关键字。
在 windows 上搜索 中 英 关键字也很精准。搜索韩文暂时先用了我自己的独立丐版实现!
总之,平时使用 color-rg 的时间是越来越多了!真的是越来越习惯、喜欢用了!
今天推送的这个补丁主要新增了两个功能:
- 增加了多行搜索: 如果用
find-file.*\n(goto-char
这样的正则搜索, 可以搜索到第一行是 find-file 并且第二行是 goto-char 的代码块, 以前要把 find-file 的地方找出来然后人工去找匹配的代码块, 对于语义搜索非常方便 - 增加了color-rg-show-lines-before-match 和 color-rg-show-lines-after-match 这两个选项, 对应的是 rg 的 -A NUM 和 -B NUM 两个选项, 这两个选项的好处是可以直接在搜索结果的页面内显示上下文
感谢大佬,这个好顶赞。元旦的时候本来想研究一下这个以及替换的改进
替换在isearch和vscode里都支持case sensitive以及capture group的变量。等我有时间了一定(逃
我仔细看了看search跟replace的实现,好像是在color-rg的buffer里直接调用了query-replace-regexp
?要实现capture group感觉要略大改?毕竟pcre跟emacs regex还是很多不同的,虽然是可以用 pcre2el,但是搜出来的不保证可以替换。 @manateelazycat
啥意思,没看懂
我意思是如果要实现vscode那样方便的替换,可能要绕开emacs的API。这工作量比我想象的要大不少。
在color rg现在的实现里做capture group的搜索替换会碰到两个正则表达式的语法不同的问题。例如我们用pcre在rg 里搜索color-rg-(\w+)-(.*)
,目标是把匹配项替换成color-rg-\u$2$1
,现在因为color-rg是用了emacs的query-replace-regexp
去实现替换的,其实不太好改。
首先是pcre的语法要改成emacs regex color-rg-\([[:alnum:]]+\)-\(.*\)
,其次$1
要改成\1
用pcre2el好像能解决一部分问题。但是pcre跟emacs regex不能一一对应,例如替换上emacs就不支持\u
\l
这样的modifier
感觉还是要保存好rg的匹配结果并在那个基础上去实现这个功能
;; color-rg/color-rg.el:1305
(defun color-rg-replace-all-matches ()
"Replace all matched results."
(interactive)
(save-excursion
(let (changed-line-number)
(let ((inhibit-message t)) ; don't flush to echo area when apply changed, optimise for color-rg
(with-current-buffer color-rg-buffer
(let* ((search-keyword (color-rg-search-keyword color-rg-cur-search))
(replace-text (read-string (format "Replace '%s' all matches with: " search-keyword) search-keyword)))
(color-rg-switch-to-edit-mode)
(if (color-rg-search-literal color-rg-cur-search)
(query-replace search-keyword replace-text nil (point-min) (point-max))
(query-replace-regexp search-keyword replace-text nil (point-min) (point-max)))
(setq changed-line-number (length color-rg-changed-lines))
(color-rg-apply-changed)
(color-rg-switch-to-view-mode)
(when (> changed-line-number 0)
(setf (color-rg-search-keyword color-rg-cur-search) replace-text)))))
(message "Replace %s lines" changed-line-number))))
从替换角度都能做,只是emacs的正则确实不一样,我估计你要适应一下,如果做正则对接,我不知道有没有这样的库。
我在使用 color-rg 进行查找修改的操作时发现两个不符合预期的行为:
- 如果设置选项 kill-whole-line 为 t ,则应用修改后会删除断行(\n),导致上下两行连在一起
- 如果删除在 org-mode 的 head line 里面,会把整个 head 及其下面的内容一起删掉
好像跟 color-rg-apply-changed 用 kill-line 来实现应用改动有关。 提了 issue ,可以看看吗?
第一个问题我推送了补丁 Make sure 'kill-whole-line' is nil when kill line in color-rg. · manateelazycat/color-rg@1bb68a2 · GitHub
第二个问题欢迎提交补丁, 我很少用 org-mode, 不太想研究 org-mode 的问题。
filter results 和 color-rg-customized-search 这两个功能都太赞了. 我今晚上一直在找办法怎么 rg 自定义 file list, 并且还可以 filter. 一个小时后总算想到这个, 果然可以.
github提bug吧,最近比较忙