166 lines
3.8 KiB
Lua
166 lines
3.8 KiB
Lua
local api, fn = vim.api, vim.fn
|
|
|
|
---@class buf
|
|
---@field bufnr integer buffer handle
|
|
---@field size integer buffer line count
|
|
local buffer = {}
|
|
|
|
---Clear all content in buffer
|
|
function buffer:wipe()
|
|
api.nvim_buf_set_lines(self.bufnr, 0, -1, false, {})
|
|
self.size = 0
|
|
end
|
|
|
|
---delete buffer [_start, _end] line content [one index]
|
|
---@param _start integer start line index
|
|
---@param _end integer end line index
|
|
function buffer:del(_start, _end)
|
|
if not _start then
|
|
fn.deletebufline(self.bufnr, '$')
|
|
else
|
|
_end = _end or _start
|
|
fn.deletebufline(self.bufnr, _start, _end)
|
|
end
|
|
self.size = api.nvim_buf_line_count(self.bufnr)
|
|
end
|
|
|
|
---Set buffer option
|
|
---@param name string option name
|
|
---@param value any option value
|
|
function buffer:set(name, value)
|
|
api.nvim_buf_set_option(self.bufnr, name, value)
|
|
end
|
|
|
|
---get buffer option
|
|
---@param name string option name
|
|
---@return any
|
|
function buffer:option(name)
|
|
return api.nvim_buf_get_option(self.bufnr, name)
|
|
end
|
|
|
|
function buffer:delete()
|
|
api.nvim_buf_delete(self.bufnr, { force = true })
|
|
end
|
|
|
|
---Set buffer load keymap
|
|
---@param key string
|
|
---@param operation function | string
|
|
function buffer:map(key, operation)
|
|
vim.keymap.set('n', key, operation, {
|
|
buffer = self.bufnr,
|
|
silent = true,
|
|
})
|
|
end
|
|
|
|
---Execute normal keycode in this buffer[no recursive]
|
|
---@param key string key code
|
|
function buffer:normal(key)
|
|
api.nvim_buf_call(self.bufnr, function()
|
|
vim.cmd([[normal! ]] .. key)
|
|
end)
|
|
end
|
|
|
|
---@return boolean
|
|
---@nodiscard
|
|
function buffer:is_valid()
|
|
return api.nvim_buf_is_valid(self.bufnr)
|
|
end
|
|
|
|
---Get buffer [i, j] line content
|
|
---@param i integer? start line index
|
|
---@param j integer? end line index
|
|
---@return string[]
|
|
function buffer:lines(i, j)
|
|
i = i and i - 1 or 0
|
|
j = j and j - 1 or -1
|
|
return api.nvim_buf_get_lines(self.bufnr, i, j, false)
|
|
end
|
|
|
|
---Calculate buffer content display height
|
|
---@param width integer
|
|
---@return integer height
|
|
function buffer:height(width)
|
|
local size = self.size
|
|
local lines = self:lines()
|
|
local height = 0
|
|
for i = 1, size do
|
|
height = height + math.max(1, (math.ceil(lines[i]:width() / width)))
|
|
end
|
|
return height
|
|
end
|
|
|
|
---Add|Set line content
|
|
---@param nodes string|table|table[] string -> as line content | table -> as a node | table[] -> as node[]
|
|
---@param index number? line number should be set[one index]
|
|
function buffer:addline(nodes, index)
|
|
local newsize = self.size + 1
|
|
assert(index == nil or index <= newsize)
|
|
index = index or newsize
|
|
if index == newsize then
|
|
self.size = newsize
|
|
end
|
|
|
|
if type(nodes) == 'string' then
|
|
self[index] = nodes
|
|
return
|
|
end
|
|
|
|
|
|
local line = index - 1
|
|
local bufnr = self.bufnr
|
|
local col = 0
|
|
if type(nodes[1]) == 'string' then
|
|
self[index] = nodes[1]
|
|
nodes:load(bufnr, line, col)
|
|
return
|
|
end
|
|
|
|
|
|
local strs = {}
|
|
local num = #nodes
|
|
for i = 1, num do
|
|
strs[i] = nodes[i][1]
|
|
end
|
|
|
|
self[index] = table.concat(strs)
|
|
for i = 1, num do
|
|
local node = nodes[i]
|
|
node:load(bufnr, line, col)
|
|
col = col + #node[1]
|
|
end
|
|
end
|
|
|
|
function buffer:init()
|
|
self.bufnr = api.nvim_create_buf(false, false)
|
|
self:set('filetype', 'Trans')
|
|
self:set('buftype', 'nofile')
|
|
self.size = 0
|
|
end
|
|
|
|
---@private
|
|
buffer.__index = function(self, key)
|
|
local res = buffer[key]
|
|
if res then
|
|
return res
|
|
elseif type(key) == 'number' then
|
|
return fn.getbufoneline(self.bufnr, key)
|
|
else
|
|
error('invalid key' .. key)
|
|
end
|
|
end
|
|
|
|
---@private
|
|
buffer.__newindex = function(self, key, text)
|
|
assert(key <= self.size + 1)
|
|
fn.setbufline(self.bufnr, key, text)
|
|
end
|
|
|
|
---buffer constructor
|
|
---@return buf
|
|
return function()
|
|
return setmetatable({
|
|
bufnr = -1,
|
|
size = 0,
|
|
}, buffer)
|
|
end
|