diff options
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | plugins/extend_selection_line.lua | 19 | ||||
-rw-r--r-- | plugins/force_syntax.lua | 132 | ||||
-rw-r--r-- | plugins/indent_convert.lua | 128 | ||||
-rw-r--r-- | plugins/language_julia.lua | 52 | ||||
-rw-r--r-- | plugins/minimap.lua | 18 | ||||
-rw-r--r-- | plugins/opacity.lua | 62 |
7 files changed, 403 insertions, 13 deletions
@@ -34,8 +34,10 @@ Plugin | Description [`eval`](plugins/eval.lua?raw=1) | Replaces selected Lua code with its evaluated result [`exec`](plugins/exec.lua?raw=1) | Runs selected text through shell command and replaces with result [`ephemeraldocviews`](plugins/ephemeraldocviews.lua?raw=1) | Preview tabs. Opening a doc will replace the contents of the preview tab. Marks tabs as non-preview on any change. +*[`extend_selection_line`](plugins/extend_selection_line.lua?raw=1)* | When a selection crosses multiple lines, it is drawn to the end of the screen *([screenshot](https://user-images.githubusercontent.com/2798487/140995616-89a20b55-5917-4df8-8a7c-d7c53732fa8b.png))* [`fallbackfonts`](https://github.com/takase1121/lite-fallback-fonts)* | Adds support for fallback fonts *([gif](https://raw.githubusercontent.com/takase1121/lite-fallback-fonts/master/assets/Iw18fI57J0.gif))* [`fontconfig`](plugins/fontconfig.lua?raw=1) | Allows users to load fonts with [fontconfig](https://www.freedesktop.org/software/fontconfig/fontconfig-user.html). +*[`force_syntax`](plugins/force_syntax.lua?raw=1)* | Change the syntax used for a file. [`formatter`](https://github.com/vincens2005/lite-formatters)* | formatters for various languages [`ghmarkdown`](plugins/ghmarkdown.lua?raw=1) | Opens a preview of the current markdown file in a browser window *([screenshot](https://user-images.githubusercontent.com/3920290/82754898-f7394600-9dc7-11ea-8278-2305363ed372.png))* *[`gitdiff_highlight`](https://github.com/vincens2005/lite-xl-gitdiff-highlight)** | highlight changed lines from git *([screenshot](https://raw.githubusercontent.com/vincens2005/lite-xl-gitdiff-highlight/master/screenshot.png))* @@ -44,6 +46,8 @@ Plugin | Description [`hidelinenumbers`](plugins/hidelinenumbers.lua?raw=1) | Hides the line numbers on the left of documents *([screenshot](https://user-images.githubusercontent.com/3920290/81692043-b8b19c00-9455-11ea-8d74-ad99be4b9c5f.png))* [`hidestatus`](plugins/hidestatus.lua?raw=1) | Hides the status bar at the bottom of the window ~~[`inanimate`](plugins/inanimate.lua?raw=1)~~ | Integrated in lite-xl using `config.transitions = false` ~~Disables all transition animations~~ +*[`immersive-title`](https://github.com/takase1121/lite-xl-immersive-title)** | Dark (or even Mica!) title bar for Lite XL +*[`indent_convert`](plugins/indent_convert.lua?raw=1)* | Convert between tabs and spaces indentation *[`indentguide`](plugins/indentguide.lua?raw=1)* | Adds indent guides *([screenshot](https://user-images.githubusercontent.com/3920290/79640716-f9860000-818a-11ea-9c3b-26d10dd0e0c0.png))* *[`Kinc Projects`](https://github.com/Kode-Community/kinc_plugin)** | Adds [Kinc](https://github.com/Kode/Kinc) Project generation with basic build commands(depends on [`console`](https://github.com/franko/console)) [`language_angelscript`](plugins/language_angelscript.lua?raw=1) | Syntax for the [Angelscript](https://www.angelcode.com/angelscript/) programming language @@ -118,6 +122,7 @@ Plugin | Description [`motiontrail`](plugins/motiontrail.lua?raw=1) | Adds a motion-trail to the caret *([screenshot](https://user-images.githubusercontent.com/3920290/83256814-085ccb00-a1ab-11ea-9e35-e6633cbed1a9.gif))* ~~[`nagbar`](https://github.com/takase1121/lite-nagbar)*~~ | integrated in lite-xl ~~consistent and _beautiful_ confirmation dialogs for lite and lite-xl *([gif](https://raw.githubusercontent.com/takase1121/lite-nagbar/master/assets/preview.gif))*~~ [`navigate`](plugins/navigate.lua?raw=1) | Allows moving back and forward between document positions, reducing the amount of scrolling +[`opacity`](plugins/opacity.lua?raw=1) | Change the opaqueness/transparency of `lite-xl` using shift+mousewheel or a command. [`open_ext`](plugins/open_ext.lua?raw=1) | Automatically prompts you if you tried to open a binary file in the editor [`openfilelocation`](plugins/openfilelocation.lua?raw=1) | Opens the parent directory of the current file in the file manager [`openselected`](plugins/openselected.lua?raw=1) | Opens the selected filename or url diff --git a/plugins/extend_selection_line.lua b/plugins/extend_selection_line.lua new file mode 100644 index 0000000..e986597 --- /dev/null +++ b/plugins/extend_selection_line.lua @@ -0,0 +1,19 @@ +-- mod-version:2 -- lite-xl 2.0 +local DocView = require "core.docview" +local style = require "core.style" + +local draw_line_body = DocView.draw_line_body +function DocView:draw_line_body(idx, x, y, ...) + draw_line_body(self, idx, x, y, ...) + local lh = self:get_line_height() + for _, line1, _, line2, _ in self.doc:get_selections(true) do + if idx >= line1 and idx < line2 and line1 ~= line2 then + -- draw selection from the end of the line to the end of the available space + local x1 = x + self:get_col_x_offset(idx, #self.doc.lines[idx]) + local x2 = x + self.scroll.x + self.size.x + if x2 > x1 then + renderer.draw_rect(x1, y, x2 - x1, lh, style.selection) + end + end + end +end diff --git a/plugins/force_syntax.lua b/plugins/force_syntax.lua new file mode 100644 index 0000000..dce4abc --- /dev/null +++ b/plugins/force_syntax.lua @@ -0,0 +1,132 @@ +-- mod-version:2 -- lite-xl 2.0 +local core = require "core" +local Doc = require "core.doc" +local syntax = require "core.syntax" +local command = require "core.command" +local common = require "core.common" +local style = require "core.style" +local StatusView = require "core.statusview" +local DocView = require "core.docview" + +local function doc() + if core.active_view and getmetatable(core.active_view) == DocView then return core.active_view.doc end + if core.last_active_view and getmetatable(core.last_active_view) == DocView then return core.last_active_view.doc end +end + +-- Force plaintext syntax to have a name +local plain_text_syntax = syntax.get("", "") +plain_text_syntax.name = plain_text_syntax.name or "Plain Text" + +local doc_reset_syntax = Doc.reset_syntax +function Doc:reset_syntax() + local syntax_get = syntax.get + if self.force_syntax then + syntax.get = function() return self.force_syntax end + end + doc_reset_syntax(self) + syntax.get = syntax_get +end + +local function get_syntax_name(s) + if not s then return "Undefined" end + local name = s.name + if not name then + local exts = type(s.files) == "string" and { s.files } or s.files + if exts then + name = table.concat(exts, ", ") + end + end + return name or "Undefined" +end + +local statusview_get_items = StatusView.get_items +function StatusView:get_items() + local left, right = statusview_get_items(self) + + local is_dv = core.active_view and getmetatable(core.active_view) == DocView + if not is_dv then return left, right end + + local syntax_name = get_syntax_name(doc().syntax) + + local ins = { + style.dim, + self.separator2, + style.text, + syntax_name + } + + if syntax_name then + for _,item in pairs(ins) do + table.insert(right, item) + end + end + + return left, right +end + +local function get_syntax_list() + local pt_name = plain_text_syntax.name + if doc().syntax == plain_text_syntax then + pt_name = "Current: "..pt_name + end + local list = { ["Auto detect"] = false, + [pt_name] = plain_text_syntax } + local keylist = { "Auto detect", pt_name } + + for _,s in pairs(syntax.items) do + local name = get_syntax_name(s) + local fullname = name + local i = 1 + while list[fullname] do + i = i + 1 + fullname = name.." ("..i..")" + end + if doc().syntax == s then + fullname = "Current: "..fullname + end + list[fullname] = s + table.insert(keylist, fullname) + end + + return list, keylist +end + +local function sorter(a, b) + -- Compare only syntax name + a = a:gsub("Current: ", "") + b = b:gsub("Current: ", "") + return string.upper(a) < string.upper(b) +end + +local function bias_sorter(a, b) + -- Bias towards Current and Auto detect syntax + if a:match("Current: ") then return true end + if b:match("Current: ") then return false end + if a:match("Auto detect") then return true end + if b:match("Auto detect") then return false end + return sorter(a, b) +end + +command.add("core.docview", { + ["force-syntax:select-file-syntax"] = + function() + core.command_view:enter( + "Set syntax for this file", + function(text, item) -- submit + local list, _ = get_syntax_list() + doc().force_syntax = list[item.text] + doc():reset_syntax() + end, + function(text) -- suggest + local _, keylist = get_syntax_list() + local res = common.fuzzy_match(keylist, text) + -- Force Current and Auto detect syntax to the bottom + -- if the text is empty + table.sort(res, #text == 0 and bias_sorter or sorter) + return res + end, + nil, -- cancel + nil -- validate + ) + end +}) diff --git a/plugins/indent_convert.lua b/plugins/indent_convert.lua new file mode 100644 index 0000000..c86686d --- /dev/null +++ b/plugins/indent_convert.lua @@ -0,0 +1,128 @@ +-- mod-version:2 -- lite-xl 2.0 +local core = require "core" +local config = require "core.config" +local command = require "core.command" + +config.plugins.indent_convert = { + update_indent_type = true -- set to false to avoid updating the document indent type +} + +local zero_pattern = _VERSION == "Lua 5.1" and "%z" or "\0" + +-- TODO: only set document indent type if there are no selections +-- TODO: correctly restore selections accounting for the offset caused by the conversion + +-- To replace N spaces with tabs, we match the last N spaces before the start of +-- the actual code and replace them with a tab. +-- We repeat this until we can't find any more spaces before the code. +-- The problem we encounter with this method is that if we have less than N +-- remaining spaces, those will end up at the start of the line. +-- Eg: +-- int main() { +-- __printf("Hello world\n"); +-- ___return 0; +-- } +-- +-- Becomes +-- int main() { +-- #printf("Hello world\n"); +-- _#return 0; +-- } +-- +-- Instead of +-- int main() { +-- #printf("Hello world\n"); +-- #_return 0; +-- } +-- With regex we could do something like +-- `regex.gsub("(^(?: {2})*)(?: {2})", "\\1\t")` +-- but the implementation of `regex.gsub` is very slow. +-- +-- The workaround is to find the longest possible repetition of N*X spaces and +-- use that information to replace the longest repetition of spaces starting +-- from the beginning of the line, then the second longest... +local function spaces_replacer(text, indent_size) + local spaces = string.rep(" ", indent_size) + local total = 0 + local n + local reps = 0 + -- find the longest repetition of indent_size*spaces + repeat + reps = reps + 1 + local s, _ = string.find(text, "%f[^"..zero_pattern.."\n]"..string.rep(spaces, reps)) + until not s + reps = reps - 1 + while reps > 0 do + text, n = string.gsub(text, + "(%f[^"..zero_pattern.."\n])("..string.rep(spaces, reps)..")", + "%1"..string.rep("\t", reps)) + total = total + n + reps = reps - 1 + end + return text, total +end + +local function tabs_replacer(text, indent_size) + local spaces = string.rep(" ", indent_size) + local total = 0 + local n + -- replace the last tab before the text until there aren't anymore + repeat + text, n = string.gsub(text, "(%f[^"..zero_pattern.."\n]\t*)(\t)", "%1"..spaces) + total = total + n + until n == 0 + return text, total +end + +local function replacer(doc, fn, indent_size) + return function(text) + return fn(text, indent_size) + end +end + +local function get_indent_size(doc) + local indent_size = config.indent_size + if type(doc.get_indent_info) == "function" then + -- use the new `Doc:get_indent_info` function + indent_size = select(2, doc:get_indent_info()) + end + return indent_size +end + +local function tabs_to_spaces() + local doc = core.active_view.doc + local indent_size = get_indent_size(doc) + local selections = doc.selections + doc:replace(replacer(doc, tabs_replacer, indent_size)) + doc.selections = selections + doc:sanitize_selection() + if config.plugins.indent_convert.update_indent_type then + doc.indent_info = { + type = "soft", + size = indent_size, + confirmed = true + } + end +end + +local function spaces_to_tabs() + local doc = core.active_view.doc + local indent_size = get_indent_size(doc) + local selections = doc.selections + doc:replace(replacer(doc, spaces_replacer, indent_size)) + doc.selections = selections + doc:sanitize_selection() + if config.plugins.indent_convert.update_indent_type then + doc.indent_info = { + type = "hard", + size = indent_size, + confirmed = true + } + end +end + +command.add("core.docview", { + ["indent-convert:tabs-to-spaces"] = tabs_to_spaces, + ["indent-convert:spaces-to-tabs"] = spaces_to_tabs + } +) diff --git a/plugins/language_julia.lua b/plugins/language_julia.lua index 65bc1ce..e62a9b2 100644 --- a/plugins/language_julia.lua +++ b/plugins/language_julia.lua @@ -1,5 +1,5 @@ -- mod-version:2 -- lite-xl 2.0 --- Support for the Julia programming language: +-- Support for the Julia programming language: -- Covers the most used keywords up to Julia version 1.6.4 local syntax = require "core.syntax" @@ -9,25 +9,37 @@ syntax.add { files = { "%.jl$" }, comment = "#", patterns = { - { pattern = { "#=", "=#" }, type = "comment" }, - { pattern = "#.-\n", type = "comment" }, - { pattern = { '"', '"', '\\' }, type = "string" }, - { pattern = { "`", "`", '\\' }, type = "string" }, + {pattern = {"#=", "=#"}, type="comment" }, + {pattern = "#.*$", type="comment" }, + { pattern = { 'icxx"""', '"""' }, type = "string", syntax = ".cpp" }, + { pattern = { 'cxx"""', '"""' }, type = "string", syntax = ".cpp" }, + { pattern = { 'py"""', '"""' }, type = "string", syntax = ".py" }, + { pattern = { 'js"""', '"""' }, type = "string", syntax = ".js" }, + { pattern = { 'md"""', '"""' }, type = "string", syntax = ".md" }, + { pattern = "%d%w*[%.-+*//]", type = "number" }, { pattern = "0[oO_][0-7]+", type = "number" }, { pattern = "-?0x[%x_]+", type = "number" }, + { pattern = "-?0b[%x_]+", type = "number" }, { pattern = "-?%d+_%d", 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 = "[^%d%g]%:%a*", type = "function" }, + { pattern = "[%+%-=/%*%^%%<>!~|&%:]",type = "operator"}, + { pattern = '""".*"""', type = "string" }, + { pattern = '".*"', type = "string" }, + { pattern = '[bv]".*"', type = "string" }, + { pattern = 'r".*$', type = "string" }, + { pattern = "'\\.*'", type = "string" }, + { pattern = "'.'", type = "string" }, + { pattern = "[%a_][%w_]*%f[(]", type = "function" }, + { pattern = "%g*!", type="function"}, + { pattern = "[%a_][%w_]*", type = "symbol" }, }, symbols = { -- keywords - ["abstract type"] = "keyword", ["baremodule"] = "keyword", ["begin"] = "keyword", - ["break`"] = "keyword", + ["break"] = "keyword", ["catch"] = "keyword", ["const"] = "keyword", ["continue"] = "keyword", @@ -44,24 +56,31 @@ syntax.add { ["function"] = "keyword", ["global"] = "keyword", ["if"] = "keyword", + ["in"] = "keyword", ["import"] = "keyword", ["let"] = "keyword", ["local"] = "keyword", ["macro"] = "keyword", + ["type"] = "keyword", ["module"] = "keyword", + ["mutable"] = "keyword", ["quote"] = "keyword", ["return"] = "keyword", ["try"] = "keyword", ["typeof"] = "keyword", ["using"] = "keyword", ["while"] = "keyword", - + ["where"] = "keyword", + -- types ["struct"] = "keyword2", - ["mutable struct"] = "keyword2", + ["abstract"] = "keyword2", + ["primitive"] = "keyword2", + ["mutable"] = "keyword2", ["Char"] = "keyword2", ["Bool"] = "keyword2", ["Int"] = "keyword2", + ["Integer"] = "keyword2", ["Int8"] = "keyword2", ["UInt8"] = "keyword2", ["Int16"] = "keyword2", @@ -77,10 +96,17 @@ syntax.add { ["Float64"] = "keyword2", ["Vector"] = "keyword2", ["Matrix"] = "keyword2", + ["Ref"] = "keyword2", + ["String"] = "keyword2", + ["Function"] = "keyword2", + ["Number"] = "keyword2", -- literals ["missing"] = "literal", ["true"] = "literal", ["false"] = "literal", - }, + ["nothing"] = "literal", + ["Inf"] = "literal", + ["NaN"] = "literal", + } } diff --git a/plugins/minimap.lua b/plugins/minimap.lua index b129f40..2c383b8 100644 --- a/plugins/minimap.lua +++ b/plugins/minimap.lua @@ -16,6 +16,13 @@ config.plugins.minimap = { -- how many spaces one tab is equivalent to tab_width = 4, draw_background = true, + + -- you can override these colors + selection_color = nil, + caret_color = nil, + + -- If other plugins provide per-line highlights, + -- this controls the placement. (e.g. gitdiff_highlight) highlight_align = 'left', highlight_width = 3, gutter_width = 5, @@ -222,6 +229,17 @@ DocView.draw_scrollbar = function(self) -- draw visual rect renderer.draw_rect(x, visible_y, w, scroller_height, visual_color) + -- highlight the selected lines, and the line with the caret on it + local selection_color = config.plugins.minimap.selection_color or style.dim + local caret_color = config.plugins.minimap.caret_color or style.caret + local selection_line, selection_col, selection_line2, selection_col2 = self.doc:get_selection() + local selection_y = y + (selection_line - minimap_start_line) * line_spacing + local selection2_y = y + (selection_line2 - minimap_start_line) * line_spacing + local selection_min_y = math.min(selection_y, selection2_y) + local selection_h = math.abs(selection2_y - selection_y)+1 + renderer.draw_rect(x, selection_min_y, w, selection_h, selection_color) + renderer.draw_rect(x, selection_y, w, line_spacing, caret_color) + local highlight_align = config.plugins.minimap.highlight_align local highlight_width = config.plugins.minimap.highlight_width local gutter_width = config.plugins.minimap.gutter_width diff --git a/plugins/opacity.lua b/plugins/opacity.lua new file mode 100644 index 0000000..8dd0d9a --- /dev/null +++ b/plugins/opacity.lua @@ -0,0 +1,62 @@ +-- mod-version:2 -- lite-xl 2.0 +local common = require "core.common" +local command = require "core.command" +local keymap = require "core.keymap" +local RootView = require "core.rootview" + +local opacity_on = true +local use_mousewheel = true +local opacity_steps = 0.05 +local default_opacity = 1 +local current_opacity = default_opacity + +local function set_opacity(opacity) + if not opacity_on then opacity_on = true end + current_opacity = common.clamp(opacity, 0.2, 1) + system.set_window_opacity(current_opacity) +end + +local on_mouse_wheel = RootView.on_mouse_wheel + +function RootView:on_mouse_wheel(d, ...) + if keymap.modkeys["shift"] and use_mousewheel then + if d < 0 then command.perform "opacity:decrease" end + if d > 0 then command.perform "opacity:increase" end + else + return on_mouse_wheel(self, d, ...) + end +end + +local function tog_opacity() + opacity_on = not opacity_on + if opacity_on then + system.set_window_opacity(current_opacity) + else + system.set_window_opacity(default_opacity) + end +end + +local function res_opacity() + set_opacity(default_opacity) +end + +local function inc_opacity() + set_opacity(current_opacity + opacity_steps) +end + +local function dec_opacity() + set_opacity(current_opacity - opacity_steps) +end + +command.add(nil, { + ["opacity:toggle" ] = function() tog_opacity() end, + ["opacity:reset" ] = function() res_opacity() end, + ["opacity:decrease"] = function() dec_opacity() end, + ["opacity:increase"] = function() inc_opacity() end, + ["opacity:toggle mouse wheel use"] = function() use_mousewheel = not use_mousewheel end, +}) + +keymap.add { + ["shift+f11"] = "opacity:toggle", + ["ctrl+f11"] = "opacity:toggle mouse wheel use", +} |