2626local to_table = function (obj )
2727 obj = type (obj ) == ' string' and { obj } or obj
2828
29- return vim .iter (obj ):map (function (line )
30- return vim .split (line or ' ' , ' \n ' , { trimempty = true })
31- end ):flatten ():totable ()
29+ return vim
30+ .iter (obj )
31+ :map (function (line )
32+ return vim .split (line or ' ' , ' \n ' , { trimempty = true })
33+ end )
34+ :flatten ()
35+ :totable ()
3236end
3337
3438local function remove_indentation (tbl )
4751--- @param highlight string higlight group
4852local show_virtual_text = function (buf , id , text , lnum , position , highlight )
4953 local ns = vim .api .nvim_create_namespace (' Lua-console' )
50- local ext_mark = vim .api .nvim_buf_get_extmark_by_id (0 , ns , id , {})
5154
55+ local ext_mark = vim .api .nvim_buf_get_extmark_by_id (0 , ns , id , {})
5256 if # ext_mark > 0 then vim .api .nvim_buf_del_extmark (0 , ns , id ) end
5357
5458 vim .api .nvim_buf_set_extmark (buf , ns , lnum , 0 , {
@@ -77,8 +81,18 @@ local toggle_help = function(buf)
7781
7882 message =
7983 [[ %s - eval a line or selection, %s - eval buffer, %s - open file, %s - load messages, %s - save console, %s - load console, %s/%s - resize window, %s - toggle help]]
80- message =
81- string.format (message , cm .eval , cm .eval_buffer , cm .open , cm .messages , cm .save , cm .load , cm .resize_up , cm .resize_down , cm .help )
84+ message = string.format (
85+ message ,
86+ cm .eval ,
87+ cm .eval_buffer ,
88+ cm .open ,
89+ cm .messages ,
90+ cm .save ,
91+ cm .load ,
92+ cm .resize_up ,
93+ cm .resize_down ,
94+ cm .help
95+ )
8296
8397 local visible_line = vim .fn .line (' w0' )
8498 show_virtual_text (buf , 2 , message , visible_line - 1 , ' overlay' , ' Comment' )
@@ -155,11 +169,13 @@ local get_last_assignment = function()
155169 for i = lnum - 1 , 0 , - 1 do
156170 line = vim .api .nvim_buf_get_lines (0 , i , i + 1 , false )[1 ]
157171
158- if line :match (' ^%s*' .. last_var .. ' %s*=' ) then break end
172+ if line :match (' ^%s*' .. last_var .. ' %s*,?[^=]- =' ) then break end
159173 offset = offset + 1
160174 end
161175
162- return last_var , last_val , offset
176+ lnum = (lnum - offset ) > 0 and lnum - offset or nil
177+
178+ return last_var , last_val , lnum
163179end
164180
165181--- Pretty prints objects
@@ -191,31 +207,45 @@ end
191207
192208--- @param buf number
193209--- @param lines string[] Text to append to current buffer after current selection
194- local append_current_buffer = function (buf , lines )
210+ --- @param lnum ? number | nil Line number to append from
211+ local append_current_buffer = function (buf , lines , lnum )
195212 if not lines or # lines == 0 then return end
213+ lnum = lnum or vim .fn .line (' .' )
214+
215+ local ns = vim .api .nvim_create_namespace (' Lua-console' )
216+ vim .api .nvim_buf_clear_namespace (buf , ns , 0 , - 1 )
196217
197- local lnum = vim .fn .line (' .' )
198218 local prefix = config .buffer .result_prefix
199219 local empty_results = { ' nil' , ' ' , ' ""' , " ''" }
200220
201221 local virtual_text
202222 local line = lines [# lines ]
203223
204- local last_assigned_var , last_assigned_val , last_assignment_offset = get_last_assignment ()
205- if last_assigned_var then
206- virtual_text = to_string (pretty_print (last_assigned_val ), ' ' , true )
207- show_virtual_text (buf , 3 , prefix .. virtual_text , lnum - last_assignment_offset - 1 , ' eol' , ' Comment' )
224+ local _ , last_assigned_val , last_assignment_lnum = get_last_assignment ()
225+ if last_assignment_lnum then
226+ last_assigned_val = to_string (pretty_print (last_assigned_val ), ' ' , true )
227+ show_virtual_text (buf , 3 , prefix .. last_assigned_val , last_assignment_lnum - 1 , ' eol' , ' Comment' )
208228 end
209229
210230 if vim .tbl_contains (empty_results , line ) then
211231 table.remove (lines )
212232
213- virtual_text = get_line_assignment (vim .fn .getbufline (buf , lnum , lnum )) or line
214- show_virtual_text (buf , 4 , prefix .. virtual_text , lnum - 1 , ' eol' , ' Comment' )
233+ virtual_text = get_line_assignment (vim .fn .getbufline (buf , lnum , lnum )) or line -- ! resets env._last_assignment by calling evaluator
234+
235+ if last_assignment_lnum ~= lnum then
236+ show_virtual_text (buf , 4 , prefix .. virtual_text , lnum - 1 , ' eol' , ' Comment' )
237+ end
215238 end
216239
217240 if # lines == 0 then return end
218241
242+ if # lines == 1 and last_assignment_lnum ~= lnum and not config .buffer .show_one_line_results then
243+ virtual_text = lines [1 ]
244+ show_virtual_text (buf , 4 , prefix .. virtual_text , lnum - 1 , ' eol' , ' Comment' )
245+
246+ return
247+ end
248+
219249 lines [1 ] = prefix .. lines [1 ]
220250 table.insert (lines , 1 , ' ' ) -- insert an empty line
221251
@@ -293,7 +323,7 @@ function get_ctx(buf)
293323 end ,
294324 _reset_last_assignment = function ()
295325 mt ._last_assignment = nil
296- end
326+ end ,
297327 }
298328
299329 lc .ctx [buf ] = env
@@ -314,7 +344,7 @@ function lua_evaluator(lines, ctx)
314344 local lines_with_return_last_line = add_return (lines , # lines )
315345
316346 if not select (2 , load (to_string (lines_with_return_first_line ), ' ' , ' t' , env )) then
317- lines = lines_with_return_first_line
347+ lines = lines_with_return_first_line
318348 elseif not select (2 , load (to_string (lines_with_return_last_line ), ' ' , ' t' , env )) then
319349 lines = lines_with_return_last_line
320350 end
@@ -408,23 +438,23 @@ end
408438--- @param buf number
409439--- @param range number[]
410440--- @return string
411- local function get_lang (buf , range )
412- local pattern = (' ^.*' .. config .external_evaluators .lang_prefix .. ' (.- )%s*$' )
441+ local function get_lang (buf , lnum )
442+ local pattern = (' ^.*' .. config .external_evaluators .lang_prefix .. ' (%w+ )%s*$' )
413443 local line , lang
414444
415- line = vim .api .nvim_buf_get_lines (buf , math.max (0 , range [ 1 ] - 2 ), range [ 2 ] , false )[1 ]
416- lang = line :match (pattern )
445+ line = vim .api .nvim_buf_get_lines (buf , math.max (0 , lnum - 1 ), lnum , false )[1 ]
446+ lang = line and line :match (pattern )
417447 if lang then return lang end
418448
419449 line = vim .api .nvim_buf_get_lines (buf , 0 , 1 , false )[1 ]
420- lang = line :match (pattern )
450+ lang = line and line :match (pattern )
421451 if lang then return lang end
422452
423453 return vim .bo [buf ].filetype
424454end
425455
426- local get_evaluator = function (buf , range )
427- local lang = get_lang (buf , range )
456+ local get_evaluator = function (buf , lnum )
457+ local lang = get_lang (buf , lnum )
428458
429459 if lang == ' ' then
430460 vim .notify (' Plese specify the language to evaluate or set the filetype' , vim .log .levels .WARN )
@@ -440,27 +470,35 @@ end
440470--- @param full ? boolean evaluate full buffer
441471local eval_code_in_buffer = function (buf , full )
442472 buf = buf or vim .fn .bufnr ()
443- local win = vim .fn .bufwinid (buf )
444473
445- if vim .api .nvim_get_mode ().mode == ' V' then vim .api .nvim_input (' <Esc>' ) end
474+ local mode = vim .api .nvim_get_mode ().mode
475+ if mode == ' V' or mode == ' v' then vim .api .nvim_input (' <Esc>' ) end
476+
477+ local v_start , v_end , lines
446478
447- local v_start , v_end
448479 if full then
449480 v_start , v_end = 1 , vim .api .nvim_buf_line_count (buf )
450- else
451- v_start , v_end = vim .fn .line (' .' , win ), vim .fn .line (' v' , win )
481+ elseif mode == ' v' or mode == ' V' then
482+ v_start , v_end = vim .fn .getpos (' .' ), vim .fn .getpos (' v' )
483+ lines = vim .fn .getregion (v_start , v_end , { type = mode })
484+
485+ v_start , v_end = v_start [2 ], v_end [2 ]
486+
452487 if v_start > v_end then
453488 v_start , v_end = v_end , v_start
454489 end
490+ else
491+ v_start = vim .fn .line (' .' )
492+ v_end = v_start
455493 end
456494
457- vim .api . nvim_win_set_cursor ( win , { v_end , 0 } )
495+ vim .fn . cursor ( v_end , 0 )
458496
459- local lines = vim .api .nvim_buf_get_lines (buf , v_start - 1 , v_end , false )
497+ lines = lines or vim .api .nvim_buf_get_lines (buf , v_start - 1 , v_end , false )
460498 lines = remove_empty_lines (lines )
461499 if # lines == 0 then return end
462500
463- local evaluator = get_evaluator (buf , { v_start , v_end } )
501+ local evaluator = get_evaluator (buf , v_start - 1 )
464502 if not evaluator then return end
465503
466504 local result = evaluator (lines )
472510--- Load messages into console
473511local load_messages = function (buf )
474512 local ns = vim .api .nvim_create_namespace (' Lua-console' )
513+ local lnum = vim .fn .line (' .' )
475514
476515 --- This way we catch the output of messages command, in case it was overriden by some other plugin, like Noice
477516 vim .ui_attach (ns , { ext_messages = true }, function (event , entries ) --- @diagnostic disable-line
@@ -484,8 +523,8 @@ local load_messages = function(buf)
484523 if # messages == 0 then return end
485524
486525 vim .schedule (function ()
487- vim . api . nvim_input ( ' <Down> ' ) -- forcing to redraw buffer
488- append_current_buffer ( buf , to_table ( messages ))
526+ append_current_buffer ( buf , to_table ( messages ), lnum )
527+ vim . api . nvim__redraw { flush = true , buf = buf }
489528 end )
490529 end )
491530
0 commit comments