From ca617f5317d16d0ba0af074a68ee2ce46c343889 Mon Sep 17 00:00:00 2001 From: ThaCuber <70547062+ThaCuber@users.noreply.github.com> Date: Sat, 27 May 2023 14:48:17 -0400 Subject: carets-a-lot (#237) * Update manifest.json * Add files via upload * Update manifest.json * fixed trail not actually changing color when "custom color" is turned off * added reason for for-loop around draw_char * made surrounding character display a setting, false by default * changed to common.lerp and fixed underline trail * fixed carets suddenly appearing after remaking them may be temporary * eval was not supposed to be updated * fixed trail appearing when scrolling this problem was in original motiontrail lol * `core.pop_clip_rect` doesn't have any parameters, dang it --- manifest.json | 6 +-- plugins/custom_caret.lua | 58 +++++++++++++++++++++++--- plugins/motiontrail.lua | 103 ++++++++++++++++++++++++++++++++++++----------- plugins/smoothcaret.lua | 13 +++--- 4 files changed, 142 insertions(+), 38 deletions(-) diff --git a/manifest.json b/manifest.json index 710d284..a6cd6b6 100644 --- a/manifest.json +++ b/manifest.json @@ -101,7 +101,7 @@ }, { "description": "Customize the caret in the editor", - "version": "0.2", + "version": "0.3", "path": "plugins/custom_caret.lua", "id": "custom_caret", "mod_version": "3" @@ -1037,7 +1037,7 @@ }, { "description": "Adds a motion-trail to the caret *([gif](https://user-images.githubusercontent.com/3920290/83256814-085ccb00-a1ab-11ea-9e35-e6633cbed1a9.gif))*", - "version": "0.1", + "version": "0.2", "path": "plugins/motiontrail.lua", "id": "motiontrail", "mod_version": "3" @@ -1220,7 +1220,7 @@ }, { "description": "Smooth caret animation *([gif](https://user-images.githubusercontent.com/20792268/139006049-a0ba6559-88cb-49a7-8077-4822445b4a1f.gif))*", - "version": "0.1", + "version": "0.2", "path": "plugins/smoothcaret.lua", "id": "smoothcaret", "mod_version": "3" diff --git a/plugins/custom_caret.lua b/plugins/custom_caret.lua index a8d0601..ac45f55 100644 --- a/plugins/custom_caret.lua +++ b/plugins/custom_caret.lua @@ -2,7 +2,6 @@ --[[ Author: techie-guy - Plugin to customize the caret in the editor Thanks to @Guldoman for the initial example on Discord @@ -26,10 +25,12 @@ local common = require "core.common" local config = require "core.config" local DocView = require "core.docview" + config.plugins.custom_caret = common.merge({ shape = "line", custom_color = true, - caret_color = table.pack(table.unpack(style.caret)) + caret_color = table.pack(table.unpack(style.caret)), + surrounding_chars = false, }, config.plugins.custom_caret) -- Reference to plugin config @@ -80,7 +81,14 @@ core.add_thread(function() path = "caret_color", type = "color", default = table.pack(table.unpack(style.caret)), - } + }, + { + label = "Surrounding Characters", + description = "When using block caret, whether you want to show the characters around for a better character switch.", + path = "surrounding_chars", + type ="toggle", + default = false, + }, } ---@cast settings plugins.settings @@ -88,16 +96,28 @@ core.add_thread(function() end end) +local caret_idx = 1 + +local docview_update = DocView.update +function DocView:update() + docview_update(self) + caret_idx = 1 +end + function DocView:draw_caret(x, y) local caret_width = style.caret_width local caret_height = self:get_line_height() local current_caret_shape = conf.shape local caret_color = conf.custom_color and conf.caret_color or style.caret + local font = self:get_font() + local line, col = self.doc:get_selection_idx(caret_idx) + local charw = math.ceil(font:get_width(self.doc:get_char(line, col))) + if (current_caret_shape == "block") then - caret_width = math.ceil(self:get_font():get_width("a")) + caret_width = charw elseif (current_caret_shape == "underline") then - caret_width = math.ceil(self:get_font():get_width("a")) + caret_width = charw caret_height = style.caret_width*2 y = y+self:get_line_height() else @@ -106,4 +126,32 @@ function DocView:draw_caret(x, y) end renderer.draw_rect(x, y, caret_width, caret_height, caret_color) + if current_caret_shape == "block" then + core.push_clip_rect(x, y, caret_width, caret_height) + + local function draw_char(l, c) + l = common.clamp(l, 1, #self.doc.lines ) + c = common.clamp(c, 1, #self.doc.lines[l]) + local cx,cy = self:get_line_screen_position(l, c) + renderer.draw_text( + font, self.doc:get_char(l, c), + cx, cy+self:get_line_text_y_offset(), + style.background + ) + end + + if conf.surrounding_chars then + for yo=-1, 1 do + for xo=-1, 1 do + draw_char(line+xo, col+yo) + end + end + else + draw_char(line, col) + end + + core.pop_clip_rect() + end + + caret_idx = caret_idx + 1 end diff --git a/plugins/motiontrail.lua b/plugins/motiontrail.lua index 16e7307..5c8a270 100644 --- a/plugins/motiontrail.lua +++ b/plugins/motiontrail.lua @@ -30,43 +30,100 @@ config.plugins.motiontrail = common.merge({ } }, config.plugins.motiontrail) +local cc_installed = pcall(require, 'plugins.custom_caret') +local cc_conf = config.plugins.custom_caret -local function lerp(a, b, t) - return a + (b - a) * t -end +local function get_caret_size(dv, i) + local line, col = dv.doc:get_selection_idx(i) + local chw = dv:get_font():get_width(dv.doc:get_char(line, col)) + local w = style.caret_width + local h = dv:get_line_height() + if cc_installed then + local cc_shape = cc_conf.shape + if cc_shape == "underline" or dv.doc.overwrite then + w = chw + h = style.caret_width * 2 + elseif cc_shape == "block" then + w = chw + end + end -local function get_caret_rect(dv) - local line, col = dv.doc:get_selection() - local x, y = dv:get_line_screen_position(line, col) - return x, y, style.caret_width, dv:get_line_height() + return w, h end +local caret_idx, caret_amt = 1, 0 -local last_x, last_y, last_view +local dv_update = DocView.update +function DocView:update() + self.last_pos = self.last_pos or {} + self.last_view = self.last_view or {} + self.last_doc_pos = self.last_doc_pos or {} + caret_idx = caret_idx or 1 + + -- continue from whatever caret_idx left + caret_amt = caret_amt and math.max(caret_amt, caret_idx) or 0 + for i=1, caret_amt - caret_idx do + local ri = caret_idx + i + self.last_pos[ri] = nil + self.last_view[ri] = nil + self.last_doc_pos[ri] = nil + end + caret_idx = 1 + dv_update(self) +end -local draw = DocView.draw +local dv_draw = DocView.draw +function DocView:draw() + self.draws = self.draws and self.draws + 1 or 1 + return dv_draw(self) +end -function DocView:draw(...) - draw(self, ...) +local dv_draw_caret = DocView.draw_caret +function DocView:draw_caret(x, y) if not config.plugins.motiontrail.enabled or self ~= core.active_view then + dv_draw_caret(self, x, y) return end - local x, y, w, h = get_caret_rect(self) + self.last_pos[caret_idx] = self.last_pos[caret_idx] or {} + self.last_doc_pos[caret_idx] = self.last_doc_pos[caret_idx] or {} + local line, col = self.doc:get_selection_idx(caret_idx) + + if self.draws <= 1 then + local lsx, lsy = self.last_pos[caret_idx][1] or x, self.last_pos[caret_idx][2] or y + local lsl, lsc = self.last_doc_pos[caret_idx][1], self.last_doc_pos[caret_idx][2] + local w, h = get_caret_size(self, caret_idx) + + if self.difference_in_coords and lsx == x and lsy == y then + self.difference_in_coords = false + end + + if lsl ~= line or lsc ~= col then self.difference_in_coords = true end - if last_view == self and (x ~= last_x or y ~= last_y) then - local lx = x - for i = 0, 1, 1 / config.plugins.motiontrail.steps do - local ix = lerp(x, last_x, i) - local iy = lerp(y, last_y, i) - local iw = math.max(w, math.ceil(math.abs(ix - lx))) - renderer.draw_rect(ix, iy, iw, h, style.caret) - lx = ix + if self.difference_in_coords and self.last_view[caret_idx] == self then + local lx = x + for i = 0, 1, 1 / config.plugins.motiontrail.steps do + local ix = common.lerp(x, lsx, i) + local iy = common.lerp(y, lsy, i) + if cc_installed and cc_conf.shape == "underline" or self.doc.overwrite then + iy = iy + self:get_line_height() + end + local iw = math.max(w, math.ceil(math.abs(ix - lx))) + local color = style.caret + if cc_installed and cc_conf.custom_color then + color = cc_conf.caret_color + end + renderer.draw_rect(ix, iy, iw, h, color) + lx = ix + end + core.redraw = true end - core.redraw = true end - last_view, last_x, last_y = self, x, y + self.last_pos[caret_idx][1], self.last_pos[caret_idx][2], self.last_view[caret_idx] = x, y, self + self.last_doc_pos[caret_idx][1], self.last_doc_pos[caret_idx][2] = line, col + caret_idx = caret_idx + 1 + self.draws = 0 + dv_draw_caret(self, x, y) end - diff --git a/plugins/smoothcaret.lua b/plugins/smoothcaret.lua index 5639ff2..86718de 100644 --- a/plugins/smoothcaret.lua +++ b/plugins/smoothcaret.lua @@ -31,6 +31,8 @@ config.plugins.smoothcaret = common.merge({ } }, config.plugins.smoothcaret) +local caret_idx = 1 + local docview_update = DocView.update function DocView:update() docview_update(self) @@ -96,7 +98,7 @@ function DocView:update() end -- This is used by `DocView:draw_caret` to keep track of the current caret - self.caret_idx = 1 + caret_idx = 1 end local docview_draw_caret = DocView.draw_caret @@ -106,11 +108,8 @@ function DocView:draw_caret(x, y) return end - local c = self.visible_carets[self.caret_idx] or { current = { x = x, y = y } } - local lh = self:get_line_height() - - -- We use the scroll position to move back to the position relative to the window - renderer.draw_rect(c.current.x - self.scroll.x, c.current.y - self.scroll.y, style.caret_width, lh, style.caret) + local c = self.visible_carets[caret_idx] or { current = { x = x, y = y } } + docview_draw_caret(self, c.current.x - self.scroll.x, c.current.y - self.scroll.y) - self.caret_idx = self.caret_idx + 1 + caret_idx = caret_idx + 1 end -- cgit v1.2.3