@@ -10,6 +10,14 @@ M.defaults = {
10
10
},
11
11
}
12
12
13
+ local api = vim .api
14
+ --- @class Remote
15
+ local remote
16
+
17
+ --- @type number ?
18
+ local chan_id
19
+
20
+ local cursor_row , cursor_col
13
21
local should_cache_lines = true
14
22
local cached_lines
15
23
local prev_lazyredraw
@@ -85,6 +93,7 @@ local function add_inline_highlights(line, cached_lns, updated_lines, undo_delet
85
93
-- Observation: when changing "line" to "tes", there should not be an offset (-2)
86
94
-- after changing "lin" to "t" (because we are not modifying the line)
87
95
highlight .column = highlight .column + col_offset
96
+ highlight .hunk = nil
88
97
table.insert (highlights , highlight )
89
98
90
99
if defer then
@@ -176,13 +185,15 @@ end
176
185
-- Expose functions to tests
177
186
M ._preview_across_lines = get_diff_highlights
178
187
179
- local function run_buf_cmd (buf , cmd )
180
- vim .api .nvim_buf_call (buf , function ()
181
- log (function ()
182
- return (" Previewing command: %s (current line = %d)" ):format (cmd , vim .api .nvim_win_get_cursor (0 )[1 ])
183
- end )
184
- vim .cmd (cmd )
188
+ --- @param cmd string
189
+ local function run_cmd (cmd )
190
+ local cursor_pos = api .nvim_win_get_cursor (0 )
191
+ cursor_row , cursor_col = cursor_pos [1 ], cursor_pos [2 ]
192
+
193
+ log (function ()
194
+ return (" Previewing command: %s (l=%d,c=%d)" ):format (cmd , cursor_row , cursor_col )
185
195
end )
196
+ return remote .run_cmd (chan_id , cmd , cursor_row , cursor_col )
186
197
end
187
198
188
199
-- Called when the user is still typing the command or the command arguments
@@ -194,11 +205,11 @@ local function command_preview(opts, preview_ns, preview_buf)
194
205
local args = opts .cmd_args
195
206
local command = opts .command
196
207
197
- local bufnr = vim . api .nvim_get_current_buf ()
208
+ local bufnr = api .nvim_get_current_buf ()
198
209
if should_cache_lines then
199
210
prev_lazyredraw = vim .o .lazyredraw
200
211
vim .o .lazyredraw = true
201
- cached_lines = vim . api .nvim_buf_get_lines (bufnr , 0 , - 1 , false )
212
+ cached_lines = api .nvim_buf_get_lines (bufnr , 0 , - 1 , false )
202
213
should_cache_lines = false
203
214
end
204
215
@@ -207,10 +218,11 @@ local function command_preview(opts, preview_ns, preview_buf)
207
218
local prev_errmsg = vim .v .errmsg
208
219
local visible_line_range = { vim .fn .line (" w0" ), vim .fn .line (" w$" ) }
209
220
221
+ local updated_lines
210
222
if opts .line1 == opts .line2 then
211
- run_buf_cmd ( bufnr , (" %s %s" ):format (command .cmd , args ))
223
+ updated_lines = run_cmd ( (" %s %s" ):format (command .cmd , args ))
212
224
else
213
- run_buf_cmd ( bufnr , (" %d,%d%s %s" ):format (opts .line1 , opts .line2 , command .cmd , args ))
225
+ updated_lines = run_cmd ( (" %d,%d%s %s" ):format (opts .line1 , opts .line2 , command .cmd , args ))
214
226
end
215
227
216
228
vim .v .errmsg = prev_errmsg
@@ -220,12 +232,11 @@ local function command_preview(opts, preview_ns, preview_buf)
220
232
math.max (visible_line_range [2 ], vim .fn .line (" w$" )),
221
233
}
222
234
223
- local updated_lines = vim .api .nvim_buf_get_lines (bufnr , 0 , - 1 , false )
224
235
local set_lines = function (lines )
225
236
-- TODO: is this worth optimizing?
226
- vim . api .nvim_buf_set_lines (bufnr , 0 , - 1 , false , lines )
237
+ api .nvim_buf_set_lines (bufnr , 0 , - 1 , false , lines )
227
238
if preview_buf then
228
- vim . api .nvim_buf_set_lines (preview_buf , 0 , - 1 , false , lines )
239
+ api .nvim_buf_set_lines (preview_buf , 0 , - 1 , false , lines )
229
240
end
230
241
end
231
242
@@ -255,7 +266,7 @@ local function command_preview(opts, preview_ns, preview_buf)
255
266
for _ , hl in ipairs (highlights ) do
256
267
local hl_group = command .hl_groups [hl .kind ]
257
268
if hl_group ~= false then
258
- vim . api .nvim_buf_add_highlight (
269
+ api .nvim_buf_add_highlight (
259
270
bufnr ,
260
271
preview_ns ,
261
272
hl_group ,
285
296
local create_user_commands = function (commands )
286
297
for name , command in pairs (commands ) do
287
298
local args , range
288
- vim . api .nvim_create_user_command (name , function (opts )
299
+ api .nvim_create_user_command (name , function (opts )
289
300
local range_string = range and range
290
301
or (
291
302
opts .range == 2 and (" %s,%s" ):format (opts .line1 , opts .line2 )
@@ -341,7 +352,51 @@ local validate_config = function(config)
341
352
end
342
353
end
343
354
355
+ local create_autocmds = function ()
356
+ local id = api .nvim_create_augroup (" command_preview.nvim" , { clear = true })
357
+
358
+ api .nvim_create_autocmd (" CmdlineEnter" , {
359
+ group = id ,
360
+ callback = function ()
361
+ remote .sync (chan_id )
362
+ end ,
363
+ })
364
+
365
+ -- We need to be able to tell when the command was cancelled so the buffer lines are refetched next time.
366
+ api .nvim_create_autocmd (" CmdLineLeave" , {
367
+ group = id ,
368
+ -- Schedule wrap to run after a potential command execution
369
+ callback = vim .schedule_wrap (function ()
370
+ restore_buffer_state ()
371
+ end ),
372
+ })
373
+
374
+ api .nvim_create_autocmd (" VimLeavePre" , {
375
+ group = id ,
376
+ callback = function ()
377
+ if chan_id then
378
+ vim .fn .chanclose (chan_id )
379
+ end
380
+ end ,
381
+ })
382
+
383
+ api .nvim_create_autocmd ({ " TextChanged" , " TextChangedI" , " BufEnter" }, {
384
+ group = id ,
385
+ callback = remote .on_buffer_updated ,
386
+ })
387
+
388
+ api .nvim_create_autocmd (" BufWritePost" , {
389
+ group = id ,
390
+ callback = remote .on_buffer_saved ,
391
+ })
392
+ end
393
+
344
394
M .setup = function (user_config )
395
+ -- Avoid an infinite loop when invoked from a child process
396
+ if vim .env .LIVECOMMAND_NVIM_SERVER == " 1" then
397
+ return
398
+ end
399
+
345
400
if vim .fn .has (" nvim-0.8.0" ) ~= 1 then
346
401
vim .notify (
347
402
" [live-command] This plugin requires at least Neovim 0.8. Please upgrade your Neovim version." ,
@@ -353,20 +408,16 @@ M.setup = function(user_config)
353
408
local config = vim .tbl_deep_extend (" force" , M .defaults , user_config or {})
354
409
validate_config (config )
355
410
create_user_commands (config .commands )
411
+ remote = require (" live-command.remote" )
356
412
357
- local id = vim .api .nvim_create_augroup (" command_preview.nvim" , { clear = true })
358
- -- We need to be able to tell when the command was cancelled so the buffer lines are refetched next time.
359
- vim .api .nvim_create_autocmd ({ " CmdLineLeave" }, {
360
- group = id ,
361
- -- Schedule wrap to run after a potential command execution
362
- callback = vim .schedule_wrap (function ()
363
- restore_buffer_state ()
364
- end ),
365
- })
413
+ remote .init_rpc (function (id )
414
+ chan_id = id
415
+ end )
416
+ create_autocmds ()
366
417
367
418
M .debug = user_config .debug
368
419
369
- vim . api .nvim_create_user_command (" LiveCommandLog" , function ()
420
+ api .nvim_create_user_command (" LiveCommandLog" , function ()
370
421
local msg = (" live-command log\n ================\n\n %s%s" ):format (
371
422
logs .ERROR and " [ERROR]\n " .. table.concat (logs .ERROR , " \n " ) .. (logs .TRACE and " \n " or " " ) or " " ,
372
423
logs .TRACE and " [TRACE]\n " .. table.concat (logs .TRACE , " \n " ) or " "
@@ -375,6 +426,6 @@ M.setup = function(user_config)
375
426
end , { nargs = 0 })
376
427
end
377
428
378
- M .version = " 1.2.1 "
429
+ M .version = " 1.3.0 "
379
430
380
431
return M
0 commit comments