(renderer) invalidate cache on buffer change
All checks were successful
NeoVim tests / code-quality (push) Successful in 1m32s
All checks were successful
NeoVim tests / code-quality (push) Successful in 1m32s
This commit is contained in:
parent
3682c07b3e
commit
23708652e5
@ -10,10 +10,10 @@
|
|||||||
-- change on the underlying filesystem.
|
-- change on the underlying filesystem.
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- @alias FsDir { kind: 'dir'; path: string; expanded: boolean; children: FsNode[] }
|
--- @alias u.examples.FsDir { kind: 'dir'; path: string; expanded: boolean; children: u.examples.FsNode[] }
|
||||||
--- @alias FsFile { kind: 'file'; path: string }
|
--- @alias u.examples.FsFile { kind: 'file'; path: string }
|
||||||
--- @alias FsNode FsDir | FsFile
|
--- @alias u.examples.FsNode u.examples.FsDir | u.examples.FsFile
|
||||||
--- @alias ShowOpts { root_path?: string, width?: number, focus_path?: string }
|
--- @alias u.examples.ShowOpts { root_path?: string, width?: number, focus_path?: string }
|
||||||
|
|
||||||
local Buffer = require 'u.buffer'
|
local Buffer = require 'u.buffer'
|
||||||
local Renderer = require('u.renderer').Renderer
|
local Renderer = require('u.renderer').Renderer
|
||||||
@ -58,13 +58,13 @@ function H.relative(path, base)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- @param root_path string
|
--- @param root_path string
|
||||||
--- @return { tree: FsDir; path_to_node: table<string, FsNode> }
|
--- @return { tree: u.examples.FsDir; path_to_node: table<string, u.examples.FsNode> }
|
||||||
function H.get_tree_inf(root_path)
|
function H.get_tree_inf(root_path)
|
||||||
logger:info { 'get_tree_inf', root_path }
|
logger:info { 'get_tree_inf', root_path }
|
||||||
--- @type table<string, FsNode>
|
--- @type table<string, u.examples.FsNode>
|
||||||
local path_to_node = {}
|
local path_to_node = {}
|
||||||
|
|
||||||
--- @type FsDir
|
--- @type u.examples.FsDir
|
||||||
local tree = {
|
local tree = {
|
||||||
kind = 'dir',
|
kind = 'dir',
|
||||||
path = H.normalize(root_path or '.'),
|
path = H.normalize(root_path or '.'),
|
||||||
@ -77,8 +77,8 @@ function H.get_tree_inf(root_path)
|
|||||||
return { tree = tree, path_to_node = path_to_node }
|
return { tree = tree, path_to_node = path_to_node }
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param tree FsDir
|
--- @param tree u.examples.FsDir
|
||||||
--- @param path_to_node table<string, FsNode>
|
--- @param path_to_node table<string, u.examples.FsNode>
|
||||||
function H.populate_dir_children(tree, path_to_node)
|
function H.populate_dir_children(tree, path_to_node)
|
||||||
tree.children = {}
|
tree.children = {}
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ local function _render_in_buffer(opts)
|
|||||||
local parts = H.split_path(H.relative(focused_path, tree_inf.tree.path))
|
local parts = H.split_path(H.relative(focused_path, tree_inf.tree.path))
|
||||||
local path_to_node = tree_inf.path_to_node
|
local path_to_node = tree_inf.path_to_node
|
||||||
|
|
||||||
--- @param node FsDir
|
--- @param node u.examples.FsDir
|
||||||
--- @param child_names string[]
|
--- @param child_names string[]
|
||||||
local function expand_to(node, child_names)
|
local function expand_to(node, child_names)
|
||||||
if #child_names == 0 then return end
|
if #child_names == 0 then return end
|
||||||
@ -310,7 +310,7 @@ local function _render_in_buffer(opts)
|
|||||||
--
|
--
|
||||||
local renderer = Renderer.new(opts.bufnr)
|
local renderer = Renderer.new(opts.bufnr)
|
||||||
tracker.create_effect(function()
|
tracker.create_effect(function()
|
||||||
--- @type { tree: FsDir; path_to_node: table<string, FsNode> }
|
--- @type { tree: u.examples.FsDir; path_to_node: table<string, u.examples.FsNode> }
|
||||||
local tree_inf = s_tree_inf:get()
|
local tree_inf = s_tree_inf:get()
|
||||||
local tree = tree_inf.tree
|
local tree = tree_inf.tree
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ local function _render_in_buffer(opts)
|
|||||||
|
|
||||||
--- Since the filesystem is a recursive tree of nodes, we need to
|
--- Since the filesystem is a recursive tree of nodes, we need to
|
||||||
--- recursively render each node. This function does just that:
|
--- recursively render each node. This function does just that:
|
||||||
--- @param node FsNode
|
--- @param node u.examples.FsNode
|
||||||
--- @param level number
|
--- @param level number
|
||||||
local function render_node(node, level)
|
local function render_node(node, level)
|
||||||
local name = vim.fs.basename(node.path)
|
local name = vim.fs.basename(node.path)
|
||||||
@ -414,7 +414,7 @@ end
|
|||||||
local current_inf = nil
|
local current_inf = nil
|
||||||
|
|
||||||
--- Show the filetree:
|
--- Show the filetree:
|
||||||
--- @param opts? ShowOpts
|
--- @param opts? u.examples.ShowOpts
|
||||||
function M.show(opts)
|
function M.show(opts)
|
||||||
if current_inf ~= nil then return current_inf.controller end
|
if current_inf ~= nil then return current_inf.controller end
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
@ -456,7 +456,7 @@ function M.hide()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Toggle the filetree:
|
--- Toggle the filetree:
|
||||||
--- @param opts? ShowOpts
|
--- @param opts? u.examples.ShowOpts
|
||||||
function M.toggle(opts)
|
function M.toggle(opts)
|
||||||
if current_inf == nil then
|
if current_inf == nil then
|
||||||
M.show(opts)
|
M.show(opts)
|
||||||
|
@ -14,7 +14,7 @@ local ICONS = {
|
|||||||
}
|
}
|
||||||
local DEFAULT_ICON = { text = '', group = 'DiagnosticSignOk' }
|
local DEFAULT_ICON = { text = '', group = 'DiagnosticSignOk' }
|
||||||
|
|
||||||
--- @alias Notification {
|
--- @alias u.examples.Notification {
|
||||||
--- kind: number;
|
--- kind: number;
|
||||||
--- id: number;
|
--- id: number;
|
||||||
--- text: string;
|
--- text: string;
|
||||||
@ -30,7 +30,7 @@ local s_notifications = s_notifications_raw:debounce(50)
|
|||||||
|
|
||||||
-- Render effect:
|
-- Render effect:
|
||||||
tracker.create_effect(function()
|
tracker.create_effect(function()
|
||||||
--- @type Notification[]
|
--- @type u.examples.Notification[]
|
||||||
local notifs = s_notifications:get()
|
local notifs = s_notifications:get()
|
||||||
|
|
||||||
if #notifs == 0 then
|
if #notifs == 0 then
|
||||||
@ -99,14 +99,14 @@ local function my_notify(msg, level, opts)
|
|||||||
|
|
||||||
local id = math.random(math.huge)
|
local id = math.random(math.huge)
|
||||||
|
|
||||||
--- @param notifs Notification[]
|
--- @param notifs u.examples.Notification[]
|
||||||
s_notifications_raw:schedule_update(function(notifs)
|
s_notifications_raw:schedule_update(function(notifs)
|
||||||
table.insert(notifs, { kind = level, id = id, text = msg })
|
table.insert(notifs, { kind = level, id = id, text = msg })
|
||||||
return notifs
|
return notifs
|
||||||
end)
|
end)
|
||||||
|
|
||||||
vim.defer_fn(function()
|
vim.defer_fn(function()
|
||||||
--- @param notifs Notification[]
|
--- @param notifs u.examples.Notification[]
|
||||||
s_notifications_raw:schedule_update(function(notifs)
|
s_notifications_raw:schedule_update(function(notifs)
|
||||||
for i, notif in ipairs(notifs) do
|
for i, notif in ipairs(notifs) do
|
||||||
if notif.id == id then
|
if notif.id == id then
|
||||||
|
@ -44,7 +44,7 @@ local function shallow_copy_arr(arr) return vim.iter(arr):totable() end
|
|||||||
-- shortest portion of this function.
|
-- shortest portion of this function.
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- @alias SelectController {
|
--- @alias u.examples.SelectController {
|
||||||
--- get_items: fun(): T[];
|
--- get_items: fun(): T[];
|
||||||
--- set_items: fun(items: T[]);
|
--- set_items: fun(items: T[]);
|
||||||
--- set_filter_text: fun(filter_text: string);
|
--- set_filter_text: fun(filter_text: string);
|
||||||
@ -53,17 +53,17 @@ local function shallow_copy_arr(arr) return vim.iter(arr):totable() end
|
|||||||
--- set_selected_indices: fun(indicies: number[], ephemeral?: boolean);
|
--- set_selected_indices: fun(indicies: number[], ephemeral?: boolean);
|
||||||
--- close: fun();
|
--- close: fun();
|
||||||
--- }
|
--- }
|
||||||
--- @alias SelectOpts<T> {
|
--- @alias u.examples.SelectOpts<T> {
|
||||||
--- items: `T`[];
|
--- items: `T`[];
|
||||||
--- multi?: boolean;
|
--- multi?: boolean;
|
||||||
--- format_item?: fun(item: T): Tree;
|
--- format_item?: fun(item: T): u.renderer.Tree;
|
||||||
--- on_finish?: fun(items: T[], indicies: number[]);
|
--- on_finish?: fun(items: T[], indicies: number[]);
|
||||||
--- on_selection_changed?: fun(items: T[], indicies: number[]);
|
--- on_selection_changed?: fun(items: T[], indicies: number[]);
|
||||||
--- mappings?: table<string, fun(select: SelectController)>;
|
--- mappings?: table<string, fun(select: u.examples.SelectController)>;
|
||||||
--- }
|
--- }
|
||||||
|
|
||||||
--- @generic T
|
--- @generic T
|
||||||
--- @param opts SelectOpts<T>
|
--- @param opts u.examples.SelectOpts<T>
|
||||||
function M.create_picker(opts) -- {{{
|
function M.create_picker(opts) -- {{{
|
||||||
local is_in_insert_mode = vim.api.nvim_get_mode().mode:sub(1, 1) == 'i'
|
local is_in_insert_mode = vim.api.nvim_get_mode().mode:sub(1, 1) == 'i'
|
||||||
local stopinsert = not is_in_insert_mode
|
local stopinsert = not is_in_insert_mode
|
||||||
@ -557,7 +557,7 @@ function M.create_picker(opts) -- {{{
|
|||||||
return safe_run(function() H.finish(true) end)
|
return safe_run(function() H.finish(true) end)
|
||||||
end
|
end
|
||||||
|
|
||||||
return controller --[[@as SelectController]]
|
return controller --[[@as u.examples.SelectController]]
|
||||||
end -- }}}
|
end -- }}}
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -373,6 +373,10 @@ function Renderer:_expr_map_callback(mode, lhs) -- {{{
|
|||||||
end -- }}}
|
end -- }}}
|
||||||
|
|
||||||
function Renderer:_on_text_changed()
|
function Renderer:_on_text_changed()
|
||||||
|
-- Reset changedtick, so that the reconciler knows to refresh its cached
|
||||||
|
-- buffer-content before computing the diff:
|
||||||
|
self.changedtick = 0
|
||||||
|
|
||||||
--- @type integer, integer
|
--- @type integer, integer
|
||||||
local l, c = unpack(vim.api.nvim_win_get_cursor(0))
|
local l, c = unpack(vim.api.nvim_win_get_cursor(0))
|
||||||
l = l - 1 -- make it actually 0-based
|
l = l - 1 -- make it actually 0-based
|
||||||
@ -574,13 +578,13 @@ function TreeBuilder:tree() return self.nodes end
|
|||||||
|
|
||||||
-- Levenshtein utility {{{
|
-- Levenshtein utility {{{
|
||||||
-- luacheck: ignore
|
-- luacheck: ignore
|
||||||
--- @alias 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
|
--- @private
|
||||||
--- @generic T
|
--- @generic T
|
||||||
--- @param x `T`[]
|
--- @param x `T`[]
|
||||||
--- @param y 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 LevenshteinChange<T>[] The changes, from last (greatest index) to first (smallest index).
|
--- @return u.renderer.LevenshteinChange<T>[] The changes, from last (greatest index) to first (smallest index).
|
||||||
function H.levenshtein(x, y, cost)
|
function H.levenshtein(x, y, cost)
|
||||||
-- At the moment, this whole `cost` plumbing is not used. Deletes have the
|
-- At the moment, this whole `cost` plumbing is not used. Deletes have the
|
||||||
-- same cost as Adds or Changes. I can imagine a future, however, where
|
-- same cost as Adds or Changes. I can imagine a future, however, where
|
||||||
@ -631,7 +635,7 @@ function H.levenshtein(x, y, cost)
|
|||||||
-- Backtrack to find the changes
|
-- Backtrack to find the changes
|
||||||
local i = m
|
local i = m
|
||||||
local j = n
|
local j = n
|
||||||
--- @type LevenshteinChange[]
|
--- @type u.renderer.LevenshteinChange[]
|
||||||
local changes = {}
|
local changes = {}
|
||||||
|
|
||||||
while i > 0 or j > 0 do
|
while i > 0 or j > 0 do
|
||||||
@ -648,7 +652,7 @@ function H.levenshtein(x, y, cost)
|
|||||||
if is_first_min(cost_of_change, cost_of_add, cost_of_delete) then
|
if is_first_min(cost_of_change, cost_of_add, cost_of_delete) then
|
||||||
-- potential change
|
-- potential change
|
||||||
if x[i] ~= y[j] then
|
if x[i] ~= y[j] then
|
||||||
--- @type LevenshteinChange
|
--- @type u.renderer.LevenshteinChange
|
||||||
local change = { kind = 'change', from = x[i], index = i, to = y[j] }
|
local change = { kind = 'change', from = x[i], index = i, to = y[j] }
|
||||||
table.insert(changes, change)
|
table.insert(changes, change)
|
||||||
end
|
end
|
||||||
@ -656,13 +660,13 @@ function H.levenshtein(x, y, cost)
|
|||||||
j = j - 1
|
j = j - 1
|
||||||
elseif is_first_min(cost_of_add, cost_of_change, cost_of_delete) then
|
elseif is_first_min(cost_of_add, cost_of_change, cost_of_delete) then
|
||||||
-- addition
|
-- addition
|
||||||
--- @type LevenshteinChange
|
--- @type u.renderer.LevenshteinChange
|
||||||
local change = { kind = 'add', item = y[j], index = i + 1 }
|
local change = { kind = 'add', item = y[j], index = i + 1 }
|
||||||
table.insert(changes, change)
|
table.insert(changes, change)
|
||||||
j = j - 1
|
j = j - 1
|
||||||
elseif is_first_min(cost_of_delete, cost_of_change, cost_of_add) then
|
elseif is_first_min(cost_of_delete, cost_of_change, cost_of_add) then
|
||||||
-- deletion
|
-- deletion
|
||||||
--- @type LevenshteinChange
|
--- @type u.renderer.LevenshteinChange
|
||||||
local change = { kind = 'delete', item = x[i], index = i }
|
local change = { kind = 'delete', item = x[i], index = i }
|
||||||
table.insert(changes, change)
|
table.insert(changes, change)
|
||||||
i = i - 1
|
i = i - 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user