From d663a04e56573c3db9ec58c77c82a2a7925aa1bb Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sun, 24 Apr 2022 23:44:36 +0200 Subject: Make `indentguide` highlight the current block --- plugins/indentguide.lua | 94 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 13 deletions(-) (limited to 'plugins') diff --git a/plugins/indentguide.lua b/plugins/indentguide.lua index 0513be4..1c4f8ae 100644 --- a/plugins/indentguide.lua +++ b/plugins/indentguide.lua @@ -4,18 +4,28 @@ local config = require "core.config" local DocView = require "core.docview" +-- TODO: replace with `doc:get_indent_info()` when 2.1 releases +local function get_indent_info(doc) + if doc.get_indent_info then + return doc:get_indent_info() + end + return config.tab_type, config.indent_size +end + + local function get_line_spaces(doc, idx, dir) + local _, indent_size = get_indent_info(doc) local text = doc.lines[idx] - if not text then - return 0 + if not text or #text == 1 then + return -1 end local s, e = text:find("^%s*") if e == #text then return get_line_spaces(doc, idx + dir, dir) end local n = 0 - for i = s, e do - n = n + (text:byte(i) == 9 and config.indent_size or 1) + for _,b in pairs({text:byte(s, e)}) do + n = n + (b == 9 and indent_size or 1) end return n end @@ -30,21 +40,79 @@ local function get_line_indent_guide_spaces(doc, idx) return get_line_spaces(doc, idx) end +local docview_update = DocView.update +function DocView:update() + docview_update(self) -local draw_line_text = DocView.draw_line_text + local function get_indent(idx) + if idx < 1 or idx > #self.doc.lines then return -1 end + if not self.lineguide_indents[idx] then + self.lineguide_indents[idx] = get_line_indent_guide_spaces(self.doc, idx) + end + return self.lineguide_indents[idx] + end + + self.lineguide_indents = {} + self.lineguide_indent_active = {} + + local minline, maxline = self:get_visible_line_range() + for i = minline, maxline do + self.lineguide_indents[i] = get_line_indent_guide_spaces(self.doc, i) + end + + local line = self.doc:get_selection() + local lvl = get_indent(line) + local top, bottom + local _, indent_size = get_indent_info(self.doc) + -- check if we're the header or the footer of a block + if get_indent(line + 1) > lvl and get_indent(line + 1) <= lvl + indent_size then + top = true + lvl = get_indent(line + 1) + elseif get_indent(line - 1) > lvl and get_indent(line - 1) <= lvl + indent_size then + bottom = true + lvl = get_indent(line - 1) + end + + self.lineguide_indent_active[line] = lvl + + -- check if the lines before the current are part of the block + local i = line - 1 + if i > 0 and not top then + repeat + if get_indent(i) <= lvl - indent_size then break end + self.lineguide_indent_active[i] = lvl + i = i - 1 + until i < minline + end + -- check if the lines after the current are part of the block + i = line + 1 + if i <= #self.doc.lines and not bottom then + repeat + if get_indent(i) <= lvl - indent_size then break end + self.lineguide_indent_active[i] = lvl + i = i + 1 + until i > maxline + end +end + + +local draw_line_text = DocView.draw_line_text function DocView:draw_line_text(idx, x, y) - local spaces = get_line_indent_guide_spaces(self.doc, idx) - local w = math.ceil(1 * SCALE) + local spaces = self.lineguide_indents[idx] or -1 + local _, indent_size = get_indent_info(self.doc) + local w = math.max(1, SCALE) local h = self:get_line_height() - local sspaces = "" local font = self:get_font() - local ss = font:subpixel_scale() - for _ = 0, spaces - 1, config.indent_size do + local space_sz = font:get_width(" ") + for i = 0, spaces - 1, indent_size do local color = style.guide or style.selection - local sw = font:get_width_subpixel(sspaces) / ss - renderer.draw_rect(x + sw, y, w, h, color) - sspaces = sspaces .. (' '):rep(config.indent_size) + local active_lvl = self.lineguide_indent_active[idx] or -1 + if i < active_lvl and i + indent_size >= active_lvl then + color = style.accent + end + local sw = space_sz * i + renderer.draw_rect(math.ceil(x + sw), y, w, h, color) end draw_line_text(self, idx, x, y) end -- cgit v1.2.3 From 25b576f6ee81b6913cc772e1d7465d3648f5a23e Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sun, 24 Apr 2022 23:58:46 +0200 Subject: Add multicursor support to `indentguide` --- plugins/indentguide.lua | 69 ++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 32 deletions(-) (limited to 'plugins') diff --git a/plugins/indentguide.lua b/plugins/indentguide.lua index 1c4f8ae..c7e781c 100644 --- a/plugins/indentguide.lua +++ b/plugins/indentguide.lua @@ -60,39 +60,44 @@ function DocView:update() self.lineguide_indents[i] = get_line_indent_guide_spaces(self.doc, i) end - local line = self.doc:get_selection() - local lvl = get_indent(line) - local top, bottom local _, indent_size = get_indent_info(self.doc) - - -- check if we're the header or the footer of a block - if get_indent(line + 1) > lvl and get_indent(line + 1) <= lvl + indent_size then - top = true - lvl = get_indent(line + 1) - elseif get_indent(line - 1) > lvl and get_indent(line - 1) <= lvl + indent_size then - bottom = true - lvl = get_indent(line - 1) - end - - self.lineguide_indent_active[line] = lvl - - -- check if the lines before the current are part of the block - local i = line - 1 - if i > 0 and not top then - repeat - if get_indent(i) <= lvl - indent_size then break end - self.lineguide_indent_active[i] = lvl - i = i - 1 - until i < minline - end - -- check if the lines after the current are part of the block - i = line + 1 - if i <= #self.doc.lines and not bottom then - repeat - if get_indent(i) <= lvl - indent_size then break end - self.lineguide_indent_active[i] = lvl - i = i + 1 - until i > maxline + for _,line in self.doc:get_selections() do + local lvl = get_indent(line) + local top, bottom + + if not self.lineguide_indent_active[line] + or self.lineguide_indent_active[line] > lvl then + + -- check if we're the header or the footer of a block + if get_indent(line + 1) > lvl and get_indent(line + 1) <= lvl + indent_size then + top = true + lvl = get_indent(line + 1) + elseif get_indent(line - 1) > lvl and get_indent(line - 1) <= lvl + indent_size then + bottom = true + lvl = get_indent(line - 1) + end + + self.lineguide_indent_active[line] = lvl + + -- check if the lines before the current are part of the block + local i = line - 1 + if i > 0 and not top then + repeat + if get_indent(i) <= lvl - indent_size then break end + self.lineguide_indent_active[i] = lvl + i = i - 1 + until i < minline + end + -- check if the lines after the current are part of the block + i = line + 1 + if i <= #self.doc.lines and not bottom then + repeat + if get_indent(i) <= lvl - indent_size then break end + self.lineguide_indent_active[i] = lvl + i = i + 1 + until i > maxline + end + end end end -- cgit v1.2.3 From 4d4e0b45b186bf18e36af6b18577c7569a01f9d4 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Mon, 25 Apr 2022 00:06:06 +0200 Subject: Allow customizing `indentguide` highlight color --- plugins/indentguide.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins') diff --git a/plugins/indentguide.lua b/plugins/indentguide.lua index c7e781c..e564f71 100644 --- a/plugins/indentguide.lua +++ b/plugins/indentguide.lua @@ -114,7 +114,7 @@ function DocView:draw_line_text(idx, x, y) local color = style.guide or style.selection local active_lvl = self.lineguide_indent_active[idx] or -1 if i < active_lvl and i + indent_size >= active_lvl then - color = style.accent + color = style.guide_highlight or style.accent end local sw = space_sz * i renderer.draw_rect(math.ceil(x + sw), y, w, h, color) -- cgit v1.2.3 From 62701704b525a116fce1cd168236fc93b9856450 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Mon, 25 Apr 2022 00:06:40 +0200 Subject: Rename `indentguide` variables --- plugins/indentguide.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'plugins') diff --git a/plugins/indentguide.lua b/plugins/indentguide.lua index e564f71..99b1311 100644 --- a/plugins/indentguide.lua +++ b/plugins/indentguide.lua @@ -46,18 +46,18 @@ function DocView:update() local function get_indent(idx) if idx < 1 or idx > #self.doc.lines then return -1 end - if not self.lineguide_indents[idx] then - self.lineguide_indents[idx] = get_line_indent_guide_spaces(self.doc, idx) + if not self.indentguide_indents[idx] then + self.indentguide_indents[idx] = get_line_indent_guide_spaces(self.doc, idx) end - return self.lineguide_indents[idx] + return self.indentguide_indents[idx] end - self.lineguide_indents = {} - self.lineguide_indent_active = {} + self.indentguide_indents = {} + self.indentguide_indent_active = {} local minline, maxline = self:get_visible_line_range() for i = minline, maxline do - self.lineguide_indents[i] = get_line_indent_guide_spaces(self.doc, i) + self.indentguide_indents[i] = get_line_indent_guide_spaces(self.doc, i) end local _, indent_size = get_indent_info(self.doc) @@ -65,8 +65,8 @@ function DocView:update() local lvl = get_indent(line) local top, bottom - if not self.lineguide_indent_active[line] - or self.lineguide_indent_active[line] > lvl then + if not self.indentguide_indent_active[line] + or self.indentguide_indent_active[line] > lvl then -- check if we're the header or the footer of a block if get_indent(line + 1) > lvl and get_indent(line + 1) <= lvl + indent_size then @@ -77,14 +77,14 @@ function DocView:update() lvl = get_indent(line - 1) end - self.lineguide_indent_active[line] = lvl + self.indentguide_indent_active[line] = lvl -- check if the lines before the current are part of the block local i = line - 1 if i > 0 and not top then repeat if get_indent(i) <= lvl - indent_size then break end - self.lineguide_indent_active[i] = lvl + self.indentguide_indent_active[i] = lvl i = i - 1 until i < minline end @@ -93,7 +93,7 @@ function DocView:update() if i <= #self.doc.lines and not bottom then repeat if get_indent(i) <= lvl - indent_size then break end - self.lineguide_indent_active[i] = lvl + self.indentguide_indent_active[i] = lvl i = i + 1 until i > maxline end @@ -104,7 +104,7 @@ end local draw_line_text = DocView.draw_line_text function DocView:draw_line_text(idx, x, y) - local spaces = self.lineguide_indents[idx] or -1 + local spaces = self.indentguide_indents[idx] or -1 local _, indent_size = get_indent_info(self.doc) local w = math.max(1, SCALE) local h = self:get_line_height() @@ -112,7 +112,7 @@ function DocView:draw_line_text(idx, x, y) local space_sz = font:get_width(" ") for i = 0, spaces - 1, indent_size do local color = style.guide or style.selection - local active_lvl = self.lineguide_indent_active[idx] or -1 + local active_lvl = self.indentguide_indent_active[idx] or -1 if i < active_lvl and i + indent_size >= active_lvl then color = style.guide_highlight or style.accent end -- cgit v1.2.3