Skip to content

Commit b3abd72

Browse files
committed
Use macro to define vim api functions
1 parent b493dbd commit b3abd72

File tree

4 files changed

+76
-124
lines changed

4 files changed

+76
-124
lines changed

TODO

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[_] Replace run-command!, run-command-async! everywhere
2+
[X] samples
3+
[_] socket-repl plugin
4+
[_] Test socket-repl plugin
5+
[_] Squash, merge branch

sample-plugin-simple/src/sample_plugin/core.clj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
(defn -main
66
[& args]
77
(nvim/connect!)
8-
(nvim/hsplit!)
9-
(let [cur-buf (nvim/get-current-buffer)]
8+
(nvim/vim-command ":new")
9+
(let [cur-buf (nvim/vim-get-current-buffer)]
1010
(nvim/buffer-set-text! cur-buf "Sample plugin was here!")))

sample-plugin/src/sample_plugin/core.clj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@
1212
(fn [msg]
1313
;; Plugin can call back to nvim if it wants to, while
1414
;; its doing its own thing.
15-
(nvim/run-command-async! ":echo 'incrementing'"
15+
(nvim/vim-command-async ":echo 'incrementing'"
1616
(fn [_] nil))
1717
(swap! x inc)
1818
@x)))
1919

2020
;; Stay alive for a minute!
2121
(dotimes [n 60]
2222
(if (= 0 (mod n 10))
23-
(nvim/run-command! (str ":echo 'plugin alive for " n " seconds.'")))
23+
(nvim/vim-command (str ":echo 'plugin alive for " n " seconds.'")))
2424
(Thread/sleep 1000))
2525

2626
;; Let nvim know we're shutting down.
27-
(nvim/run-command! ":let g:is_running=0")
28-
(nvim/run-command! ":echo 'plugin stopping.'"))
27+
(nvim/vim-command ":let g:is_running=0")
28+
(nvim/vim-command ":echo 'plugin stopping.'"))

src/neovim_client/nvim.clj

Lines changed: 65 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(ns neovim-client.nvim
2-
(:require [clojure.string :as str]
2+
(:require [clojure.core.async :as async]
3+
[clojure.string :as str]
34
[neovim-client.message :as message :refer [->request-msg]]
45
[neovim-client.rpc :as rpc]))
56

@@ -10,143 +11,89 @@
1011

1112
;; TODO - Check for connection, before allowing commands?
1213

13-
(defn send-message!
14-
[vim-command & args]
15-
(rpc/send-message! (->request-msg vim-command (or args []))))
16-
17-
(defn run-command! [cmd-str] (send-message! "vim_command" cmd-str))
18-
19-
(defn run-command-async!
20-
[cmd-str f]
21-
(rpc/send-message-async! (->request-msg "vim_command" [cmd-str]) f))
22-
23-
(defn get-var-async
24-
[var-name f]
25-
(rpc/send-message-async! (->request-msg "vim_get_var" [var-name]) f))
26-
27-
(defn get-vvar-async
28-
[var-name f]
29-
(rpc/send-message-async! (->request-msg "vim_get_vvar" [var-name]) f))
30-
31-
(defn call-function-async
32-
[f-name args f]
33-
(rpc/send-message-async! (->request-msg "vim_call_function" [f-name args]) f))
34-
35-
(defn get-api-info [] (send-message! "vim_get_api_info"))
14+
(defmacro defvim
15+
[fn-name vim-command & args]
16+
`(do
17+
(defn ~(symbol (str fn-name "-async"))
18+
[~@args f#]
19+
(rpc/send-message-async!
20+
(message/->request-msg ~vim-command [~@args])
21+
f#))
22+
(defn ~fn-name
23+
[~@args]
24+
(rpc/send-message!
25+
(message/->request-msg ~vim-command [~@args])))))
26+
27+
;; :let g:foo=1
28+
;; (vim-get-var-async "foo" println) => 1
29+
(defvim buffer-get-line "buffer_get_line" buffer line-num)
30+
(defvim buffer-line-count "buffer_line_count" buffer)
31+
(defvim buffer-get-name "buffer_get_name" buffer)
32+
(defvim buffer-set-line "buffer_set_line" buffer line-num line)
33+
(defvim vim-call-function "vim_call_function" f-name args)
34+
(defvim vim-command "vim_command" cmd-str)
35+
(defvim vim-get-api-info "vim_get_api_info")
36+
(defvim vim-get-current-buffer "vim_get_current_buffer")
37+
(defvim vim-get-current-line "vim_get_current_line")
38+
(defvim vim-get-current-window "vim_get_current_window")
39+
(defvim vim-get-buffers "vim_get_buffers")
40+
(defvim vim-get-var "vim_get_var" var-name)
41+
(defvim vim-get-vvar "vim_get_vvar" var-name)
42+
(defvim vim-get-windows "vim_get_windows")
43+
(defvim vim-set-current-line "vim_set_current_line" line)
44+
(defvim window-get-buffer "window_get_buffer" window)
45+
(defvim window-get-cursor "window_get_cursor" window)
46+
47+
;; Special cases
48+
;; TODO give x, y correct names
49+
(defvim buffer-get-line-slice* "buffer_get_line_slice" buffer start end x y)
50+
(defn buffer-get-line-slice
51+
[buffer start end]
52+
(buffer-get-line-slice* buffer start end true true))
53+
(defn buffer-get-line-slice-async
54+
[buffer start end f]
55+
(buffer-get-line-slice*-async buffer start end true true f))
3656

37-
(defn get-api-info-async [f]
38-
(rpc/send-message-async! (->request-msg "vim_get_api_info" []) f))
57+
;; ***** Custom *****
3958

40-
;; ***** Cursor *****
59+
;; TODO - fix custom names, move to another ns?
4160

42-
(declare get-current-window-async)
4361
(defn get-cursor-location-async
4462
"Gets the cursor's current position as a tuple (row, col) asynchronously."
4563
[f]
46-
(get-current-window-async
47-
(fn [window]
48-
(rpc/send-message-async!
49-
(->request-msg "window_get_cursor" [window]) f))))
50-
51-
;; ***** Lines *****
52-
53-
(defn get-current-line [] (send-message! "vim_get_current_line"))
54-
55-
(defn set-current-line! [line] (send-message! "vim_set_current_line" line))
56-
57-
;; ***** Windows *****
58-
59-
(defn get-current-window-async
60-
"Gets a reference to the current window asynchronously."
61-
[f]
62-
(rpc/send-message-async! (->request-msg "vim_get_current_window" []) f))
63-
64-
;; ***** Buffers *****
65-
66-
(defn get-current-buffer
67-
"Returns a reference to the current buffer."
68-
[]
69-
(send-message! "vim_get_current_buffer"))
70-
71-
(declare buffer-get-text)
72-
(defn get-current-buffer-async
73-
"Like `get-current-buffer`, but async."
74-
[f]
75-
(rpc/send-message-async! (->request-msg "vim_get_current_buffer" []) f))
76-
77-
(defn get-buffers [] (send-message! "vim_get_buffers"))
78-
79-
(defn get-buffer-line-count [buffer] (send-message! "buffer_line_count" buffer))
80-
(defn get-buffer-line-count-async
81-
"Like `get-buffer-line-count but async.
82-
83-
`f` callback function invoked with the buffer line count as an argument."
84-
[buffer f]
85-
(rpc/send-message-async! (->request-msg "buffer_line_count" [buffer]) f))
86-
87-
(defn buffer-set-line!
88-
[buffer line-num line]
89-
(send-message! "buffer_set_line" buffer line-num line))
90-
91-
(defn buffer-set-line-async!
92-
([buffer line-num line]
93-
(buffer-set-line-async! buffer line-num line identity))
94-
([buffer line-num line f]
95-
(rpc/send-message-async! (->request-msg "buffer_set_line"
96-
[buffer line-num line]) f)))
97-
98-
(defn buffer-get-line
99-
[buffer line-num]
100-
(send-message! "buffer_get_line" buffer line-num))
101-
102-
(defn buffer-get-line-async
103-
[buffer line-num f]
104-
(rpc/send-message-async! (->request-msg "buffer_get_line"
105-
[buffer line-num]) f))
106-
107-
(defn buffer-get-lines-async
108-
[buffer start end f]
109-
(rpc/send-message-async! (->request-msg "buffer_get_line_slice"
110-
[buffer start end true true]) f))
111-
112-
;; ***** Experimental *****
64+
(vim-get-current-window-async #(window-get-cursor-async % f)))
11365

11466
(defn buffer-update-lines!
11567
"Alter each line of the buffer using the function."
11668
[buffer update-fn]
117-
(doseq [n (range (get-buffer-line-count buffer))]
118-
(buffer-get-line-async buffer n #(buffer-set-line-async! buffer n
119-
(update-fn %)))))
120-
121-
;; TODO: Do this with `get-buffer-line-slice`
122-
(defn buffer-get-text
123-
"Get the buffer's text as a single string."
124-
[buffer]
125-
(let [buf-size (get-buffer-line-count buffer)
126-
lines (map (partial buffer-get-line buffer) (range buf-size))]
127-
(str/join "\n" lines)))
128-
69+
(doseq [n (range (buffer-line-count buffer))]
70+
(buffer-get-line-async buffer n #(buffer-set-line-async buffer n
71+
(update-fn %)
72+
identity))))
12973
(defn get-current-buffer-text-async
13074
"Convenience function to get the current buffer's text asynchronously."
13175
[f]
132-
(get-current-buffer-async
133-
(fn [buffer] (buffer-get-lines-async
76+
(vim-get-current-buffer-async
77+
(fn [buffer] (buffer-get-line-slice-async
13478
buffer 0 -1 (fn [lines] (f (str/join "\n" lines)))))))
13579

136-
;; TODO - make it wipe out text in the buffer after the last line of new text.
13780
(defn buffer-set-text!
81+
"Replace the contents of the buffer with `text`."
13882
[buffer text]
13983
(let [lines (str/split text #"\n")]
14084
(doseq [n (range (count lines))]
141-
(buffer-set-line! buffer n (nth lines n)))))
142-
143-
(defn hsplit! [] (run-command! "new"))
144-
(defn vsplit! [] (run-command! "vnew"))
85+
(buffer-set-line buffer n (nth lines n)))))
14586

14687
(defn get-current-word-async
14788
"Get the current word asynchronously."
14889
[f]
149-
(call-function-async "expand" ["<cword>"] f))
150-
151-
;; TODO
152-
;; the rest of the functions in (get_api_info)
90+
(vim-call-function-async "expand" ["<cword>"] f))
91+
92+
(defn buffer-visible?-async
93+
"Returns a channel which will contain true if the buffer is currently
94+
visible."
95+
[buffer-name]
96+
(async/go
97+
(let [visible-buffers (map (comp buffer-get-name window-get-buffer)
98+
(vim-get-windows))]
99+
((set visible-buffers) buffer-name))))

0 commit comments

Comments
 (0)