aboutsummaryrefslogtreecommitdiff
path: root/editors/emacs/ra.el
diff options
context:
space:
mode:
Diffstat (limited to 'editors/emacs/ra.el')
-rw-r--r--editors/emacs/ra.el87
1 files changed, 87 insertions, 0 deletions
diff --git a/editors/emacs/ra.el b/editors/emacs/ra.el
new file mode 100644
index 000000000..099f611be
--- /dev/null
+++ b/editors/emacs/ra.el
@@ -0,0 +1,87 @@
1;;; ra.el --- Rust analyzer emacs bindings -*- lexical-binding: t; -*-
2;;; Commentary:
3;;; Small utilities for interacting with Rust analyzer.
4;;; Run
5;;; cargo install --git https://github.com/matklad/rust-analyzer/ ra_cli
6;;; to install the analyzer binary. Then copy-paste the bellow code to
7;;; your `.init.el` and use `ra-extend-selection` and
8;;; `ra-shrink-selection` functions.
9;;; Code:
10
11
12(defvar ra--selections-cache '(0 0 ()))
13(defun ra--cache-tick ()
14 "Get buffer modification count for cache."
15 (nth 0 ra--selections-cache))
16(defun ra--cache-sel ()
17 "Get current selection for cache."
18 (nth 1 ra--selections-cache))
19(defun ra--cache-nth-sel (n)
20 "Get Nth selection."
21 (nth n (nth 2 ra--selections-cache)))
22(defun ra--cache-set-nth-sel (n)
23 "Get Nth selection."
24 (setf (nth 1 ra--selections-cache) n)
25 (nth n (nth 2 ra--selections-cache)))
26
27
28(defun ra-extend-selection ()
29 "Extend START END region to contain the encompassing syntactic construct."
30 (interactive)
31 (let* ((p (point))
32 (m (or (and mark-active (mark)) p))
33 (start (min p m))
34 (end (max p m)))
35 (ra--extend-selection start end)))
36
37
38(defun ra-shrink-selection (start end)
39 "Shrink START END region to contain previous selection."
40 (interactive "r")
41 (ra--freshen-cache start end)
42 (let ((sel-id (ra--cache-sel)))
43 (if (not (= 0 sel-id))
44 (let* ((r (ra--cache-set-nth-sel (- sel-id 1))))
45 (push-mark (nth 0 r) t t)
46 (goto-char (nth 1 r))
47 (setq deactivate-mark nil)))))
48
49; Add this to setup keybinding
50; (require 'rust-mode)
51; (define-key rust-mode-map (kbd "C-w") 'ra-extend-selection)
52; (define-key rust-mode-map (kbd "C-S-w") 'ra-shrink-selection)
53
54
55
56(defun ra--extend-selection (start end)
57 "Extend START END region to contain the encompassing syntactic construct."
58 (ra--freshen-cache start end)
59 (let* ((next-sel-idx (+ 1 (ra--cache-sel)))
60 (r (ra--cache-set-nth-sel next-sel-idx)))
61 (push-mark (nth 0 r) t t)
62 (goto-char (nth 1 r))
63 (setq deactivate-mark nil)))
64
65(defun ra--selections (start end)
66 "Get list of selections for START END from Rust analyzer."
67 (read (with-output-to-string
68 (call-process-region
69 (point-min) (point-max)
70 "ra_cli" nil standard-output nil
71 "extend-selection"
72 (number-to-string start)
73 (number-to-string end)))))
74
75(defun ra--freshen-cache (start end)
76 "Make selection cache up-to-date for current buffer state and START END."
77 (if (not (and
78 (= (buffer-modified-tick) (ra--cache-tick))
79 (equal `(,start ,end) (ra--cache-nth-sel (ra--cache-sel)))))
80 (ra--set-cache start end)))
81
82(defun ra--set-cache (start end)
83 "Set selections cache for current buffer state and START END."
84 (setq ra--selections-cache `(,(buffer-modified-tick) 0 ,(ra--selections start end))))
85
86(provide 'ra)
87;;; ra.el ends here