This changes command names to be prefixed with `:BQN` for better
discovery (completion in command mode).
Then this introduces plug mappings and automatically maps them to
- `<CR>` evals, till the line (or range), as previously
- `<leader>bf` evals the whole file
- `<leader>bc` clears output after the line (or range)
---
The changes as we've discussed before.
I didn't map `<plug>(bqn_clear_file)` here as I'm not sure what would be the
best key for that, was thinking of `<leader>bcf` but then it introduces a delay
when you press `<leader>bc` as neovim waits for the possible continuation.
Once we see an error returned from CBQN we set diagnostics via
`vim.diagnostic` API. This helps to see which line contains the error.
The diagnostic set is "ephemeral" as it will be cleared (or replaced
with another one) once we eval another piece of code.
---
Let me know what you think! I've found this useful to quickly find an offending
line. Would be cool if CBQN reported a column as well...
I think it's worth having. Usually I get the errors on the same line I'm
evaluating so I had not thought about needing this info but as it is
availabe, I don't see why we wouldn't do this.
Maybe the column could be calculated from the "arrows" CBQN draws into
the error message. Or then we could submit a patch to CBQN :) Anyway, I
think for now this is good as-is.
lua/bqn.lua | 40 +++++++++++++++++++++++++++++++++-------
1 file changed, 33 insertions(+), 7 deletions(-)
diff --git a/lua/bqn.lua b/lua/bqn.lua
index 33b95c8..fcd3ee8 100644
--- a/lua/bqn.lua+++ b/lua/bqn.lua
@@ -1,6 +1,15 @@
local ns = vim.api.nvim_create_namespace('bqnout')
+local function enumerate(it)+ local idx, v = 0, nil+ return function()+ v, idx = it(), idx + 1+ return v, idx+ end+end+function clearBQN(from, to)
+ vim.diagnostic.reset(ns, 0) vim.api.nvim_buf_clear_namespace(0, ns, from, to)
end
@@ -45,20 +54,37 @@ function evalBQN(from, to, pretty)
local executable = assert(io.popen(cmd))
local output = executable:read('*all')
+ local error = nil local lines = {}
- local line_count = 0- local is_error = nil- for line in output:gmatch("[^\n]+") do- if is_error == nil then- is_error = line:find("^Error:") ~= nil+ for line, lnum in enumerate(output:gmatch("[^\n]+")) do+ if lnum == 1 then+ local message = line:gsub("^Error: (.*)", "%1")+ if message ~= line then+ error = {message=message}+ end+ end+ if error ~= nil and lnum == 2 then+ local lnum = line:gsub("^%(%-p%):(%d+):", "%1")+ error.lnum = tonumber(lnum) + from - 1 end
local hl = 'bqnoutok'
- if is_error then hl = 'bqnouterr' end+ if error ~= nil then hl = 'bqnouterr' end table.insert(lines, {{' ' .. line, hl}})
- line_count = line_count + 1 end
table.insert(lines, {{' ', 'bqnoutok'}})
+ -- Reset and show diagnostics+ vim.diagnostic.reset(ns, 0)+ if error ~= nil and error.lnum ~= nil then+ vim.diagnostic.set(ns, 0, {{+ message=error.message,+ lnum=error.lnum,+ col=0,+ severity=vim.diagnostic.severity.ERROR,+ source='BQN',+ }})+ end+ -- Compute `cto` (clear to) position by looking forward from `to` till we
-- find first non-empty line. We do this so we clear all "orphaned" virtual
-- line blocks (which correspond to already deleted lines).
--
2.30.2