From 3f917dcb4520bbbb8281b4f78afde57734611531 Mon Sep 17 00:00:00 2001 From: sammyette Date: Mon, 30 Jan 2023 12:43:26 -0400 Subject: [PATCH] feat: add option to only draw whitespace if it is within selection (#1312) * refactor: remove sort_positions usage * refactor: move draw conditional to has_any_selection and other changes - snake case (sssss) - break after finding selection * fix: typo of config plugins * fix: do check for show selected only properly * feat: only draw within selection per substitution * `drawwhitespace`: Make `show_selected_only` work properly --------- Co-authored-by: Guldoman --- data/plugins/drawwhitespace.lua | 49 +++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/data/plugins/drawwhitespace.lua b/data/plugins/drawwhitespace.lua index 89be875d..6c422172 100644 --- a/data/plugins/drawwhitespace.lua +++ b/data/plugins/drawwhitespace.lua @@ -1,5 +1,6 @@ -- mod-version:3 +local core = require "core" local style = require "core.style" local DocView = require "core.docview" local common = require "core.common" @@ -11,6 +12,7 @@ config.plugins.drawwhitespace = common.merge({ show_leading = true, show_trailing = true, show_middle = true, + show_selected_only = false, show_middle_min = 1, @@ -64,6 +66,13 @@ config.plugins.drawwhitespace = common.merge({ type = "toggle", default = true, }, + { + label = "Show Selected Only", + description = "Only draw whitespaces if it is within a selection.", + path = "show_selected_only", + type = "toggle", + default = false, + }, { label = "Show Trailing as Error", description = "Uses an error square to spot them easily, requires 'Show Trailing' enabled.", @@ -292,11 +301,41 @@ function DocView:draw_line_text(idx, x, y) for i=1,#cache,4 do local tx = cache[i + 1] + x local tw = cache[i + 2] - if tx <= x2 then - local sub = cache[i] - local color = cache[i + 3] - if tx + tw >= x1 then - tx = renderer.draw_text(font, sub, tx, ty, color) + local sub = cache[i] + local color = cache[i + 3] + local partials = {} + if config.plugins.drawwhitespace.show_selected_only and self.doc:has_any_selection() then + for _, l1, c1, l2, c2 in self.doc:get_selections(true) do + if idx > l1 and idx < l2 then + -- Between selection lines, so everything is selected + table.insert(partials, false) + elseif idx == l1 and idx == l2 then + -- Both ends of the selection are on the same line + local _x1 = math.max(cache[i + 1], self:get_col_x_offset(idx, c1)) + local _x2 = math.min((cache[i + 1] + tw), self:get_col_x_offset(idx, c2)) + if _x1 < _x2 then + table.insert(partials, {_x1 + x, 0, _x2 - _x1, math.huge}) + end + elseif idx >= l1 and idx <= l2 then + -- On one of the selection ends + if idx == l1 then -- Start of the selection + local _x = math.max(cache[i + 1], self:get_col_x_offset(idx, c1)) + table.insert(partials, {_x + x, 0, math.huge, math.huge}) + else -- End of the selection + local _x = math.min((cache[i + 1] + tw), self:get_col_x_offset(idx, c2)) + table.insert(partials, {0, 0, _x + x, math.huge}) + end + end + end + end + + if #partials == 0 and not config.plugins.drawwhitespace.show_selected_only then + renderer.draw_text(font, sub, tx, ty, color) + else + for _, p in pairs(partials) do + if p then core.push_clip_rect(table.unpack(p)) end + renderer.draw_text(font, sub, tx, ty, color) + if p then core.pop_clip_rect() end end end end