diff options
Diffstat (limited to 'editors/emacs/ra.el')
-rw-r--r-- | editors/emacs/ra.el | 86 |
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 | ||