-
Notifications
You must be signed in to change notification settings - Fork 0
/
boonmee.el
148 lines (123 loc) · 5.14 KB
/
boonmee.el
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
(require 'json)
(defcustom boonmee-idle-time 0.5
"Time after which to query quickinfo at point"
:group 'boonmee
:type 'float)
(defcustom boonmee-command "boonmee"
"The location of the boonmee binary"
:group 'boonmee
:type 'string)
(defcustom boonmee-log-file (make-temp-file "boonmee.log")
"The file name boonmee will log to"
:group 'boonmee
:type 'string)
(defun boonmee-handle-error (resp)
(print "boonmee: error"))
(defun boonmee-handle-definition (resp)
(let* ((data (plist-get resp :data))
(start (plist-get data :start))
(line (plist-get start :line))
(column (plist-get start :offset))
(file (plist-get data :file)))
(find-file file)
(goto-line line)
(move-to-column column)))
(defun boonmee-handle-quickinfo (resp)
(let* ((data (plist-get resp :data))
(display-string (plist-get data :displayString)))
(message display-string)))
(defun boonmee-handle-completion (resp)
(print resp))
(defun boonmee-handle-response (process output)
(ignore-errors
(let* ((json-object-type 'plist)
(resp (json-read-from-string output))
(command (plist-get resp :command))
(success (eq (plist-get resp :success) t)))
(cond
((string= "error" command)
(boonmee-handle-error resp))
((and (string= "definition" command) success)
(boonmee-handle-definition resp))
((and (string= "quickinfo" command) success)
(boonmee-handle-quickinfo resp))
((and (string= "completionInfo" command) success)
(boonmee-handle-completion resp))
((string= "info" command)
(print output))
((not success) nil)
(t (message (concat "boonmee: cannot handle command " command) ))))))
(defun boonmee-init ()
(if (get-process "boonmee")
nil
(let ((proc (start-process "boonmee" "boonmee-out" boonmee-command "-L" boonmee-log-file)))
(print (concat "boonmee: logging to " boonmee-log-file))
(set-process-filter proc 'boonmee-handle-response))))
(defun boonmee-project-root (file)
(when-let ((dir (file-name-directory (directory-file-name file))))
(if (file-exists-p (concat dir "package.json"))
dir
(when (not (string= dir (file-name-directory (directory-file-name dir))))
(boonmee-project-root dir)))))
(defun boonmee-request-id ()
(number-to-string (float-time)))
(defun boonmee-req-file (file project-root)
(if (buffer-modified-p (current-buffer))
(let ((out-file (concat project-root ".boonmee/cache/" (file-name-nondirectory file))))
(make-directory (file-name-directory out-file) :parents)
(write-region (point-min) (point-max) out-file)
out-file)
file))
(defun boonmee-goto-definition ()
(interactive)
(when-let ((file (buffer-file-name))
(root (boonmee-project-root file)))
(let* ((line (string-to-number (format-mode-line "%l")))
(offset (string-to-number (format-mode-line "%c")))
(req-id (boonmee-request-id))
(req-file (boonmee-req-file file root))
(args (list :file req-file :line line :offset offset :projectRoot root))
(req (json-encode (list :command "definition" :type "request" :requestId req-id :arguments args))))
(process-send-string "boonmee" (concat req "~\n")))))
(defun boonmee-quickinfo ()
(interactive)
(when-let* ((file (buffer-file-name))
(root (boonmee-project-root file)))
(let* ((line (string-to-number (format-mode-line "%l")))
(offset (string-to-number (format-mode-line "%c")))
(req-id (boonmee-request-id))
(req-file (boonmee-req-file file root))
(args (list :file req-file :line line :offset offset :projectRoot root))
(req (json-encode (list :command "quickinfo" :type "request" :requestId req-id :arguments args))))
(process-send-string "boonmee" (concat req "~\n")))))
(defun boonmee-completions ()
(interactive)
(when-let* ((file (buffer-file-name))
(root (boonmee-project-root file)))
(let* ((line (string-to-number (format-mode-line "%l")))
(offset (string-to-number (format-mode-line "%c")))
(req-id (boonmee-request-id))
(req-file (boonmee-req-file file root))
(args (list :file req-file :line line :offset offset :projectRoot root))
(req (json-encode (list :command "completions" :type "request" :requestId req-id :arguments args))))
(process-send-string "boonmee" (concat req "~\n")))))
(defvar boonmee-global-timer nil
"Timer to trigger quickinfo.")
(defun boonmee-intellisense ()
(when (bound-and-true-p boonmee-mode)
(boonmee-quickinfo)))
(defun boonmee-info ()
(let ((req (json-encode (list :command "info" :type "request" :requestId "-1"))))
(process-send-string "boonmee" (concat req "~\n"))))
(define-minor-mode boonmee-mode
"Clojure intellisense"
:group 'boonmee
(when boonmee-mode
(progn
(boonmee-init)
(boonmee-info)
(unless boonmee-global-timer
(setq boonmee-global-timer
(run-with-idle-timer boonmee-idle-time
:repeat 'boonmee-intellisense))))))
(provide 'boonmee-mode)