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