|
|
|
|
@@ -15,7 +15,7 @@ local H = {}
|
|
|
|
|
|
|
|
|
|
--- @alias u.renderer.TagEventHandler fun(tag: u.renderer.Tag, mode: string, lhs: string): string
|
|
|
|
|
|
|
|
|
|
--- @alias u.renderer.TagAttributes { [string]?: unknown; imap?: table<string, u.renderer.TagEventHandler>; nmap?: table<string, u.renderer.TagEventHandler>; vmap?: table<string, u.renderer.TagEventHandler>; xmap?: table<string, u.renderer.TagEventHandler>; omap?: table<string, u.renderer.TagEventHandler>, on_change?: fun(text: string): unknown }
|
|
|
|
|
--- @alias u.renderer.TagAttributes { [string]?: unknown, imap?: table<string, u.renderer.TagEventHandler>, nmap?: table<string, u.renderer.TagEventHandler>, vmap?: table<string, u.renderer.TagEventHandler>, xmap?: table<string, u.renderer.TagEventHandler>, omap?: table<string, u.renderer.TagEventHandler>, on_change?: fun(text: string): unknown }
|
|
|
|
|
|
|
|
|
|
--- @class u.renderer.Tag
|
|
|
|
|
--- @field kind 'tag'
|
|
|
|
|
@@ -56,8 +56,8 @@ M.h = setmetatable({}, {
|
|
|
|
|
--- @field bufnr number
|
|
|
|
|
--- @field ns number
|
|
|
|
|
--- @field changedtick number
|
|
|
|
|
--- @field old { lines: string[]; extmarks: u.renderer.RendererExtmark[] }
|
|
|
|
|
--- @field curr { lines: string[]; extmarks: u.renderer.RendererExtmark[] }
|
|
|
|
|
--- @field old { lines: string[], extmarks: u.renderer.RendererExtmark[] }
|
|
|
|
|
--- @field curr { lines: string[], extmarks: u.renderer.RendererExtmark[] }
|
|
|
|
|
local Renderer = {}
|
|
|
|
|
Renderer.__index = Renderer
|
|
|
|
|
M.Renderer = Renderer
|
|
|
|
|
@@ -98,10 +98,9 @@ function Renderer.new(bufnr) -- {{{
|
|
|
|
|
return self
|
|
|
|
|
end -- }}}
|
|
|
|
|
|
|
|
|
|
--- @param opts {
|
|
|
|
|
--- tree: u.renderer.Tree;
|
|
|
|
|
--- on_tag?: fun(tag: u.renderer.Tag, start0: [number, number], stop0: [number, number]): any;
|
|
|
|
|
--- }
|
|
|
|
|
--- @class u.renderer.MarkupOpts
|
|
|
|
|
--- @field tree u.renderer.Tree
|
|
|
|
|
--- @field on_tag? fun(tag: u.renderer.Tag, start0: [number, number], stop0: [number, number]): any
|
|
|
|
|
function Renderer.markup_to_lines(opts) -- {{{
|
|
|
|
|
--- @type string[]
|
|
|
|
|
local lines = {}
|
|
|
|
|
@@ -158,10 +157,9 @@ function Renderer.markup_to_lines(opts) -- {{{
|
|
|
|
|
return lines
|
|
|
|
|
end -- }}}
|
|
|
|
|
|
|
|
|
|
--- @param opts {
|
|
|
|
|
--- tree: u.renderer.Tree;
|
|
|
|
|
--- format_tag?: fun(tag: u.renderer.Tag): string;
|
|
|
|
|
--- }
|
|
|
|
|
--- @class u.renderer.StringOpts
|
|
|
|
|
--- @field tree u.renderer.Tree
|
|
|
|
|
--- @field format_tag? fun(tag: u.renderer.Tag): string
|
|
|
|
|
function Renderer.markup_to_string(opts) return table.concat(Renderer.markup_to_lines(opts), '\n') end
|
|
|
|
|
|
|
|
|
|
--- @param bufnr number
|
|
|
|
|
@@ -534,9 +532,9 @@ end -- }}}
|
|
|
|
|
--- (outermost).
|
|
|
|
|
---
|
|
|
|
|
--- @private (private for now)
|
|
|
|
|
--- @param pos0 [number; number]
|
|
|
|
|
--- @param pos0 [number, number]
|
|
|
|
|
--- @param mode string?
|
|
|
|
|
--- @return { extmark: u.renderer.RendererExtmark; tag: u.renderer.Tag; }[]
|
|
|
|
|
--- @return { extmark: u.renderer.RendererExtmark, tag: u.renderer.Tag }[]
|
|
|
|
|
function Renderer:get_tags_at(pos0, mode) -- {{{
|
|
|
|
|
local cursor_line0, cursor_col0 = pos0[1], pos0[2]
|
|
|
|
|
if not mode then mode = vim.api.nvim_get_mode().mode end
|
|
|
|
|
@@ -560,9 +558,8 @@ function Renderer:get_tags_at(pos0, mode) -- {{{
|
|
|
|
|
--- @type u.renderer.RendererExtmark[]
|
|
|
|
|
local mapped_extmarks = vim
|
|
|
|
|
.iter(raw_overlapping_extmarks)
|
|
|
|
|
--- @return u.renderer.RendererExtmark
|
|
|
|
|
:map(function(ext)
|
|
|
|
|
--- @type number, number, number, { end_row?: number; end_col?: number }|nil
|
|
|
|
|
--- @type number, number, number, { end_row?: number, end_col?: number }|nil
|
|
|
|
|
local id, line0, col0, details = unpack(ext)
|
|
|
|
|
local start = { line0, col0 }
|
|
|
|
|
local stop = { line0, col0 }
|
|
|
|
|
@@ -575,7 +572,6 @@ function Renderer:get_tags_at(pos0, mode) -- {{{
|
|
|
|
|
|
|
|
|
|
local intersecting_extmarks = vim
|
|
|
|
|
.iter(mapped_extmarks)
|
|
|
|
|
--- @param ext u.renderer.RendererExtmark
|
|
|
|
|
:filter(function(ext)
|
|
|
|
|
if ext.stop[1] ~= nil and ext.stop[2] ~= nil then
|
|
|
|
|
-- If we've "ciw" and "collapsed" an extmark onto the cursor,
|
|
|
|
|
@@ -640,10 +636,9 @@ function Renderer:get_tags_at(pos0, mode) -- {{{
|
|
|
|
|
-- created extmarks in self.curr.extmarks, which also has which tag each
|
|
|
|
|
-- extmark is associated with. Cross-reference with that list to get a list
|
|
|
|
|
-- of tags that we need to fire events for:
|
|
|
|
|
--- @type { extmark: u.renderer.RendererExtmark; tag: u.renderer.Tag }[]
|
|
|
|
|
--- @type { extmark: u.renderer.RendererExtmark, tag: u.renderer.Tag }[]
|
|
|
|
|
local matching_tags = vim
|
|
|
|
|
.iter(intersecting_extmarks)
|
|
|
|
|
--- @param ext u.renderer.RendererExtmark
|
|
|
|
|
:map(function(ext)
|
|
|
|
|
for _, extmark_cache in ipairs(self.curr.extmarks) do
|
|
|
|
|
if extmark_cache.id == ext.id then return { extmark = ext, tag = extmark_cache.tag } end
|
|
|
|
|
@@ -656,7 +651,7 @@ end -- }}}
|
|
|
|
|
|
|
|
|
|
--- @private
|
|
|
|
|
--- @param tag_or_id string | u.renderer.Tag
|
|
|
|
|
--- @return { start: [number, number]; stop: [number, number] } | nil
|
|
|
|
|
--- @return { start: [number, number], stop: [number, number] } | nil
|
|
|
|
|
function Renderer:get_tag_bounds(tag_or_id) -- {{{
|
|
|
|
|
for _, x in ipairs(self.curr.extmarks) do
|
|
|
|
|
local pos = { start = x.start, stop = x.stop }
|
|
|
|
|
@@ -733,12 +728,12 @@ function TreeBuilder:tree() return self.nodes end
|
|
|
|
|
|
|
|
|
|
-- Levenshtein utility {{{
|
|
|
|
|
-- luacheck: ignore
|
|
|
|
|
--- @alias u.renderer.LevenshteinChange<T> ({ kind: 'add'; item: T; index: number; } | { kind: 'delete'; item: T; index: number; } | { kind: 'change'; from: T; to: T; index: number; })
|
|
|
|
|
--- @alias u.renderer.LevenshteinChange<T> ({ kind: 'add', item: T, index: number } | { kind: 'delete', item: T, index: number } | { kind: 'change', from: T, to: T, index: number })
|
|
|
|
|
--- @private
|
|
|
|
|
--- @generic T
|
|
|
|
|
--- @param x `T`[]
|
|
|
|
|
--- @param y T[]
|
|
|
|
|
--- @param cost? { of_delete?: fun(x: T): number; of_add?: fun(x: T): number; of_change?: fun(x: T, y: T): number; }
|
|
|
|
|
--- @param cost? { of_delete?: (fun(x: T): number), of_add?: (fun(x: T): number), of_change?: (fun(x: T, y: T): number) }
|
|
|
|
|
--- @return u.renderer.LevenshteinChange<T>[] The changes, from last (greatest index) to first (smallest index).
|
|
|
|
|
function H.levenshtein(x, y, cost)
|
|
|
|
|
-- At the moment, this whole `cost` plumbing is not used. Deletes have the
|
|
|
|
|
|