Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lua/lua-console/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local default_config = {
autosave = true, -- autosave on console hide / close
load_on_start = true, -- load saved session on start
preserve_context = true, -- preserve results between evaluations
print_one_line_results = true,
},
window = {
relative = 'editor',
Expand All @@ -16,7 +17,7 @@ local default_config = {
title = ' Lua console ',
title_pos = 'left',
height = 0.6, -- percentage of main window
zindex = 1,
zindex = 100,
},
mappings = {
toggle = '`',
Expand Down
30 changes: 17 additions & 13 deletions lua/lua-console/injections.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,36 @@ M.set_highlighting = function()
local lang_prefix = config.external_evaluators.lang_prefix
local lang_pattern = ('^%s([^\\n]-)\\n.+$'):format(lang_prefix)

vim.treesitter.query.add_directive('deindent!', function(_, _, _, predicate, metadata) -- remove indentaion in the region
local capture_id = predicate[2]
if not metadata[capture_id].range then return end
vim.treesitter.query.add_directive(
'deindent!',
function(_, _, _, predicate, metadata) -- remove indentaion in the region
local capture_id = predicate[2]
if not metadata[capture_id].range then return end

metadata[capture_id].range[2] = tonumber(predicate[3]) -- set indent col to 0
end, { all = true, force = true })
metadata[capture_id].range[2] = tonumber(predicate[3]) -- set indent col to 0
end,
{ all = true, force = true }
)

local function extend_query(query)
local extended = ''
vim.tbl_map(function(path)
extended = extended .. io.open(path):read("*a") .. '\n'
extended = extended .. io.open(path):read('*a') .. '\n'
end, vim.treesitter.query.get_files('lua', 'injections'))

return extended .. query
end

local query = ([[ ;query
local query_string = ([[ ;query
((string_content) @injection.language @injection.content
(#lua-match? @injection.language "^@1")
(#gsub! @injection.language "@2" "%1")
(#offset! @injection.content 1 0 0 0)
(#deindent! @injection.content 0))
(#lua-match? @injection.language "^@1")
(#gsub! @injection.language "@2" "%1")
(#offset! @injection.content 1 0 0 0)
(#deindent! @injection.content 0))
]]):gsub('@1', lang_prefix):gsub('@2', lang_pattern)

query = extend_query(query)
vim.treesitter.query.set('lua', 'injections', query)
query_string = extend_query(query_string)
vim.treesitter.query.set('lua', 'injections', query_string)
end

return M
2 changes: 1 addition & 1 deletion lua/lua-console/mappings.lua
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ M.set_evaluator_mappings = function(buf, toggle)
callback = function()
utils.eval_code_in_buffer(buf)
end,
}, { 'n', 'v' })
}, { 'n', 'x' })

set_map(buf, m.eval_buffer, {
desc = 'Eval code in current buffer',
Expand Down
109 changes: 74 additions & 35 deletions lua/lua-console/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ end
local to_table = function(obj)
obj = type(obj) == 'string' and { obj } or obj

return vim.iter(obj):map(function(line)
return vim.split(line or '', '\n', { trimempty = true })
end):flatten():totable()
return vim
.iter(obj)
:map(function(line)
return vim.split(line or '', '\n', { trimempty = true })
end)
:flatten()
:totable()
end

local function remove_indentation(tbl)
Expand All @@ -47,8 +51,8 @@ end
---@param highlight string higlight group
local show_virtual_text = function(buf, id, text, lnum, position, highlight)
local ns = vim.api.nvim_create_namespace('Lua-console')
local ext_mark = vim.api.nvim_buf_get_extmark_by_id(0, ns, id, {})

local ext_mark = vim.api.nvim_buf_get_extmark_by_id(0, ns, id, {})
if #ext_mark > 0 then vim.api.nvim_buf_del_extmark(0, ns, id) end

vim.api.nvim_buf_set_extmark(buf, ns, lnum, 0, {
Expand Down Expand Up @@ -77,8 +81,18 @@ local toggle_help = function(buf)

message =
[[%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]]
message =
string.format(message, cm.eval, cm.eval_buffer, cm.open, cm.messages, cm.save, cm.load, cm.resize_up, cm.resize_down, cm.help)
message = string.format(
message,
cm.eval,
cm.eval_buffer,
cm.open,
cm.messages,
cm.save,
cm.load,
cm.resize_up,
cm.resize_down,
cm.help
)

local visible_line = vim.fn.line('w0')
show_virtual_text(buf, 2, message, visible_line - 1, 'overlay', 'Comment')
Expand Down Expand Up @@ -155,11 +169,13 @@ local get_last_assignment = function()
for i = lnum - 1, 0, -1 do
line = vim.api.nvim_buf_get_lines(0, i, i + 1, false)[1]

if line:match('^%s*' .. last_var .. '%s*=') then break end
if line:match('^%s*' .. last_var .. '%s*,?[^=]-=') then break end
offset = offset + 1
end

return last_var, last_val, offset
lnum = (lnum - offset) > 0 and lnum - offset or nil

return last_var, last_val, lnum
end

---Pretty prints objects
Expand Down Expand Up @@ -191,31 +207,45 @@ end

---@param buf number
---@param lines string[] Text to append to current buffer after current selection
local append_current_buffer = function(buf, lines)
---@param lnum? number|nil Line number to append from
local append_current_buffer = function(buf, lines, lnum)
if not lines or #lines == 0 then return end
lnum = lnum or vim.fn.line('.')

local ns = vim.api.nvim_create_namespace('Lua-console')
vim.api.nvim_buf_clear_namespace(buf, ns, 0, -1)

local lnum = vim.fn.line('.')
local prefix = config.buffer.result_prefix
local empty_results = { 'nil', '', '""', "''" }

local virtual_text
local line = lines[#lines]

local last_assigned_var, last_assigned_val, last_assignment_offset = get_last_assignment()
if last_assigned_var then
virtual_text = to_string(pretty_print(last_assigned_val), '', true)
show_virtual_text(buf, 3, prefix .. virtual_text, lnum - last_assignment_offset - 1, 'eol', 'Comment')
local _, last_assigned_val, last_assignment_lnum = get_last_assignment()
if last_assignment_lnum then
last_assigned_val = to_string(pretty_print(last_assigned_val), '', true)
show_virtual_text(buf, 3, prefix .. last_assigned_val, last_assignment_lnum - 1, 'eol', 'Comment')
end

if vim.tbl_contains(empty_results, line) then
table.remove(lines)

virtual_text = get_line_assignment(vim.fn.getbufline(buf, lnum, lnum)) or line
show_virtual_text(buf, 4, prefix .. virtual_text, lnum - 1, 'eol', 'Comment')
virtual_text = get_line_assignment(vim.fn.getbufline(buf, lnum, lnum)) or line -- ! resets env._last_assignment by calling evaluator

if last_assignment_lnum ~= lnum then
show_virtual_text(buf, 4, prefix .. virtual_text, lnum - 1, 'eol', 'Comment')
end
end

if #lines == 0 then return end

if #lines == 1 and last_assignment_lnum ~= lnum and not config.buffer.show_one_line_results then
virtual_text = lines[1]
show_virtual_text(buf, 4, prefix .. virtual_text, lnum - 1, 'eol', 'Comment')

return
end

lines[1] = prefix .. lines[1]
table.insert(lines, 1, '') -- insert an empty line

Expand Down Expand Up @@ -293,7 +323,7 @@ function get_ctx(buf)
end,
_reset_last_assignment = function()
mt._last_assignment = nil
end
end,
}

lc.ctx[buf] = env
Expand All @@ -314,7 +344,7 @@ function lua_evaluator(lines, ctx)
local lines_with_return_last_line = add_return(lines, #lines)

if not select(2, load(to_string(lines_with_return_first_line), '', 't', env)) then
lines = lines_with_return_first_line
lines = lines_with_return_first_line
elseif not select(2, load(to_string(lines_with_return_last_line), '', 't', env)) then
lines = lines_with_return_last_line
end
Expand Down Expand Up @@ -408,23 +438,23 @@ end
---@param buf number
---@param range number[]
---@return string
local function get_lang(buf, range)
local pattern = ('^.*' .. config.external_evaluators.lang_prefix .. '(.-)%s*$')
local function get_lang(buf, lnum)
local pattern = ('^.*' .. config.external_evaluators.lang_prefix .. '(%w+)%s*$')
local line, lang

line = vim.api.nvim_buf_get_lines(buf, math.max(0, range[1] - 2), range[2], false)[1]
lang = line:match(pattern)
line = vim.api.nvim_buf_get_lines(buf, math.max(0, lnum - 1), lnum, false)[1]
lang = line and line:match(pattern)
if lang then return lang end

line = vim.api.nvim_buf_get_lines(buf, 0, 1, false)[1]
lang = line:match(pattern)
lang = line and line:match(pattern)
if lang then return lang end

return vim.bo[buf].filetype
end

local get_evaluator = function(buf, range)
local lang = get_lang(buf, range)
local get_evaluator = function(buf, lnum)
local lang = get_lang(buf, lnum)

if lang == '' then
vim.notify('Plese specify the language to evaluate or set the filetype', vim.log.levels.WARN)
Expand All @@ -440,27 +470,35 @@ end
---@param full? boolean evaluate full buffer
local eval_code_in_buffer = function(buf, full)
buf = buf or vim.fn.bufnr()
local win = vim.fn.bufwinid(buf)

if vim.api.nvim_get_mode().mode == 'V' then vim.api.nvim_input('<Esc>') end
local mode = vim.api.nvim_get_mode().mode
if mode == 'V' or mode == 'v' then vim.api.nvim_input('<Esc>') end

local v_start, v_end, lines

local v_start, v_end
if full then
v_start, v_end = 1, vim.api.nvim_buf_line_count(buf)
else
v_start, v_end = vim.fn.line('.', win), vim.fn.line('v', win)
elseif mode == 'v' or mode == 'V' then
v_start, v_end = vim.fn.getpos('.'), vim.fn.getpos('v')
lines = vim.fn.getregion(v_start, v_end, { type = mode })

v_start, v_end = v_start[2], v_end[2]

if v_start > v_end then
v_start, v_end = v_end, v_start
end
else
v_start = vim.fn.line('.')
v_end = v_start
end

vim.api.nvim_win_set_cursor(win, { v_end, 0 })
vim.fn.cursor(v_end, 0)

local lines = vim.api.nvim_buf_get_lines(buf, v_start - 1, v_end, false)
lines = lines or vim.api.nvim_buf_get_lines(buf, v_start - 1, v_end, false)
lines = remove_empty_lines(lines)
if #lines == 0 then return end

local evaluator = get_evaluator(buf, { v_start, v_end })
local evaluator = get_evaluator(buf, v_start - 1)
if not evaluator then return end

local result = evaluator(lines)
Expand All @@ -472,6 +510,7 @@ end
---Load messages into console
local load_messages = function(buf)
local ns = vim.api.nvim_create_namespace('Lua-console')
local lnum = vim.fn.line('.')

---This way we catch the output of messages command, in case it was overriden by some other plugin, like Noice
vim.ui_attach(ns, { ext_messages = true }, function(event, entries) ---@diagnostic disable-line
Expand All @@ -484,8 +523,8 @@ local load_messages = function(buf)
if #messages == 0 then return end

vim.schedule(function()
vim.api.nvim_input('<Down>') -- forcing to redraw buffer
append_current_buffer(buf, to_table(messages))
append_current_buffer(buf, to_table(messages), lnum)
vim.api.nvim__redraw { flush = true, buf = buf }
end)
end)

Expand Down
11 changes: 10 additions & 1 deletion spec/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@ local inspect = require('inspect')

local log = function(...) --luacheck: ignore
local caller = debug.getinfo(2)
local caller_path = caller.short_src

local time = os.date('*t', os.time())
time.min, time.sec = 0, 0

---@diagnostic disable-next-line
time = os.time() - os.time(time)

if caller_path then
local path_dirs = vim.split(vim.fs.dirname(caller_path), '/')
caller_path = path_dirs[#path_dirs] .. '/' .. vim.fs.basename(caller_path)
end

local result = ('\nLOG #%s (%s:%s:%s) => '):format(
time,
caller_path or '',
caller.name or '',
caller.short_src or '',
caller.currentline or ''
)

local nargs = select('#', ...)
local var_no = ''

Expand Down
11 changes: 6 additions & 5 deletions spec/spec_helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ end
M.to_string = function(tbl)
tbl = tbl or {}

if type(tbl) == 'string' then tbl = { tbl } end
if type(tbl) ~= 'table' then tbl = { tbl } end
return table.concat(tbl, '\n'):clean()
end

Expand Down Expand Up @@ -61,17 +61,18 @@ M.send_keys = function(keys)
end

M.get_virtual_text = function(buf, line_start, line_end)
local ns = vim.api.nvim_create_namespace('Lua-console')
local ids = vim.api.nvim_buf_get_extmarks(buf, ns, { line_start or 0, 0 }, { line_end or 0, -1 }, {})
local ids = vim.api.nvim_buf_get_extmarks(buf, -1, { line_start or 0, 0 }, { line_end or -1, -1 }, { details = true })

if vim.tbl_isempty(ids) then
_G.LOG('No extmarks found')
return ''
end

local mark = vim.api.nvim_buf_get_extmark_by_id(buf, ns, ids[1][1], { details = true })
local marks = vim.tbl_map(function(mark)
return mark[4].virt_text[1][1]
end, ids)

return mark[3].virt_text[1][1]
return marks
end

---Collects paths for nested keys
Expand Down
3 changes: 3 additions & 0 deletions spec/unit/mappings_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe('lua-console.nvim - mappings', function()
buffer = {
load_on_start = false,
save_path = vim.fn.stdpath('state') .. '/lua-console-test.lua',
show_one_line_results = true,
},
}

Expand Down Expand Up @@ -264,6 +265,7 @@ describe('lua-console.nvim - mappings', function()
utils.attach_toggle(other_buf)
end)

--TODO: finish spec
it('cretes mappings for attached buffer', function()
-- code
end)
Expand Down Expand Up @@ -328,6 +330,7 @@ describe('lua-console.nvim - mappings', function()
-- code
end)

--TODO: finish spec
it('removes mappings for dettached buffer', function()
-- code
end)
Expand Down
Loading
Loading