Skip to content

Commit

Permalink
fix(renderer): Reworked hybrid_mode
Browse files Browse the repository at this point in the history
Closes #92, #93

feat: Added ability to only load part of the buffer when file is too big

Added configuration options to control this behavior.

fix: Removed usage of `deep_merge`

Now, only highlight groups are left unchanged. Everything else is done
via `tbl_deep_extend`.
  • Loading branch information
OXY2DEV committed Aug 8, 2024
1 parent d69122d commit e29b7b5
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 42 deletions.
111 changes: 78 additions & 33 deletions ftplugin/markdown.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,33 @@ vim.api.nvim_create_autocmd({ "BufWinEnter" }, {

markview.state.buf_states[buffer] = true;

local parsed_content = markview.parser.init(buffer, markview.configuration);
local lines = vim.api.nvim_buf_line_count(buffer);

markview.renderer.clear(buffer);
markview.renderer.render(buffer, parsed_content, markview.configuration)

if lines < (markview.configuration.max_length or 1000) then
local parsed_content = markview.parser.init(buffer, markview.configuration);

markview.renderer.render(buffer, parsed_content, markview.configuration)
else
local cursor = vim.api.nvim_win_get_cursor(0);
local start = math.max(0, cursor[1] - (markview.configuration.render_range or 100));
local stop = math.min(lines, cursor[1] + (markview.configuration.render_range or 100));

local parsed_content = markview.parser.parse_range(buffer, markview.configuration, start, stop);

markview.renderer.render(buffer, parsed_content, markview.configuration)
end

-- This needs all of the buffer to be parsed
local keymap_content = markview.parser.init(buffer, markview.configuration);

for _, window in ipairs(windows) do
if markview.configuration.callbacks and markview.configuration.callbacks.on_enable then
pcall(markview.configuration.callbacks.on_enable, buffer, window);
end

markview.keymaps.init(buffer, window, parsed_content, markview.configuration);
markview.keymaps.init(buffer, window, keymap_content, markview.configuration);
end
end
});
Expand Down Expand Up @@ -123,28 +139,45 @@ vim.api.nvim_create_autocmd({ "ModeChanged", "TextChanged" }, {

::noCallbacks::

-- Mode is a valid mode
if markview.configuration.modes and vim.list_contains(markview.configuration.modes, mode) then
local parsed_content = markview.parser.init(buffer, markview.configuration);
local parse_start, parse_stop = utils.get_cursor_range(buffer, windows[1]);
local lines = vim.api.nvim_buf_line_count(buffer);
local parsed_content;

markview.renderer.clear(buffer);

local partial_contents = markview.parser.parse_range(event.buf, markview.configuration, parse_start, parse_stop);
local current_range = markview.renderer.get_content_range(partial_contents);
if lines < (markview.configuration.max_length or 1000) then
parsed_content = markview.parser.init(buffer, markview.configuration);

if markview.configuration.hybrid_modes and vim.list_contains(markview.configuration.hybrid_modes, mode) then
markview.renderer.render(buffer, parsed_content, markview.configuration, parse_start, parse_stop);
markview.renderer.clear_content_range(event.buf, partial_contents)
else
markview.renderer.render(buffer, parsed_content, markview.configuration);
end
else
local cursor = vim.api.nvim_win_get_cursor(0);
local start = math.max(0, cursor[1] - (markview.configuration.render_range or 100));
local stop = math.min(lines, cursor[1] + (markview.configuration.render_range or 100));

-- Or else things won't render on first redraw from the other autocmd
markview.renderer.update_range(buffer, current_range);
parsed_content = markview.parser.parse_range(buffer, markview.configuration, start, stop);

markview.renderer.render(buffer, parsed_content, markview.configuration)
end

for _, window in ipairs(windows) do
markview.keymaps.init(buffer, window, parsed_content, markview.configuration);
end

local cursor = vim.api.nvim_win_get_cursor(0);
local start = math.max(0, cursor[1] - 1);
local stop = math.min(lines, cursor[1]);

local under_cursor = markview.parser.parse_range(event.buf, markview.configuration, start, stop);
local clear_range = markview.renderer.get_content_range(under_cursor);

if not clear_range or not clear_range[1] or not clear_range[2] then
return;
end

markview.renderer.clear(event.buf, clear_range[1], clear_range[2])

-- Mode is not a valid mode. Clear decorations.
else
-- Call an extra redraw to flush out screen updates
markview.renderer.clear(buffer);
Expand Down Expand Up @@ -186,35 +219,47 @@ vim.api.nvim_create_autocmd(events, {

move_timer:stop();
move_timer:start(100, 0, vim.schedule_wrap(function ()
if not _G.__markview_render_ranges then
_G.__markview_render_ranges = {};
end
local lines = vim.api.nvim_buf_line_count(event.buf);
local buffer = event.buf;

if not _G.__markview_render_ranges[event.buf] then
_G.__markview_render_ranges[event.buf] = {};
local parsed_content;

markview.renderer.clear(buffer);

if lines < (markview.configuration.max_length or 1000) then
parsed_content = markview.parser.init(buffer, markview.configuration);

markview.renderer.render(buffer, parsed_content, markview.configuration)
else
local cursor = vim.api.nvim_win_get_cursor(0);
local start = math.max(0, cursor[1] - (markview.configuration.render_range or 100));
local stop = math.min(lines, cursor[1] + (markview.configuration.render_range or 100));

parsed_content = markview.parser.parse_range(buffer, markview.configuration, start, stop);

markview.renderer.render(buffer, parsed_content, markview.configuration)
end

local windows = utils.find_attached_wins(event.buf);
if parsed_content and #parsed_content > 0 then
local windows = utils.find_attached_wins(event.buf);

local old_start, old_stop = _G.__markview_render_ranges[event.buf][1], _G.__markview_render_ranges[event.buf][2];
local parse_start, parse_stop = utils.get_cursor_range(event.buf, windows[1]);
for _, window in ipairs(windows) do
markview.keymaps.init(buffer, window, parsed_content, markview.configuration);
end
end

local prev_contents = markview.parser.parse_range(event.buf, markview.configuration, old_start, old_stop);
local partial_contents = markview.parser.parse_range(event.buf, markview.configuration, parse_start, parse_stop);
local cursor = vim.api.nvim_win_get_cursor(0);
local start = math.max(0, cursor[1] - 1);
local stop = math.min(lines, cursor[1]);

local current_range = markview.renderer.get_content_range(partial_contents);
local under_cursor = markview.parser.parse_range(event.buf, markview.configuration, start, stop);
local clear_range = markview.renderer.get_content_range(under_cursor);

if _G.__markview_render_ranges[event.buf] and vim.deep_equal(_G.__markview_render_ranges[event.buf], current_range) then
markview.renderer.clear_content_range(event.buf, partial_contents)
if not clear_range or not clear_range[1] or not clear_range[2] then
return;
end

markview.renderer.clear_content_range(event.buf, partial_contents)
markview.renderer.clear_content_range(event.buf, prev_contents);
markview.renderer.clear(event.buf, parse_start, parse_stop);

markview.renderer.render_in_range(event.buf, prev_contents, markview.configuration);
markview.renderer.update_range(event.buf, current_range);
markview.renderer.clear(event.buf, clear_range[1], clear_range[2])
end));
end
})
Expand Down
12 changes: 12 additions & 0 deletions lua/definitions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
--- List of modes where both raw & preview is shown
---@field hybrid_modes string[]?
---
--- Max number of lines in a file to do full rendering
---@field max_length number?
---
--- Number of lines to render on partial render mode
---@field render_range number?
---
--- Callbacks for plugin states
---@field callbacks markview.config.callbacks?
---
Expand Down Expand Up @@ -65,6 +71,12 @@
--- List of modes where both raw & preview is shown
---@field hybrid_modes string[]?
---
--- Max number of lines in a file to do full rendering
---@field max_length number?
---
--- Number of lines to render on partial render mode
---@field render_range number?
---
--- Options for various plugins states
---@field callbacks markview.config.callbacks
---
Expand Down
44 changes: 35 additions & 9 deletions lua/markview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ markview.deep_merge = function (behavior, tbl_1, tbl_2)
for index, item in ipairs(value) do
if not markview.list_contains(tbl_1[key], item) then
table.insert(tbl_1[key], item);
else
elseif tbl_1[key][index] and type(tbl_1[key][index]) == "table" and type(item) == "table" then
tbl_1[key][index] = markview.deep_merge(behavior, tbl_1[key][index], item);
elseif not markview.list_contains(tbl_1[key], item) then
tbl_1[key][index] = item;
end
end
else
Expand Down Expand Up @@ -70,31 +72,49 @@ markview.hl_exits = function (hl_list, hl)
return false;
end

markview.added_hls = {};

markview.remove_hls = function ()
if vim.tbl_isempty(markview.added_hls) then
return;
end

for _, hl in ipairs(markview.added_hls) do
if vim.fn.hlexists("Markview" .. hl) == 1 then
vim.api.nvim_set_hl(0, "Markview" .. hl, {});
end
end
end

markview.add_hls = function (obj)
local added = {};
markview.added_hls = {};
local use_hl = {};

for _, hl in ipairs(obj) do
if hl.output and type(hl.output) == "function" and pcall(hl.output) then
local _o = hl.output();
local _n = {};

for _, item in ipairs(_o) do
local exists, index = markview.hl_exits(use_hl, item);

if exists == true then
table.remove(use_hl, index);
else
table.insert(_n, item.group_name);
end
end

use_hl = vim.list_extend(use_hl, _o)
use_hl = vim.list_extend(use_hl, _o);
markview.added_hls = vim.list_extend(markview.added_hls, _n);
elseif hl.group_name and hl.value then
local contains, index = markview.list_contains(added, hl.group_name);
local contains, index = markview.list_contains(markview.added_hls, hl.group_name);

if contains == true and index then
use_hl[index] = hl;
else
table.insert(use_hl, hl)
table.insert(added, hl.group_name);
table.insert(markview.added_hls, hl.group_name);
end
end
end
Expand Down Expand Up @@ -124,16 +144,16 @@ markview.global_options = {};
---@type markview.config
markview.configuration = {
callbacks = {
on_enable = function (buffer, window)
on_enable = function (_, window)
vim.wo[window].conceallevel = 2;
vim.wo[window].concealcursor = "nc";
end,
on_disable = function (buffer, window)
on_disable = function (_, window)
vim.wo[window].conceallevel = 0;
vim.wo[window].concealcursor = "";
end,

on_mode_change = function (buffer, window, mode)
on_mode_change = function (_, window, mode)
if vim.list_contains(markview.configuration.modes, mode) then
vim.wo[window].conceallevel = 2;
else
Expand Down Expand Up @@ -1594,11 +1614,17 @@ end, {
})

markview.setup = function (user_config)
if user_config and user_config.highlight_groups then
markview.configuration.highlight_groups = vim.list_extend(markview.configuration.highlight_groups, user_config.highlight_groups);
user_config.highlight_groups = nil;
end

---@type markview.config
-- Merged configuration tables
markview.configuration = markview.deep_merge("force", markview.configuration, user_config or {});
markview.configuration = vim.tbl_deep_extend("force", markview.configuration, user_config or {});

if vim.islist(markview.configuration.highlight_groups) then
markview.remove_hls();
markview.add_hls(markview.configuration.highlight_groups);
end

Expand Down
2 changes: 2 additions & 0 deletions lua/markview/renderer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,8 @@ renderer.render = function (buffer, parsed_content, config_table, conceal_start,
_G.__markview_render_ranges[buffer] = {};
end

-- vim.print(#parsed_content)

for _, content in ipairs(_G.__markview_views[buffer]) do
local type = content.type;
local fold_closed = vim.fn.foldclosed(content.row_start + 1);
Expand Down

0 comments on commit e29b7b5

Please sign in to comment.