diff --git a/lua/easytables/export.lua b/lua/easytables/export.lua index 301c04a..e2f4139 100644 --- a/lua/easytables/export.lua +++ b/lua/easytables/export.lua @@ -13,7 +13,7 @@ function M:export_cell(content, width) o.options.export.markdown.characters.vertical .. padding .. content - .. string.rep(" ", width - #content) + .. string.rep(" ", width - vim.api.nvim_strwidth(content)) .. padding end diff --git a/lua/easytables/import.lua b/lua/easytables/import.lua new file mode 100644 index 0000000..aaeae2e --- /dev/null +++ b/lua/easytables/import.lua @@ -0,0 +1,105 @@ +local o = require("easytables.options") + +---Finds the start of the table. Currently only returns 0 as characters before the table are not supported. +local function find_col_start(buffer, row) + local result = vim.api.nvim_buf_get_lines(buffer, row, row + 1, false) + + if #result == 0 then + return nil + end + + local first_char = string.sub(result[1], 1, 1) + + if first_char == o.options.export.markdown.characters.vertical then + return 0 + end + return nil +end + +local function find_row_start(buffer) + local position = vim.api.nvim_win_get_cursor(0) + + local current_line = position[1] - 1 + while true do + if find_col_start(buffer, current_line) == nil then + return current_line + 1 + elseif current_line == 1 then + -- Nothing found + return nil + end + + current_line = current_line - 1 + end +end + +---Only call this after `find_row_start` was successful. +---@param buffer number +---@param row_start number +---@return number? +local function find_row_end( + buffer, + row_start +) + local current = row_start + + while find_col_start(buffer, current) ~= nil do + current = current + 1 + end + + return current +end + +local function find_col_end( + buffer, + row_start +) + -- Return last position of the row, as characters after tables are not supported. + return #vim.api.nvim_buf_get_text(buffer, row_start, -1, row_start, -1, {}) +end + +local function _is_header_line(line) + for i = 1, #line do + local char = line:sub(i, i) + if char ~= o.options.export.markdown.characters.horizontal and char ~= o.options.export.markdown.characters.vertical then + return false + end + end + + return true +end + +---Extracts the raw table string from the given buffer. +---@param buffer number +---@param row_start number +---@param row_end number +---@return table of strings +local function extract_table( + buffer, + row_start, + row_end +) + local lines = vim.api.nvim_buf_get_lines(buffer, row_start, row_end, false) + + local table = {} + + for _, line in ipairs(lines) do + if not _is_header_line(line) then + table[#table + 1] = {} + + for content in string.gmatch(line, "[^" .. o.options.export.markdown.characters.vertical .. "]+") do + table[#table][#table[#table] + 1] = content + end + end + end + + return table +end + + +return { + find_col_start = find_col_start, + find_row_start = find_row_start, + find_row_end = find_row_end, + find_col_end = find_col_end, + extract_table = extract_table +} diff --git a/lua/easytables/init.lua b/lua/easytables/init.lua index 1e2e77d..3ec6e28 100644 --- a/lua/easytables/init.lua +++ b/lua/easytables/init.lua @@ -2,16 +2,7 @@ local table = require("easytables.table") local window = require("easytables.window") local inputHelper = require("easytables.input") local o = require("easytables.options") - -local function create_new_table(cols, rows) - local markdown_table = table:create(cols, rows) - - local win = window:create(markdown_table) - - win:show() - win:register_listeners() - win:draw_table() -end +local import = require("easytables.import") ---Initialize `easytables` with the given options. This function **must** be called. ---@param options table See options.lua for available options @@ -35,13 +26,59 @@ local function setup(options) local cols = result[1] local rows = result[2] - create_new_table(cols, rows) + local markdown_table = table:create(cols, rows) + + local win = window:create(markdown_table) + + win:show() + win:register_listeners() + win:draw_table() end, { nargs = 1, desc = "Create a new markdown table using EasyTables" } ) + + vim.api.nvim_create_user_command( + "EasyTablesImportThisTable", + function() + local buffer = vim.api.nvim_get_current_buf() + local start_row = import.find_row_start(buffer) + + if not start_row then + error("No table found (failed to find start row)") + return + end + + local end_row = import.find_row_end(buffer, start_row) + + if not end_row then + error("No table found (failed to find end row)") + return + end + + print(vim.inspect(start_row), vim.inspect(end_row)) + + local raw_table = import.extract_table(buffer, start_row, end_row) + print(vim.inspect(raw_table)) + + local markdown_table = table:import(raw_table) + + local win = window:create(markdown_table) + + win:show() + win:register_listeners() + win:draw_table() + + + -- Remove old table + vim.api.nvim_buf_set_lines(buffer, start_row - 1, end_row, false, {}) + end, + { + desc = "Import the current markdown table at the cursor's position into EasyTables" + } + ) end return { diff --git a/lua/easytables/table.lua b/lua/easytables/table.lua index 66b98ff..60ccf2b 100644 --- a/lua/easytables/table.lua +++ b/lua/easytables/table.lua @@ -26,6 +26,22 @@ function M:create(cols, rows) return self end +function M:import(table) + self.table = table + self.highlighted_cell = { + col = 1, + row = 1, + } + + if #table > 1 then + self.header_enabled = o.options.table.header_enabled_by_default + else + self.header_enabled = false + end + + return self +end + function M:insert(col, row, value) self.table[row][col] = value end diff --git a/lua/easytables/window.lua b/lua/easytables/window.lua index bb60c1f..6545ba0 100644 --- a/lua/easytables/window.lua +++ b/lua/easytables/window.lua @@ -65,8 +65,6 @@ function M:_set_window_positions() local width = self:get_table_width() local _, height = get_window_size(self.table:cols_amount(), self.table:rows_amount()) - print("updating", vim.inspect(width), vim.inspect(height)) - vim.api.nvim_win_set_config(self.preview_window, { width = width, height = height,