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 <giulio.lettieri@gmail.com>
This commit is contained in:
sammyette 2023-01-30 12:43:26 -04:00 committed by George Sokianos
parent 4ef4b99c7a
commit 3f917dcb45
1 changed files with 44 additions and 5 deletions

View File

@ -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