diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/autosave.lua | 5 | ||||
-rw-r--r-- | plugins/language_lobster.lua | 66 | ||||
-rw-r--r-- | plugins/language_sass.lua | 2 | ||||
-rw-r--r-- | plugins/language_tcl.lua | 68 | ||||
-rw-r--r-- | plugins/language_ts.lua | 73 | ||||
-rw-r--r-- | plugins/language_v.lua | 4 | ||||
-rw-r--r-- | plugins/language_yaml.lua | 57 | ||||
-rw-r--r-- | plugins/language_zig.lua | 165 | ||||
-rw-r--r-- | plugins/lfautoinsert.lua | 1 | ||||
-rw-r--r-- | plugins/linenumbers.lua | 85 | ||||
-rw-r--r-- | plugins/minimap.lua | 299 | ||||
-rw-r--r-- | plugins/smallclock.lua | 27 |
12 files changed, 716 insertions, 136 deletions
diff --git a/plugins/autosave.lua b/plugins/autosave.lua index 2759ba6..06992ea 100644 --- a/plugins/autosave.lua +++ b/plugins/autosave.lua @@ -2,7 +2,6 @@ local core = require "core" local config = require "core.config" local Doc = require "core.doc" -local DocView = require "core.docview" local command = require "core.command" -- this is used to detect the wait time local last_keypress = os.time() @@ -21,7 +20,7 @@ local function loop_for_save() looping = false end -- wait the timeout. may cause timeout to be slightly imprescise - coroutine.yield(config.autosave_timeout) + coroutine.yield(config.autosave_timeout) end end @@ -42,5 +41,5 @@ function Doc:on_text_change(type) if self.filename then updatepress() end - return on_text_change(type) + return on_text_change(self, type) end diff --git a/plugins/language_lobster.lua b/plugins/language_lobster.lua new file mode 100644 index 0000000..8b4d899 --- /dev/null +++ b/plugins/language_lobster.lua @@ -0,0 +1,66 @@ +-- mod-version:1 -- lite-xl 1.16 +local syntax = require "core.syntax" + +syntax.add { + files = "%.lobster$", + comment = "//", + patterns = { + { pattern = "//.-\n", type = "comment" }, + { pattern = { "/%*", "%*/" }, type = "comment" }, + + { pattern = "struct%s()[%a_][%w_]*", type = {"keyword", "keyword2"} }, + { pattern = "class%s()[%a_][%w_]*", type = {"keyword", "keyword2"} }, + { pattern = "import%s+from", type = "keyword" }, + + { pattern = { '"', '"', '\\' }, type = "string" }, + { pattern = { "'", "'", '\\' }, type = "string" }, + { pattern = { '"""', '"""' }, type = "string" }, + { pattern = "0x%x+", type = "number" }, + { pattern = "%d+[%d%.eE]*f?", type = "number" }, + { pattern = "%.?%d+f?", type = "number" }, + { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, + { pattern = "[%a_][%w_]*%f[(]", type = "function" }, + { pattern = "[%a_][%w_]*", type = "symbol" }, + }, + symbols = { + ["import"] = "keyword", + ["def"] = "keyword", + ["fn"] = "keyword", + ["return"] = "keyword", + ["program"] = "keyword", + ["private"] = "keyword", + ["resource"] = "keyword", + + -- not really keywords but provides control-flow constructs + ["if"] = "keyword", + ["for"] = "keyword", + ["while"] = "keyword", + ["else"] = "keyword", + + ["enum"] = "keyword", + ["enum_flags"] = "keyword", + + ["int"] = "keyword2", + ["float"] = "keyword2", + ["string"] = "keyword2", + ["any"] = "keyword2", + ["void"] = "keyword2", + + ["is"] = "keyword", + ["typeof"] = "keyword", + ["var"] = "keyword", + ["let"] = "keyword", + ["pakfile"] = "keyword", + ["switch"] = "keyword", + ["case"] = "keyword", + ["default"] = "keyword", + ["namespace"] = "keyword", + + ["not"] = "operator", + ["and"] = "operator", + ["or"] = "operator", + + ["nil"] = "literal", + }, +} + diff --git a/plugins/language_sass.lua b/plugins/language_sass.lua index ce4aa2b..8e0b43e 100644 --- a/plugins/language_sass.lua +++ b/plugins/language_sass.lua @@ -2,7 +2,7 @@ local syntax = require "core.syntax" syntax.add { - files = { "%.sass$" }, + files = { "%.sass$" ,"%.scss$"}, comment = "//", patterns = { { pattern = "/[/%*].-\n", type = "comment" }, diff --git a/plugins/language_tcl.lua b/plugins/language_tcl.lua new file mode 100644 index 0000000..31efa84 --- /dev/null +++ b/plugins/language_tcl.lua @@ -0,0 +1,68 @@ +-- mod-version:1 -- lite-xl 1.16 +local syntax = require "core.syntax" + +syntax.add { + files = { "%.tcl$" }, + comment = "#", + patterns = { + { pattern = "#.-\n", type = "comment" }, + { pattern = { '"', '"', '\\' }, type = "string" }, + { pattern = "0x%x+", type = "number" }, + { pattern = "%d+[%d%.eE]*f?", type = "number" }, + { pattern = "%.?%d+f?", type = "number" }, + { pattern = "%$[%a_][%w_]*", type = "literal" }, + { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, + { pattern = "::[%a_][%w_]*", type = "function" }, + { pattern = "[%a_][%w_]*%f[:]", type = "function" }, + { pattern = "[%a_][%w_]*", type = "symbol" }, + }, + symbols = { + ["set"] = "keyword", + ["unset"] = "keyword", + ["rename"] = "keyword", + ["upvar"] = "keyword", + ["incr"] = "keyword", + ["source"] = "keyword", + ["expr"] = "keyword", + ["gets"] = "keyword", + ["puts"] = "keyword", + ["package"] = "keyword", + ["list"] = "keyword", + ["dict"] = "keyword", + ["split"] = "join", + ["concat"] = "join", + ["lappend"] = "keyword", + ["lset"] = "keyword", + ["lassign"] = "keyword", + ["lindex"] = "keyword", + ["llength"] = "keyword", + ["lsearch"] = "keyword", + ["lrange"] = "keyword", + ["linsert"] = "keyword", + ["lreplace"] = "keyword", + ["lrepeat"] = "keyword", + ["lsort"] = "keyword", + ["lreverse"] = "keyword", + ["array"] = "keyword", + ["concat"] = "keyword", + ["regexp"] = "keyword", + ["for"] = "keyword", + ["foreach"] = "keyword", + ["while"] = "keyword", + ["case"] = "keyword", + ["proc"] = "keyword", + ["if"] = "keyword", + ["else"] = "keyword", + ["elseif"] = "keyword", + ["break"] = "keyword", + ["continue"] = "keyword", + ["return"] = "keyword", + ["eval"] = "keyword", + ["try"] = "keyword2", + ["on"] = "keyword2", + ["finally"] = "keyword2", + ["throw"] = "keyword2", + ["error"] = "keyword2", + }, +} + diff --git a/plugins/language_ts.lua b/plugins/language_ts.lua new file mode 100644 index 0000000..96cf0d3 --- /dev/null +++ b/plugins/language_ts.lua @@ -0,0 +1,73 @@ +-- mod-version:1 -- lite-xl 1.16 +-- copied from language_js, but added regex highlighting back +local syntax = require "core.syntax" + +syntax.add { + files = { "%.ts$" }, + comment = "//", + patterns = { + { pattern = "//.-\n", type = "comment" }, + { pattern = { "/%*", "%*/" }, type = "comment" }, + { pattern = { '/%g', '/', '\\' }, type = "string" }, + { pattern = { '"', '"', '\\' }, type = "string" }, + { pattern = { "'", "'", '\\' }, type = "string" }, + { pattern = { "`", "`", '\\' }, type = "string" }, + { pattern = "0x[%da-fA-F]+", type = "number" }, + { pattern = "-?%d+[%d%.eE]*", type = "number" }, + { pattern = "-?%.?%d+", type = "number" }, + { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, + { pattern = "interface%s()[%a_][%w_]*", type = {"keyword", "keyword2"} }, + { pattern = "type%s()[%a_][%w_]*", type = {"keyword", "keyword2"} }, + { pattern = "[%a_][%w_]*%f[(]", type = "function" }, + { pattern = "[%a_][%w_]*", type = "symbol" }, + }, + symbols = { + ["async"] = "keyword", + ["await"] = "keyword", + ["break"] = "keyword", + ["case"] = "keyword", + ["catch"] = "keyword", + ["class"] = "keyword", + ["const"] = "keyword", + ["continue"] = "keyword", + ["debugger"] = "keyword", + ["default"] = "keyword", + ["delete"] = "keyword", + ["do"] = "keyword", + ["else"] = "keyword", + ["export"] = "keyword", + ["extends"] = "keyword", + ["finally"] = "keyword", + ["for"] = "keyword", + ["function"] = "keyword", + ["get"] = "keyword", + ["if"] = "keyword", + ["import"] = "keyword", + ["implements"] = "keyword", + ["in"] = "keyword", + ["instanceof"] = "keyword", + ["let"] = "keyword", + ["new"] = "keyword", + ["return"] = "keyword", + ["set"] = "keyword", + ["static"] = "keyword", + ["super"] = "keyword", + ["switch"] = "keyword", + ["throw"] = "keyword", + ["try"] = "keyword", + ["typeof"] = "keyword", + ["var"] = "keyword", + ["void"] = "keyword", + ["while"] = "keyword", + ["with"] = "keyword", + ["yield"] = "keyword", + ["true"] = "literal", + ["false"] = "literal", + ["null"] = "literal", + ["undefined"] = "literal", + ["arguments"] = "keyword2", + ["Infinity"] = "keyword2", + ["NaN"] = "keyword2", + ["this"] = "keyword2", + }, +} diff --git a/plugins/language_v.lua b/plugins/language_v.lua index e4dc19b..2a580c6 100644 --- a/plugins/language_v.lua +++ b/plugins/language_v.lua @@ -45,8 +45,8 @@ syntax.add { ["match"] = "keyword", ["module"] = "keyword", ["mut"] = "keyword2", - ["none"] = "keyword", ["or"] = "keyword", + ["pub"] = "keyword", ["return"] = "keyword", ["rlock"] = "keyword", ["select"] = "keyword", @@ -63,7 +63,7 @@ syntax.add { ["true"] = "literal", ["false"] = "literal", - ["pub"] = "literal", + ["none"] = "literal", }, } diff --git a/plugins/language_yaml.lua b/plugins/language_yaml.lua new file mode 100644 index 0000000..40e19b6 --- /dev/null +++ b/plugins/language_yaml.lua @@ -0,0 +1,57 @@ +-- mod-version:1 -- lite-xl 1.16 +local syntax = require "core.syntax" + +syntax.add { + files = { "%.yml$", "%.yaml$" }, + comment = "#", + patterns = { + { pattern = { "#", "\n"}, type = "comment" }, + { pattern = { '"', '"', '\\' }, type = "string" }, + { pattern = { "'", "'", '\\' }, type = "string" }, + { pattern = "%-?%.inf", type = "number" }, + { pattern = "%.NaN", type = "number" }, + { + pattern = "%&()%g+", + type = { "keyword", "literal" } + }, + { pattern = "!%g+", type = "keyword" }, + { pattern = "<<", type = "literal" }, + { + pattern = "[%s]%*()[%w%d_]+", + type = { "keyword", "keyword2" } + }, + { + pattern = "%*()[%w%d_]+", + type = { "keyword", "literal" } + }, + { + pattern = "[%[%{]()%s*[%w%d]+%g+%s*():%s", + type = { "operator", "keyword2", "operator" } + }, + { + pattern = "[%s][%w%d]+%g+%s*():%s", + type = { "keyword2", "operator" } + }, + { + pattern = "[%w%d]+%g+%s*():%s", + type = { "literal", "operator" } + }, + { pattern = "0%d+", type = "number" }, + { pattern = "0x%x+", type = "number" }, + { pattern = "[%+%-]?%d+[,%.eE:%+%d]*%d+", type = "number" }, + { pattern = "[%*%|%!>%%]", type = "keyword" }, + { pattern = "[%-:%?%*%{%}%[%]]", type = "operator" }, + -- Everything else for keywords to work + { + pattern = "[%d%a_][%g_]*()[%]%},]", + type = { "string", "operator" } + }, + { pattern = "[%d%a_][%g_]*", type = "string" }, + }, + symbols = { + ["true"] = "number", + ["false"] = "number", + ["y"] = "number", + ["n"] = "number" + } +} diff --git a/plugins/language_zig.lua b/plugins/language_zig.lua index 2c098af..3b4c953 100644 --- a/plugins/language_zig.lua +++ b/plugins/language_zig.lua @@ -5,33 +5,41 @@ syntax.add { files = { "%.zig$" }, comment = "//", patterns = { - { pattern = "//.-\n", type = "comment" }, - { pattern = "#!.-\n", type = "comment" }, - { pattern = { '"', '"', '\\' }, type = "string" }, - { pattern = { "'", "'", '\\' }, type = "string" }, - { pattern = "-?[iuf][%d_]+", type = "keyword2" }, - { pattern = "-?\\x[%x_]+", type = "number" }, - { pattern = "-?\\u{[%x_]+}", type = "number" }, - { pattern = "-?%d+[%d%.eE]*f?", type = "number" }, - { pattern = "-?%.?%d+f?", type = "number" }, - { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, - { pattern = "[%a_][%w_]*%f[(]", type = "function" }, - { pattern = "@?[%a_][%w_]*", type = "symbol" }, + { pattern = "//.-\n", type = "comment" }, + { pattern = "\\\\.-\n", type = "string" }, + { pattern = { '"', '"', '\\' }, type = "string" }, + { pattern = { "'", "'", '\\' }, type = "string" }, + { pattern = "[iu][%d_]+", type = "keyword2" }, + { pattern = "0b[01_]+", type = "number" }, + { pattern = "0o[0-7_]+", type = "number" }, + { pattern = "0x[%x_]+", type = "number" }, + { pattern = "0x[%x_]+%.[%x_]*[pP][-+]?%d+", type = "number" }, + { pattern = "0x[%x_]+%.[%x_]*", type = "number" }, + { pattern = "0x%.[%x_]+[pP][-+]?%d+", type = "number" }, + { pattern = "0x%.[%x_]+", type = "number" }, + { pattern = "0x[%x_]+[pP][-+]?%d+", type = "number" }, + { pattern = "0x[%x_]+", type = "number" }, + { pattern = "%d[%d_]*%.[%d_]*[eE][-+]?%d+", type = "number" }, + { pattern = "%d[%d_]*%.[%d_]*", type = "number" }, + { pattern = "%d[%d_]*", type = "number" }, + { pattern = "[%+%-=/%*%^%%<>!~|&%.%?]", type = "operator" }, + { pattern = "[%a_][%w_]*()%s*%(", type = {"function", "normal"} }, + { pattern = "[A-Z][%w_]*", type = "keyword2" }, + { pattern = "[%a_][%w_]*", type = "symbol" }, + { pattern = "@()[%a_][%w_]*", type = {"operator", "function"} }, }, symbols = { ["fn"] = "keyword", - ["asm"] = "keyword", ["volatile"] = "keyword", - ["continue"] = "keyword", ["break"] = "keyword", ["switch"] = "keyword", ["for"] = "keyword", ["while"] = "keyword", - ["var"] = "keyword", ["anytype"] = "keyword", + ["anyframe"] = "keyword", ["const"] = "keyword", ["test"] = "keyword", ["packed"] = "keyword", @@ -42,146 +50,43 @@ syntax.add { ["errdefer"] = "keyword", ["align"] = "keyword", ["usingnamespace"] = "keyword", - ["noasync"] = "keyword", ["async"] = "keyword", ["await"] = "keyword", ["cancel"] = "keyword", ["suspend"] = "keyword", ["resume"] = "keyword", - ["threadlocal"] = "keyword", - ["linksection"] = "keyword", - ["callconv"] = "keyword", - ["try"] = "keyword", ["catch"] = "keyword", ["orelse"] = "keyword", ["unreachable"] = "keyword", - ["noreturn"] = "keyword", ["error"] = "keyword", ["if"] = "keyword", ["else"] = "keyword", ["return"] = "keyword", ["comptime"] = "keyword", - ["stdcallcc"] = "keyword", ["ccc"] = "keyword", ["nakedcc"] = "keyword", - ["and"] = "keyword", ["or"] = "keyword", - - -- std - ["@import"] = "keyword", - ["@cImport"] = "keyword", - - [ "@addWithOverflow" ] = "function", - [ "@alignCast" ] = "function", - [ "@alignOf" ] = "function", - [ "@as" ] = "function", - [ "@asyncCall" ] = "function", - [ "@atomicLoad" ] = "function", - [ "@atomicRmw" ] = "function", - [ "@atomicStore" ] = "function", - [ "@bitCast" ] = "function", - [ "@bitOffsetOf" ] = "function", - [ "@boolToInt" ] = "function", - [ "@bitSizeOf" ] = "function", - [ "@breakpoint" ] = "function", - [ "@mulAdd" ] = "function", - [ "@byteSwap" ] = "function", - [ "@bitReverse" ] = "function", - [ "@byteOffsetOf" ] = "function", - [ "@call" ] = "function", - [ "@cDefine" ] = "function", - [ "@cImport" ] = "function", - [ "@cInclude" ] = "function", - [ "@clz" ] = "function", - [ "@cmpxchgStrong" ] = "function", - [ "@cmpxchgWeak" ] = "function", - [ "@compileError" ] = "function", - [ "@compileLog" ] = "function", - [ "@ctz" ] = "function", - [ "@cUndef" ] = "function", - [ "@divExact" ] = "function", - [ "@divFloor" ] = "function", - [ "@divTrunc" ] = "function", - [ "@embedFile" ] = "function", - [ "@enumToInt" ] = "function", - [ "@errorName" ] = "function", - [ "@errorReturnTrace" ] = "function", - [ "@errorToInt" ] = "function", - [ "@errSetCast" ] = "function", - [ "@export" ] = "function", - [ "@fence" ] = "function", - [ "@field" ] = "function", - [ "@fieldParentPtr" ] = "function", - [ "@floatCast" ] = "function", - [ "@floatToInt" ] = "function", - [ "@Frame" ] = "function", - [ "@frame" ] = "function", - [ "@frameAddress" ] = "function", - [ "@frameSize" ] = "function", - [ "@hasDecl" ] = "function", - [ "@hasField" ] = "function", - [ "@import" ] = "function", - [ "@intCast" ] = "function", - [ "@intToEnum" ] = "function", - [ "@intToError" ] = "function", - [ "@intToFloat" ] = "function", - [ "@intToPtr" ] = "function", - [ "@memcpy" ] = "function", - [ "@memset" ] = "function", - [ "@wasmMemorySize" ] = "function", - [ "@wasmMemoryGrow" ] = "function", - [ "@mod" ] = "function", - [ "@mulWithOverflow" ] = "function", - [ "@panic" ] = "function", - [ "@popCount" ] = "function", - [ "@ptrCast" ] = "function", - [ "@ptrToInt" ] = "function", - [ "@rem" ] = "function", - [ "@returnAddress" ] = "function", - [ "@setAlignStack" ] = "function", - [ "@setCold" ] = "function", - [ "@setEvalBranchQuota" ] = "function", - [ "@setFloatMode" ] = "function", - [ "@setRuntimeSafety" ] = "function", - [ "@shlExact" ] = "function", - [ "@shlWithOverflow" ] = "function", - [ "@shrExact" ] = "function", - [ "@shuffle" ] = "function", - [ "@sizeOf" ] = "function", - [ "@splat" ] = "function", - [ "@src" ] = "function", - [ "@sqrt" ] = "function", - [ "@sin" ] = "function", - [ "@cos" ] = "function", - [ "@exp" ] = "function", - [ "@exp2" ] = "function", - [ "@log" ] = "function", - [ "@log2" ] = "function", - [ "@log10" ] = "function", - [ "@fabs" ] = "function", - [ "@floor" ] = "function", - [ "@ceil" ] = "function", - [ "@trunc" ] = "function", - [ "@round" ] = "function", - [ "@subWithOverflow" ] = "function", - [ "@tagName" ] = "function", - [ "@TagType" ] = "function", - [ "@This" ] = "function", - [ "@truncate" ] = "function", - [ "@Type" ] = "function", - [ "@typeInfo" ] = "function", - [ "@typeName" ] = "function", - [ "@TypeOf" ] = "function", - [ "@unionInit" ] = "function", + ["struct"] = "keyword", + ["enum"] = "keyword", + ["union"] = "keyword", + ["opaque"] = "keyword", + ["inline"] = "keyword", + ["allowzero"] = "keyword", + ["noalias"] = "keyword", + ["nosuspend"] = "keyword", -- types + ["f16"] = "keyword2", + ["f32"] = "keyword2", + ["f64"] = "keyword2", + ["f128"] = "keyword2", ["void"] = "keyword2", ["c_void"] = "keyword2", ["isize"] = "keyword2", diff --git a/plugins/lfautoinsert.lua b/plugins/lfautoinsert.lua index 0534aa8..f03d9af 100644 --- a/plugins/lfautoinsert.lua +++ b/plugins/lfautoinsert.lua @@ -13,6 +13,7 @@ config.lfautoinsert_map = { [":%s*\n"] = false, ["->%s*\n"] = false, ["^%s*<([^/][^%s>]*)[^>]*>%s*\n"] = "</$TEXT>", + ["^%s*{{#([^/][^%s}]*)[^}]*}}%s*\n"] = "{{/$TEXT}}", ["/%*%s*\n"] = "*/", ["c/c++"] = { file_patterns = { diff --git a/plugins/linenumbers.lua b/plugins/linenumbers.lua new file mode 100644 index 0000000..fde0a08 --- /dev/null +++ b/plugins/linenumbers.lua @@ -0,0 +1,85 @@ +-- mod-version:1 -- lite-xl 1.16 +local config = require "core.config" +local style = require "core.style" +local DocView = require "core.docview" +local common = require "core.common" +local command = require "core.command" + +local draw = DocView.draw_line_gutter +local get_width = DocView.get_gutter_width + +function DocView:draw_line_gutter(idx, x, y, width) + if not config.line_numbers and not config.relative_line_numbers then + return + end + + if config.relative_line_numbers then + + local color = style.line_number + local local_idx = idx + local align = "right" + + local l1 = self.doc:get_selection(false) + if idx == l1 then + color = style.line_number2 + if config.line_numbers then + align = "center" + else + local_idx = 0 + end + else + local_idx = math.abs(idx - l1) + end + + -- Fix for old version (<=1.16) + if width == nil then + local gpad = style.padding.x * 2 + local gw = self:get_font():get_width(#self.doc.lines) + gpad + width = gpad and gw - gpad or gw + end + + common.draw_text( + self:get_font(), + color, local_idx, align, + x + style.padding.x, + y + self:get_line_text_y_offset(), + width, self:get_line_height() + ) + else + draw(self, idx, x, y, width) + end +end + +function DocView:get_gutter_width(...) + if not config.line_numbers and not config.relative_line_numbers then + return style.padding.x + else + return get_width(self, ...) + end +end + +command.add(nil, { + ["line-numbers:toggle"] = function() + config.line_numbers = not config.line_numbers + end, + + ["line-numbers:disable"] = function() + config.line_numbers = false + end, + + ["line-numbers:enable"] = function() + config.line_numbers = true + end, + + ["relative-line-numbers:toggle"] = function() + config.relative_line_numbers = not config.relative_line_numbers + end, + + ["relative-line-numbers:enable"] = function() + config.relative_line_numbers = true + end, + + ["relative-line-numbers:disable"] = function() + config.relative_line_numbers = false + end +}) diff --git a/plugins/minimap.lua b/plugins/minimap.lua new file mode 100644 index 0000000..ecae5eb --- /dev/null +++ b/plugins/minimap.lua @@ -0,0 +1,299 @@ +-- mod-version:1 +local command = require "core.command" +local common = require "core.common" +local config = require "core.config" +local style = require "core.style" +local DocView = require "core.docview" + +-- General plugin settings +config.minimap_enabled = true +config.minimap_width = 100 +config.minimap_instant_scroll = false +config.minimap_syntax_highlight = true +config.minimap_scale = 1 + +-- how many spaces one tab is equivalent to +config.minimap_tab_width = 4 + +config.minimap_draw_background = true + +-- Configure size for rendering each char in the minimap +local char_height = 1 * SCALE * config.minimap_scale +local char_spacing = 0.8 * SCALE * config.minimap_scale +local line_spacing = 2 * SCALE * config.minimap_scale + +-- Overloaded since the default implementation adds a extra x3 size of hotspot for the mouse to hit the scrollbar. +local prev_scrollbar_overlaps_point = DocView.scrollbar_overlaps_point +DocView.scrollbar_overlaps_point = function(self, x, y) + if not config.minimap_enabled then + return prev_scrollbar_overlaps_point(self, x, y) + end + + local sx, sy, sw, sh = self:get_scrollbar_rect() + return x >= sx and x < sx + sw and y >= sy and y < sy + sh +end + +-- Helper function to determine if current file is too large to be shown fully inside the minimap area. +local function is_file_too_large(self) + local line_count = #self.doc.lines + local _, _, _, sh = self:get_scrollbar_rect() + + -- check if line count is too large to fit inside the minimap area + local max_minmap_lines = math.floor(sh / line_spacing) + return line_count > 1 and line_count > max_minmap_lines +end + +-- Overloaded with an extra check if the user clicked inside the minimap to automatically scroll to that line. +local prev_on_mouse_pressed = DocView.on_mouse_pressed +DocView.on_mouse_pressed = function(self, button, x, y, clicks) + if not config.minimap_enabled then + return prev_on_mouse_pressed(self, button, x, y, clicks) + end + + -- check if user clicked in the minimap area and jump directly to that line + -- unless they are actually trying to perform a drag + local minimap_hit = self:scrollbar_overlaps_point(x, y) + if minimap_hit then + local line_count = #self.doc.lines + local minimap_height = line_count * line_spacing + + -- check if line count is too large to fit inside the minimap area + local is_too_large = is_file_too_large(self) + if is_too_large then + local _, _, _, sh = self:get_scrollbar_rect() + minimap_height = sh + end + + -- calc which line to jump to + local dy = y - self.position.y + local jump_to_line = math.floor((dy / minimap_height) * line_count) + 1 + + local _, cy, _, cy2 = self:get_content_bounds() + local lh = self:get_line_height() + local visible_lines_count = math.max(1, (cy2 - cy) / lh) + local visible_lines_start = math.max(1, math.floor(cy / lh)) + + -- calc if user hit the currently visible area + local hit_visible_area = true + if is_too_large then + + local visible_height = visible_lines_count * line_spacing + local scroll_pos = (visible_lines_start - 1) / + (line_count - visible_lines_count - 1) + scroll_pos = math.min(1.0, scroll_pos) -- 0..1 + local visible_y = self.position.y + scroll_pos * + (minimap_height - visible_height) + + local t = (line_count - visible_lines_start) / visible_lines_count + if t <= 1 then visible_y = visible_y + visible_height * (1.0 - t) end + + if y < visible_y or y > visible_y + visible_height then + hit_visible_area = false + end + else + + -- If the click is on the currently visible line numbers, + -- ignore it since then they probably want to initiate a drag instead. + if jump_to_line < visible_lines_start or jump_to_line > visible_lines_start + + visible_lines_count then hit_visible_area = false end + end + + -- if user didn't click on the visible area (ie not dragging), scroll accordingly + if not hit_visible_area then + self:scroll_to_line(jump_to_line, false, config.minimap_instant_scroll) + return + end + + end + + return prev_on_mouse_pressed(self, button, x, y, clicks) +end + +-- Overloaded with pretty much the same logic as original DocView implementation, +-- with the exception of the dragging scrollbar delta. We want it to behave a bit snappier +-- since the "scrollbar" essentially represents the lines visible in the content view. +local prev_on_mouse_moved = DocView.on_mouse_moved +DocView.on_mouse_moved = function(self, x, y, dx, dy) + if not config.minimap_enabled then + return prev_on_mouse_moved(self, x, y, dx, dy) + end + + if self.dragging_scrollbar then + local line_count = #self.doc.lines + local lh = self:get_line_height() + local delta = lh / line_spacing * dy + + if is_file_too_large(self) then + local _, sy, _, sh = self:get_scrollbar_rect() + delta = (line_count * lh) / sh * dy + end + + self.scroll.to.y = self.scroll.to.y + delta + end + + -- we need to "hide" that the scrollbar is dragging so that View doesnt does its own scrolling logic + local t = self.dragging_scrollbar + self.dragging_scrollbar = false + local r = prev_on_mouse_moved(self, x, y, dx, dy) + self.dragging_scrollbar = t + return r +end + +-- Overloaded since we want the mouse to interact with the full size of the minimap area, +-- not juse the scrollbar. +local prev_get_scrollbar_rect = DocView.get_scrollbar_rect +DocView.get_scrollbar_rect = function(self) + if not config.minimap_enabled then return prev_get_scrollbar_rect(self) end + + return self.position.x + self.size.x - config.minimap_width * SCALE, + self.position.y, config.minimap_width * SCALE, self.size.y +end + +-- Overloaded so we can render the minimap in the "scrollbar area". +local prev_draw_scrollbar = DocView.draw_scrollbar +DocView.draw_scrollbar = function(self) + if not config.minimap_enabled then return prev_draw_scrollbar(self) end + + local x, y, w, h = self:get_scrollbar_rect() + + local highlight = self.hovered_scrollbar or self.dragging_scrollbar + local visual_color = highlight and style.scrollbar2 or style.scrollbar + + local _, cy, _, cy2 = self:get_content_bounds() + local lh = self:get_line_height() + local visible_lines_count = math.max(1, (cy2 - cy) / lh) + local visible_lines_start = math.max(1, math.floor(cy / lh)) + local scroller_height = visible_lines_count * line_spacing + local line_count = #self.doc.lines + + local visible_y = self.position.y + (visible_lines_start - 1) * line_spacing + + -- check if file is too large to fit inside the minimap area + local max_minmap_lines = math.floor(h / line_spacing) + local minimap_start_line = 1 + if is_file_too_large(self) then + + local scroll_pos = (visible_lines_start - 1) / + (line_count - visible_lines_count - 1) + scroll_pos = math.min(1.0, scroll_pos) -- 0..1, procent of visual area scrolled + + local scroll_pos_pixels = scroll_pos * (h - scroller_height) + visible_y = self.position.y + scroll_pos_pixels + + -- offset visible area if user is scrolling past end + local t = (line_count - visible_lines_start) / visible_lines_count + if t <= 1 then visible_y = visible_y + scroller_height * (1.0 - t) end + + minimap_start_line = visible_lines_start - + math.floor(scroll_pos_pixels / line_spacing) + minimap_start_line = math.max(1, math.min(minimap_start_line, + line_count - max_minmap_lines)) + end + + if config.minimap_draw_background then + renderer.draw_rect(x, y, w, h, style.minimap_background or style.background) + end + -- draw visual rect + renderer.draw_rect(x, visible_y, w, scroller_height, visual_color) + + -- time to draw the actual code, setup some local vars that are used in both highlighted and plain renderind. + local line_y = y + + -- when not using syntax highlighted rendering, just use the normal color but dim it 50%. + local color = style.syntax["normal"] + color = {color[1], color[2], color[3], color[4] * 0.5} + + -- we try to "batch" characters so that they can be rendered as just one rectangle instead of one for each. + local batch_width = 0 + local batch_start = x + local minimap_cutoff_x = x + config.minimap_width * SCALE + local batch_syntax_type = nil + local function flush_batch(type) + local old_color = color + color = style.syntax[batch_syntax_type] + if config.minimap_syntax_highlight and color ~= nil then + -- fetch and dim colors + color = {color[1], color[2], color[3], color[4] * 0.5} + else + color = old_color + end + if batch_width > 0 then + renderer.draw_rect(batch_start, line_y, batch_width, char_height, color) + end + batch_syntax_type = type + batch_start = batch_start + batch_width + batch_width = 0 + end + + -- render lines with syntax highlighting + if config.minimap_syntax_highlight then + + -- keep track of the highlight type, since this needs to break batches as well + batch_syntax_type = nil + + -- per line + local endidx = minimap_start_line + max_minmap_lines + endidx = math.min(endidx, line_count) + for idx = minimap_start_line, endidx do + batch_syntax_type = nil + batch_start = x + batch_width = 0 + + -- per token + for _, type, text in self.doc.highlighter:each_token(idx) do + -- flush prev batch + if not batch_syntax_type then batch_syntax_type = type end + if batch_syntax_type ~= type then flush_batch(type) end + + -- per character + for char in common.utf8_chars(text) do + if char == " " or char == "\n" then + flush_batch(type) + batch_start = batch_start + char_spacing + elseif char == " " then + flush_batch(type) + batch_start = batch_start + (char_spacing * config.minimap_tab_width) + elseif batch_start + batch_width > minimap_cutoff_x then + flush_batch(type) + break + else + batch_width = batch_width + char_spacing + end + + end + end + flush_batch(nil) + line_y = line_y + line_spacing + end + + else -- render lines without syntax highlighting + for idx = 1, line_count - 1 do + batch_start = x + batch_width = 0 + + for char in common.utf8_chars(self.doc.lines[idx]) do + if char == " " or char == "\n" then + flush_batch() + batch_start = batch_start + char_spacing + elseif batch_start + batch_width > minimap_cutoff_x then + flush_batch() + else + batch_width = batch_width + char_spacing + end + end + flush_batch() + line_y = line_y + line_spacing + end + + end + +end + +command.add(nil, { + ["minimap:toggle-visibility"] = function() + config.minimap_enabled = not config.minimap_enabled + end, + ["minimap:toggle-syntax-highlighting"] = function() + config.minimap_syntax_highlight = not config.minimap_syntax_highlight + end +}) diff --git a/plugins/smallclock.lua b/plugins/smallclock.lua new file mode 100644 index 0000000..5c76160 --- /dev/null +++ b/plugins/smallclock.lua @@ -0,0 +1,27 @@ +-- lite-xl 1.16 +local core = require "core" +local style = require "core.style" +local status_view = require "core.statusview" + +local time = "" + +core.add_thread(function() + while true do + local t = os.date("*t") + time = string.format("%02d:%02d", t.hour, t.min) + coroutine.yield(1) + end +end) + +local get_items = status_view.get_items + +function status_view:get_items() + local left, right = get_items(self) + local t = {style.dim, self.separator2, style.accent, time} + + for _, item in ipairs(t) do + table.insert(right, item) + end + + return left, right +end |