mirror of
https://github.com/Myzel394/easytables.nvim.git
synced 2025-06-18 14:55:26 +02:00
152 lines
3.9 KiB
Lua
152 lines
3.9 KiB
Lua
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)
|
|
|
|
if find_col_start(buffer, position[1]) == nil then
|
|
return nil
|
|
end
|
|
|
|
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
|
|
return 0
|
|
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, widths)
|
|
-- Check for each cell whether it only contains horizontal chars and is the same length as widths
|
|
local previous_width = 0
|
|
local cell_index = 1
|
|
|
|
for i = 2, #line, 1 do
|
|
local char = string.sub(line, i, i)
|
|
|
|
if char == o.options.export.markdown.characters.vertical then
|
|
local expected_width = widths[cell_index]
|
|
|
|
-- Allow also - 2 width as some formatters apply spaces around the horizontal lines
|
|
if previous_width ~= expected_width and previous_width ~= expected_width - 2 then
|
|
return false
|
|
end
|
|
|
|
previous_width = 0
|
|
cell_index = cell_index + 1
|
|
elseif char ~= o.options.export.markdown.characters.horizontal and char ~= o.options.export.markdown.characters.filler then
|
|
return false
|
|
else
|
|
previous_width = previous_width + 1
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
---Calculates the width of each column in the given line.
|
|
---@param line string
|
|
---@return table
|
|
local function _get_widths(line)
|
|
local widths = {}
|
|
|
|
local current = 0
|
|
-- Skip first as it's a vertical line
|
|
for i = 2, #line do
|
|
local char = string.sub(line, i, i)
|
|
|
|
if char == o.options.export.markdown.characters.vertical then
|
|
widths[#widths + 1] = current
|
|
current = 0
|
|
else
|
|
current = current + 1
|
|
end
|
|
end
|
|
|
|
return widths
|
|
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 = {}
|
|
|
|
local widths = _get_widths(lines[1])
|
|
|
|
for i, line in ipairs(lines) do
|
|
local is_header = i == 2 and _is_header_line(line, widths)
|
|
|
|
if not is_header then
|
|
table[#table + 1] = {}
|
|
|
|
for content in string.gmatch(line, "[^" .. o.options.export.markdown.characters.vertical .. "]+") do
|
|
table[#table][#table[#table] + 1] = string.gsub(content, '^%s*(.-)%s*$', '%1')
|
|
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
|
|
}
|