mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 09:30:04 +08:00
115 lines
3.4 KiB
Lua
Vendored
115 lines
3.4 KiB
Lua
Vendored
local Object = require("nui.object")
|
|
local _ = require("nui.utils")._
|
|
local is_type = require("nui.utils").is_type
|
|
|
|
---@class NuiText
|
|
---@field protected extmark? table|{ id?: number, hl_group: string }
|
|
local Text = Object("NuiText")
|
|
|
|
---@param content string|NuiText text content or NuiText object
|
|
---@param extmark? string|table highlight group name or extmark options
|
|
function Text:init(content, extmark)
|
|
if is_type("table", content) then
|
|
-- cloning
|
|
self:set(content._content, extmark or content.extmark)
|
|
else
|
|
self:set(content, extmark)
|
|
end
|
|
end
|
|
|
|
---@param content string text content
|
|
---@param extmark? string|table highlight group name or extmark options
|
|
---@return NuiText
|
|
function Text:set(content, extmark)
|
|
if self._content ~= content then
|
|
self._content = content
|
|
self._length = vim.fn.strlen(content)
|
|
self._width = vim.api.nvim_strwidth(content)
|
|
end
|
|
|
|
if extmark then
|
|
-- preserve self.extmark.id
|
|
local id = self.extmark and self.extmark.id or nil
|
|
self.extmark = is_type("string", extmark) and { hl_group = extmark } or vim.deepcopy(extmark)
|
|
self.extmark.id = id
|
|
end
|
|
|
|
return self
|
|
end
|
|
|
|
---@return string
|
|
function Text:content()
|
|
return self._content
|
|
end
|
|
|
|
---@return number
|
|
function Text:length()
|
|
return self._length
|
|
end
|
|
|
|
---@return number
|
|
function Text:width()
|
|
return self._width
|
|
end
|
|
|
|
---@param bufnr number buffer number
|
|
---@param ns_id number namespace id
|
|
---@param linenr number line number (1-indexed)
|
|
---@param byte_start number start byte position (0-indexed)
|
|
---@return nil
|
|
function Text:highlight(bufnr, ns_id, linenr, byte_start)
|
|
if not self.extmark then
|
|
return
|
|
end
|
|
|
|
self.extmark.end_col = byte_start + self:length()
|
|
|
|
self.extmark.id = vim.api.nvim_buf_set_extmark(
|
|
bufnr,
|
|
_.ensure_namespace_id(ns_id),
|
|
linenr - 1,
|
|
byte_start,
|
|
self.extmark
|
|
)
|
|
end
|
|
|
|
---@param bufnr number buffer number
|
|
---@param ns_id number namespace id
|
|
---@param linenr_start number start line number (1-indexed)
|
|
---@param byte_start number start byte position (0-indexed)
|
|
---@param linenr_end? number end line number (1-indexed)
|
|
---@param byte_end? number end byte position (0-indexed)
|
|
---@return nil
|
|
function Text:render(bufnr, ns_id, linenr_start, byte_start, linenr_end, byte_end)
|
|
local row_start = linenr_start - 1
|
|
local row_end = linenr_end and linenr_end - 1 or row_start
|
|
|
|
local col_start = byte_start
|
|
local col_end = byte_end or byte_start + self:length()
|
|
|
|
local content = self:content()
|
|
|
|
vim.api.nvim_buf_set_text(bufnr, row_start, col_start, row_end, col_end, { content })
|
|
|
|
self:highlight(bufnr, ns_id, linenr_start, byte_start)
|
|
end
|
|
|
|
---@param bufnr number buffer number
|
|
---@param ns_id number namespace id
|
|
---@param linenr_start number start line number (1-indexed)
|
|
---@param char_start number start character position (0-indexed)
|
|
---@param linenr_end? number end line number (1-indexed)
|
|
---@param char_end? number end character position (0-indexed)
|
|
---@return nil
|
|
function Text:render_char(bufnr, ns_id, linenr_start, char_start, linenr_end, char_end)
|
|
char_end = char_end or char_start + self:width()
|
|
local byte_range = _.char_to_byte_range(bufnr, linenr_start, char_start, char_end)
|
|
self:render(bufnr, ns_id, linenr_start, byte_range[1], linenr_end, byte_range[2])
|
|
end
|
|
|
|
---@alias NuiText.constructor fun(content: string|NuiText, extmark?: string|table): NuiText
|
|
---@type NuiText|NuiText.constructor
|
|
local NuiText = Text
|
|
|
|
return NuiText
|