chore: more typing, cleanup, docs on index hell

This commit is contained in:
əlemi 2024-08-23 00:59:13 +02:00
parent 399aaad45f
commit 13e6182ce0
Signed by: alemi
GPG key ID: A4895B84D311642C
4 changed files with 113 additions and 86 deletions

View file

@ -6,16 +6,21 @@ local buffer_id_map = {}
local user_buffer_name = {} local user_buffer_name = {}
local ticks = {} local ticks = {}
---@param name string
local function create(name) local function create(name)
state.workspace:create_buffer(name):await() state.workspace:create_buffer(name):await()
print(" ++ created buffer '" .. name .. "' on " .. state.workspace.name) print(" ++ created buffer '" .. name .. "' on " .. state.workspace.name)
end end
---@param name string
local function delete(name) local function delete(name)
state.workspace:delete_buffer(name):await() state.workspace:delete_buffer(name):await()
print(" -- deleted buffer " .. name) print(" -- deleted buffer " .. name)
end end
---@param name string
---@param current boolean
---@param content string
local function attach(name, current, content) local function attach(name, current, content)
local buffer = nil local buffer = nil
if current ~= nil then if current ~= nil then
@ -92,6 +97,7 @@ local function attach(name, current, content)
return controller return controller
end end
---@param name string
local function detach(name) local function detach(name)
local buffer = buffer_id_map[name] local buffer = buffer_id_map[name]
id_buffer_map[buffer] = nil id_buffer_map[buffer] = nil

View file

@ -10,10 +10,14 @@ local available_colors = { -- TODO these are definitely not portable!
"CmpItemKindInterface", "CmpItemKindInterface",
} }
---@param x string
---@return string
local function color(x) local function color(x)
return available_colors[ math.fmod(math.abs(native.hash(x)), #available_colors) + 1 ] return available_colors[ math.fmod(math.abs(native.hash(x)), #available_colors) + 1 ]
end end
---@param x [ [integer, integer], [integer, integer] ]
---@return [ [integer, integer], [integer, integer] ]
local function order_tuples(x) -- TODO send help... local function order_tuples(x) -- TODO send help...
if x[1][1] < x[2][1] then if x[1][1] < x[2][1] then
return { { x[1][1], x[1][2] }, { x[2][1], x[2][2] } } return { { x[1][1], x[1][2] }, { x[2][1], x[2][2] } }
@ -26,6 +30,73 @@ local function order_tuples(x) -- TODO send help...
end end
end end
---@param first integer
---@param last integer
---@return integer, integer, integer, integer
local function offset_to_rowcol(first, last)
local start_row, start_col, end_row, end_col
-- TODO this seems to work but i lost my sanity over it. if you want
-- to try and make it better be warned api is madness but i will
-- thank you a lot because this is an ugly mess...
--
-- edge cases to test:
-- - [x] add newline in buffer
-- - [x] append newline to buffer
-- - [x] delete multiline
-- - [x] append at end of buffer
-- - [x] delete at end of buffer
-- - [x] delete line at end of buffer
-- - [x] delete multiline at end of buffer
-- - [x] autocomplete
-- - [ ] delete whole buffer
-- - [ ] enter insert in newline with `o`
start_row = vim.fn.byte2line(first + 1) - 1
if start_row == -2 then
-- print("?? clamping start_row to start")
start_row = vim.fn.line('$') - 1
end
local first_col_byte = vim.fn.line2byte(start_row + 1) - 1
if first_col_byte == -2 then
-- print("?? clamping start_col to 0")
start_col = 0
else
start_col = first - first_col_byte
end
if first == last then
end_row = start_row
end_col = start_col
else
end_row = vim.fn.byte2line(last + 1) - 1
if end_row == -2 then
print("?? clamping end_row to end")
end_row = vim.fn.line('$') - 1
end_col = last - vim.fn.line2byte(end_row + 1)
else
end_col = last - (vim.fn.line2byte(end_row + 1) - 1)
end
end
-- TODO this is an older approach, which covers less edge cases
-- but i didnt bother documenting/testing it yet properly
----send help it works but why is lost knowledge
--start_row = vim.fn.byte2line(first + 1) - 1
--if start_row < 0 then start_row = 0 end
--local start_row_byte = vim.fn.line2byte(start_row + 1) - 1
--if start_row_byte < 0 then start_row_byte = 0 end
--start_col = first - start_row_byte
--end_row = vim.fn.byte2line(last + 1) - 1
--if end_row < 0 then end_row = 0 end
--local end_row_byte = vim.fn.line2byte(end_row + 1) - 1
--if end_row_byte < 0 then end_row_byte = 0 end
--end_col = last - end_row_byte
return start_row, start_col, end_row, end_col
end
---@return [ [integer, integer], [integer, integer] ]
local function cursor_position() local function cursor_position()
local mode = vim.api.nvim_get_mode().mode local mode = vim.api.nvim_get_mode().mode
if mode == "v" then if mode == "v" then
@ -49,6 +120,8 @@ local function cursor_position()
end end
end end
---@param buf integer?
---@return string
local function buffer_get_content(buf) local function buffer_get_content(buf)
if buf == nil then if buf == nil then
buf = vim.api.nvim_get_current_buf() buf = vim.api.nvim_get_current_buf()
@ -57,53 +130,27 @@ local function buffer_get_content(buf)
return table.concat(lines, '\n') return table.concat(lines, '\n')
end end
-- TODO this seems to work but i lost my sanity over it. if you want ---@param buf integer
-- to try and make it better be warned api is madness but i will ---@param content string
-- thank you a lot because this is an ugly mess... ---@param first integer?
-- ---@param last integer?
-- edge cases to test: ---set content of a buffer using byte indexes
-- - [x] add newline in buffer ---if first and last are both nil, set whole buffer content
-- - [x] append newline to buffer ---if first is nil, it defaults to 0
-- - [x] delete multiline ---if last is nil, it will calculate and use the last byte in the buffer
-- - [x] append at end of buffer
-- - [x] delete at end of buffer
-- - [x] delete line at end of buffer
-- - [x] delete multiline at end of buffer
-- - [x] autocomplete
-- - [ ] delete whole buffer
-- - [ ] enter insert in newline with `o`
local function buffer_set_content(buf, content, first, last) local function buffer_set_content(buf, content, first, last)
if first == nil and last == nil then if first == nil and last == nil then
local lines = vim.split(content, "\n", {trimempty=false}) local lines = vim.split(content, "\n", {trimempty=false})
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
else else
if first == nil then first = 0 end
if last == nil then
local line_count = vim.api.nvim_buf_line_count(buf)
last = vim.api.nvim_buf_get_offset(buf, line_count + 1)
end
local first_row, first_col, last_row, last_col local first_row, first_col, last_row, last_col
vim.api.nvim_buf_call(buf, function() vim.api.nvim_buf_call(buf, function()
first_row = vim.fn.byte2line(first + 1) - 1 first_row, first_col, last_row, last_col = offset_to_rowcol(first or 0, last or 0)
if first_row == -2 then
-- print("?? clamping start_row to start")
first_row = vim.fn.line('$') - 1
end
local first_col_byte = vim.fn.line2byte(first_row + 1) - 1
if first_col_byte == -2 then
-- print("?? clamping start_col to 0")
first_col = 0
else
first_col = first - first_col_byte
end
if first == last then
last_row = first_row
last_col = first_col
else
last_row = vim.fn.byte2line(last + 1) - 1
if last_row == -2 then
print("?? clamping end_row to end")
last_row = vim.fn.line('$') - 1
last_col = last - vim.fn.line2byte(last_row + 1)
else
last_col = last - (vim.fn.line2byte(last_row + 1) - 1)
end
end
end) end)
local content_array local content_array
if content == "" then if content == "" then
@ -116,26 +163,11 @@ local function buffer_set_content(buf, content, first, last)
end end
end end
local function buffer_replace_content(buffer, first, last, content) ---@param buf integer buffer to highlight onto
-- TODO send help it works but why is lost knowledge ---@param ns integer namespace for highlight
local start_row = vim.fn.byte2line(first + 1) - 1 ---@param group string highlight group
if start_row < 0 then start_row = 0 end ---@param start RowCol
local start_row_byte = vim.fn.line2byte(start_row + 1) - 1 ---@param fini RowCol
if start_row_byte < 0 then start_row_byte = 0 end
local end_row = vim.fn.byte2line(last + 1) - 1
if end_row < 0 then end_row = 0 end
local end_row_byte = vim.fn.line2byte(end_row + 1) - 1
if end_row_byte < 0 then end_row_byte = 0 end
vim.api.nvim_buf_set_text(
buffer,
start_row,
first - start_row_byte,
end_row,
last - end_row_byte,
vim.fn.split(content, '\n', true)
)
end
local function multiline_highlight(buf, ns, group, start, fini) local function multiline_highlight(buf, ns, group, start, fini)
for i=start.row,fini.row do for i=start.row,fini.row do
if i == start.row and i == fini.row then if i == start.row and i == fini.row then
@ -162,7 +194,6 @@ return {
buffer = { buffer = {
get_content = buffer_get_content, get_content = buffer_get_content,
set_content = buffer_set_content, set_content = buffer_set_content,
replace_content = buffer_replace_content,
}, },
hash = native.hash, hash = native.hash,
available_colors = available_colors, available_colors = available_colors,

View file

@ -2,9 +2,15 @@ local state = require('codemp.state')
local utils = require('codemp.utils') local utils = require('codemp.utils')
local buffers = require('codemp.buffers') local buffers = require('codemp.buffers')
local buffer_id ---@type integer?
local buffer_id = nil
---@type integer?
local prev_window = nil local prev_window = nil
---@type integer?
local window_id = nil local window_id = nil
local ns = vim.api.nvim_create_namespace("codemp-window") local ns = vim.api.nvim_create_namespace("codemp-window")
vim.api.nvim_create_autocmd({"WinLeave"}, { vim.api.nvim_create_autocmd({"WinLeave"}, {
@ -15,6 +21,7 @@ vim.api.nvim_create_autocmd({"WinLeave"}, {
end end
}) })
---@type table<integer, string>
local row_to_buffer = {} local row_to_buffer = {}
local function update_window() local function update_window()
@ -109,6 +116,7 @@ local function init_window()
end end
local function open_window() local function open_window()
if buffer_id == nil then error("no active codemp buffer, reinitialize the window") end
window_id = vim.api.nvim_open_win(buffer_id, true, { window_id = vim.api.nvim_open_win(buffer_id, true, {
win = 0, win = 0,
split = 'left', split = 'left',

View file

@ -4,8 +4,8 @@ local state = require('codemp.state')
local window = require('codemp.window') local window = require('codemp.window')
local user_hl = {} local user_hl = {}
local tree_buf = nil
---@param controller CursorController
local function register_cursor_callback(controller) local function register_cursor_callback(controller)
vim.api.nvim_create_autocmd({"CursorMoved", "CursorMovedI", "ModeChanged"}, { vim.api.nvim_create_autocmd({"CursorMoved", "CursorMovedI", "ModeChanged"}, {
group = vim.api.nvim_create_augroup("codemp-workspace-" .. state.workspace, { clear = true }), group = vim.api.nvim_create_augroup("codemp-workspace-" .. state.workspace, { clear = true }),
@ -13,12 +13,13 @@ local function register_cursor_callback(controller)
local cur = utils.cursor.position() local cur = utils.cursor.position()
local buf = vim.api.nvim_get_current_buf() local buf = vim.api.nvim_get_current_buf()
if buffers.map[buf] ~= nil then if buffers.map[buf] ~= nil then
controller:send(buffers.map[buf], cur[1][1], cur[1][2], cur[2][1], cur[2][2]) local _ = controller:send(buffers.map[buf], cur[1][1], cur[1][2], cur[2][1], cur[2][2]) -- no need to await here
end end
end end
}) })
end end
---@param controller CursorController
local function register_cursor_handler(controller) local function register_cursor_handler(controller)
local async = vim.loop.new_async(vim.schedule_wrap(function () local async = vim.loop.new_async(vim.schedule_wrap(function ()
while true do while true do
@ -56,6 +57,9 @@ local function register_cursor_handler(controller)
controller:callback(function (_controller) async:send() end) controller:callback(function (_controller) async:send() end)
end end
---@param workspace string workspace name to join
---@return Workspace
---join a workspace and register event handlers
local function join(workspace) local function join(workspace)
local ws = state.client:join_workspace(workspace):await() local ws = state.client:join_workspace(workspace):await()
register_cursor_callback(ws.cursor) register_cursor_callback(ws.cursor)
@ -84,30 +88,8 @@ local function leave()
print(" -- left workspace") print(" -- left workspace")
end end
local function open_buffer_tree()
local tree = state.workspace:filetree()
if tree_buf == nil then
tree_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_name(tree_buf, "codemp::" .. state.workspace)
vim.api.nvim_set_option_value('buftype', 'nofile', { buf = tree_buf })
end
vim.api.nvim_set_option_value('modifiable', true, { buf = tree_buf })
utils.buffer.set_content(tree_buf, "codemp::" .. state.workspace .. "\n\n- " .. vim.fn.join(tree, "\n- "))
vim.api.nvim_set_option_value('modifiable', false, { buf = tree_buf })
vim.api.nvim_open_win(tree_buf, true, {
win = 0,
split = 'left',
width = 20,
})
vim.api.nvim_set_option_value('relativenumber', false, {})
vim.api.nvim_set_option_value('number', false, {})
vim.api.nvim_set_option_value('cursorlineopt', 'line', {})
end
return { return {
join = join, join = join,
leave = leave, leave = leave,
map = user_hl, map = user_hl,
open_buffer_tree = open_buffer_tree,
buffer_tree = tree_buf,
} }