This page looks best with JavaScript enabled

Enhance Emacs rg.el with which-function support

 ·  ☕ 2 min read

I frequently use rg.el in my daily work. While rg only displays the content of
the target lines, I want Emacs’ rg.el to tell me what the which-function is
for the target content after searching. Therefore, I modified which-function
and made some hacks to rg.el.

The effect is as follows:

The Source code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  (defun shorten-string (str)
	(if (> (length str) 30)
		(concat (substring str 0 15) "…" (substring str -14))
	  str))

  (defun exec/rg-hack ()
	(interactive)
	(let* ((msg (get-text-property (point) 'compilation-message)))
	  (if msg
		  (let* ((loc (compilation--message->loc msg))
                 (file (caar (compilation--loc->file-struct loc)))
                 (line (compilation--loc->line loc))
                 (col (compilation--loc->col loc))
                 (function_name
				  (exec/lsp-which-function file line col))
                 (text
				  (format "%-30s │"
						  (shorten-string (or function_name ""))))
                 (ov
				  (make-overlay (line-beginning-position)
								(1+ (line-beginning-position))
								nil
								t)))

			(overlay-put
             ov 'before-string
             (propertize text 'face 'font-lock-property-name-face))
			(overlay-put ov 'evaporate t)))))

  (defun exec/rg-hint-all (&rest args)
	(interactive)
	(sit-for 0.01)
	(with-current-buffer (rg-buffer-name)
	  (defvar-local rg-hack-lines 1)
	  (while (and (not (eobp)) (< rg-hack-lines 300))
		(exec/rg-hack)
		(forward-line)
		(setq-local rg-hack-lines (1+ rg-hack-lines))
		(if (= (% rg-hack-lines 10) 0)
			(sit-for 0.01)))
	  (goto-char (point-min)))

	(unless exec/which-function-current-buffer-already-exist
	  (if exec/which-function-last-buffer-name
		  (kill-buffer (find-file-noselect exec/which-function-last-buffer-name))
		)
	  )
	(setq-local exec/which-function-current-buffer-already-exist nil)
	(setq-local exec/which-function-last-buffer-name "")
	)


  (defvar-local exec/which-function-last-buffer-name "")
  (defvar-local exec/which-function-current-buffer-already-exist nil)
  (defun exec/lsp-which-function (file line column)
	(unless (eq file exec/which-function-last-buffer-name)
	  (unless exec/which-function-current-buffer-already-exist
		(if exec/which-function-last-buffer-name
			(kill-buffer (find-file-noselect exec/which-function-last-buffer-name))
		  )
		)
	  (setq-local exec/which-function-current-buffer-already-exist (get-file-buffer file))
	  (setq-local exec/which-function-last-buffer-name file))
	(let ((buffer (find-file-noselect file)))
	  (with-current-buffer buffer
		(goto-line line)
		(move-to-column column)
		(which-function))))

  (defun exec/setup-rg-hint (&rest args)
	(add-to-list 'compilation-finish-functions 'exec/rg-hint-all))


  (add-hook 'rg-mode-hook 'exec/setup-rg-hint))
Share on

EXEC
WRITTEN BY
EXEC
Eval EXEC