aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/colorpicker.lua56
-rw-r--r--plugins/ipc.lua2
-rw-r--r--plugins/language_nix.lua87
-rw-r--r--plugins/language_rivet.lua6
-rw-r--r--plugins/minimap.lua33
-rw-r--r--plugins/settings.lua77
-rw-r--r--plugins/spellcheck.lua100
7 files changed, 300 insertions, 61 deletions
diff --git a/plugins/colorpicker.lua b/plugins/colorpicker.lua
new file mode 100644
index 0000000..c280fb6
--- /dev/null
+++ b/plugins/colorpicker.lua
@@ -0,0 +1,56 @@
+-- mod-version:3
+local command = require "core.command"
+local keymap = require "core.keymap"
+local ColorPickerDialog = require "libraries.widget.colorpickerdialog"
+
+---Get the color format of given text.
+---@param text string
+---@return "html" | "html_opacity" | "rgb"
+local function get_color_type(text)
+ local found = text:find("#%x%x%x%x%x%x%x?%x?")
+ if found then
+ found = text:find("#%x%x%x%x%x%x%x%x")
+ if found then return "html_opacity" end
+ return "html"
+ else
+ found = text:find("#%x%x%x")
+ if found then
+ return "html"
+ else
+ found = text:find(
+ "rgba?%((%d+)%D+(%d+)%D+(%d+)[%s,]-([%.%d]-)%s-%)"
+ )
+ if found then return "rgb" end
+ end
+ end
+ return "html"
+end
+
+command.add("core.docview!", {
+ ["color-picker:open"] = function(dv)
+ ---@type core.doc
+ local doc = dv.doc
+ local selection = doc:get_text(doc:get_selection())
+ local type = get_color_type(selection)
+
+ ---@type widget.colorpickerdialog
+ local picker = ColorPickerDialog(nil, selection)
+ function picker:on_apply(c)
+ local value
+ if type == "html" then
+ value = string.format("#%02X%02X%02X", c[1], c[2], c[3])
+ elseif type == "html_opacity" then
+ value = string.format("#%02X%02X%02X%02X", c[1], c[2], c[3], c[4])
+ elseif type == "rgb" then
+ value = string.format("rgba(%d, %d, %d, %.2f)", c[1], c[2], c[3], c[4]/255)
+ end
+ doc:text_input(value)
+ end
+ picker:show()
+ picker:centered()
+ end,
+})
+
+keymap.add {
+ ["ctrl+alt+k"] = "color-picker:open"
+}
diff --git a/plugins/ipc.lua b/plugins/ipc.lua
index 0f9a172..16eab5d 100644
--- a/plugins/ipc.lua
+++ b/plugins/ipc.lua
@@ -866,7 +866,7 @@ end
local system_get_time = system.get_time
system.get_time = function()
- if settings_found and not settings.ui then
+ if settings_found and settings and not settings.ui then
return system_get_time()
end
diff --git a/plugins/language_nix.lua b/plugins/language_nix.lua
new file mode 100644
index 0000000..149c2fa
--- /dev/null
+++ b/plugins/language_nix.lua
@@ -0,0 +1,87 @@
+-- mod-version:3
+-- https://nixos.wiki/wiki/Overview_of_the_Nix_Language
+local syntax = require "core.syntax"
+
+local function merge_tables(a, b)
+ for _, v in pairs(b) do
+ table.insert(a, v)
+ end
+end
+
+local default_symbols = {
+ ["import"] = "keyword2",
+ ["with"] = "keyword2",
+ ["builtins"] = "keyword2",
+ ["inherit"] = "keyword2",
+ ["assert"] = "keyword2",
+ ["let"] = "keyword2",
+ ["in"] = "keyword2",
+ ["rec"] = "keyword2",
+ ["if"] = "keyword",
+ ["else"] = "keyword",
+ ["then"] = "keyword",
+ ["true"] = "literal",
+ ["false"] = "literal",
+ ["null"] = "literal",
+}
+
+local default_patterns = {}
+
+local string_interpolation = {
+ { pattern = {"%${", "}"}, type = "keyword2", syntax = {
+ patterns = default_patterns,
+ symbols = default_symbols,
+ }},
+ { pattern = "[%S][%w]*", type = "string" },
+}
+
+merge_tables(default_patterns, {
+ { pattern = "#.*", type = "comment" },
+ { pattern = {"/%*", "%*/"}, type = "comment" },
+ { pattern = "-?%.?%d+", type = "number" },
+
+ -- interpolation
+ { pattern = {"%${", "}"}, type = "keyword2", syntax = {
+ patterns = default_patterns,
+ symbols = default_symbols,
+ }},
+ { pattern = {'"', '"', '\\'}, type = "string", syntax = {
+ patterns = string_interpolation,
+ symbols = {},
+ }},
+ { pattern = {"''", "''"}, type = "string", syntax = {
+ patterns = string_interpolation,
+ symbols = {},
+ }},
+
+ -- operators
+ { pattern = "[%+%-%?!>%*]", type = "operator" },
+ { pattern = "/ ", type = "operator" },
+ { pattern = "< ", type = "operator" },
+ { pattern = "//", type = "operator" },
+ { pattern = "&&", type = "operator" },
+ { pattern = "%->", type = "operator" },
+ { pattern = "||", type = "operator" },
+ { pattern = "==", type = "operator" },
+ { pattern = "!=", type = "operator" },
+ { pattern = ">=", type = "operator" },
+ { pattern = "<=", type = "operator" },
+
+ -- paths (function because its not used otherwise)
+ { pattern = "%.?%.?/[^%s%[%]%(%){};,:]+", type = "function" },
+ { pattern = "~/[^%s%[%]%(%){};,:]+", type = "function" },
+ { pattern = {"<", ">"}, type = "function" },
+
+ -- every other symbol
+ { pattern = "[%a%-%_][%w%-%_]*", type = "symbol" },
+ { pattern = ";%.,:", type = "normal" },
+})
+
+syntax.add {
+ name = "Nix",
+ files = {"%.nix$"},
+ comment = "#",
+ block_comment = {"/*", "*/"},
+ patterns = default_patterns,
+ symbols = default_symbols,
+}
diff --git a/plugins/language_rivet.lua b/plugins/language_rivet.lua
index 0416850..aceb5a1 100644
--- a/plugins/language_rivet.lua
+++ b/plugins/language_rivet.lua
@@ -28,11 +28,11 @@ syntax.add {
type = "number"
},
{pattern = "[A-Z][%w_]*", type = "keyword2"}, -- types
+ {pattern = "%@%s?[%a_][%w_]*", type = "literal"}, -- builtin func/var
{pattern = "[%a_][%w_]*%f[(]", type = "function"},
- {pattern = "[%a_][%w_]*!%f[(]", type = "keyword2"}, -- builtin function
{pattern = "[%a_][%w_]*", type = "symbol"},
{pattern = {"#%[", "%]"}, type = "literal"},
- {pattern = "#%s?[%a_][%w_]*", type = "comment"} -- #if/#elif/#else/#endif
+ {pattern = "#%s?[%a_][%w_]*", type = "comment"} -- if/elif/else/endif
},
symbols = {
["and"] = "keyword",
@@ -49,9 +49,11 @@ syntax.add {
["errdefer"] = "keyword",
["extend"] = "keyword",
["extern"] = "keyword",
+ ["export"] = "keyword",
["false"] = "literal",
["fn"] = "keyword",
["for"] = "keyword",
+ ["from"] = "keyword",
["if"] = "keyword",
["import"] = "keyword",
["in"] = "keyword",
diff --git a/plugins/minimap.lua b/plugins/minimap.lua
index 75eb272..ac94849 100644
--- a/plugins/minimap.lua
+++ b/plugins/minimap.lua
@@ -135,29 +135,21 @@ config.plugins.minimap = common.merge({
},
{
label = "Selection Color",
- description = "Background color of selected text in html notation eg: #FFFFFF. Leave empty to use default.",
- path = "selection_color_html",
- type = "string",
- on_apply = function(value)
- if value and value:match("#%x%x%x%x%x%x") then
- config.plugins.minimap.selection_color = { common.color(value) }
- else
- config.plugins.minimap.selection_color = nil
- end
- end
+ description = "Background color of selected text.",
+ path = "selection_color",
+ type = "color",
+ default = string.format("#%02X%02X%02X%02X",
+ style.dim[1], style.dim[2], style.dim[3], style.dim[4]
+ )
},
{
label = "Caret Color",
- description = "Background color of active line in html notation eg: #FFFFFF. Leave empty to use default.",
- path = "caret_color_html",
- type = "string",
- on_apply = function(value)
- if value and value:match("#%x%x%x%x%x%x") then
- config.plugins.minimap.caret_color = { common.color(value) }
- else
- config.plugins.minimap.caret_color = nil
- end
- end
+ description = "Background color of active line.",
+ path = "caret_color",
+ type = "color",
+ default = string.format("#%02X%02X%02X%02X",
+ style.caret[1], style.caret[2], style.caret[3], style.caret[4]
+ )
},
{
label = "Highlight Alignment",
@@ -663,4 +655,3 @@ command.add("core.docview!", {
})
return MiniMap
-
diff --git a/plugins/settings.lua b/plugins/settings.lua
index 17ce998..d3af077 100644
--- a/plugins/settings.lua
+++ b/plugins/settings.lua
@@ -9,28 +9,29 @@ local View = require "core.view"
local DocView = require "core.docview"
-- check if widget is installed before proceeding
-local widget_found, Widget = pcall(require, "widget")
+local widget_found, Widget = pcall(require, "libraries.widget")
if not widget_found then
core.error("Widget library not found: https://github.com/lite-xl/lite-xl-widgets")
- return
+ return false
end
-local Label = require "widget.label"
-local Line = require "widget.line"
-local NoteBook = require "widget.notebook"
-local Button = require "widget.button"
-local TextBox = require "widget.textbox"
-local SelectBox = require "widget.selectbox"
-local NumberBox = require "widget.numberbox"
-local Toggle = require "widget.toggle"
-local ListBox = require "widget.listbox"
-local FoldingBook = require "widget.foldingbook"
-local FontsList = require "widget.fontslist"
-local ItemsList = require "widget.itemslist"
-local KeybindingDialog = require "widget.keybinddialog"
-local Fonts = require "widget.fonts"
-local FilePicker = require "widget.filepicker"
-local MessageBox = require "widget.messagebox"
+local Label = require "libraries.widget.label"
+local Line = require "libraries.widget.line"
+local NoteBook = require "libraries.widget.notebook"
+local Button = require "libraries.widget.button"
+local TextBox = require "libraries.widget.textbox"
+local SelectBox = require "libraries.widget.selectbox"
+local NumberBox = require "libraries.widget.numberbox"
+local Toggle = require "libraries.widget.toggle"
+local ListBox = require "libraries.widget.listbox"
+local FoldingBook = require "libraries.widget.foldingbook"
+local FontsList = require "libraries.widget.fontslist"
+local ItemsList = require "libraries.widget.itemslist"
+local KeybindingDialog = require "libraries.widget.keybinddialog"
+local Fonts = require "libraries.widget.fonts"
+local FilePicker = require "libraries.widget.filepicker"
+local ColorPicker = require "libraries.widget.colorpicker"
+local MessageBox = require "libraries.widget.messagebox"
---@class plugins.settings
local settings = {}
@@ -53,7 +54,8 @@ settings.type = {
BUTTON = 6,
FONT = 7,
FILE = 8,
- DIRECTORY = 9
+ DIRECTORY = 9,
+ COLOR = 10
}
---@alias settings.types
@@ -65,6 +67,8 @@ settings.type = {
---| `settings.type.BUTTON`
---| `settings.type.FONT`
---| `settings.type.FILE`
+---| `settings.type.DIRECTORY`
+---| `settings.type.COLOR`
---Represents a setting to render on a settings pane.
---@class settings.option
@@ -1261,6 +1265,14 @@ local function add_control(pane, option, plugin_name)
file.filters = option.filters or {}
widget = file
found = true
+
+ elseif option.type == settings.type.COLOR then
+ ---@type widget.label
+ Label(pane, option.label .. ":")
+ ---@type widget.colorpicker
+ local color = ColorPicker(pane, option_value)
+ widget = color
+ found = true
end
if widget and type(path) ~= "nil" then
@@ -1624,11 +1636,13 @@ function Settings:load_keymap_settings()
end
table.sort(ordered)
+ ---@type widget.textbox
+ local textbox = TextBox(self.keybinds, "", "filter bindings...")
+
---@type widget.listbox
local listbox = ListBox(self.keybinds)
listbox.border.width = 0
- listbox:enable_expand(true)
listbox:add_column("Command")
listbox:add_column("Bindings")
@@ -1653,8 +1667,15 @@ function Settings:load_keymap_settings()
}, name)
end
- function listbox:on_row_click(idx, data)
- if not keymap_dialog:is_visible() then
+ function textbox:on_change(value)
+ listbox:filter(value)
+ end
+
+ function listbox:on_mouse_pressed(button, x, y, clicks)
+ listbox.super.on_mouse_pressed(self, button, x, y, clicks)
+ local idx = listbox:get_selected()
+ local data = listbox:get_row_data(idx)
+ if clicks == 2 and not keymap_dialog:is_visible() then
local bindings = { keymap.get_binding(data) }
keymap_dialog:set_bindings(bindings)
keymap_dialog.row_id = idx
@@ -1663,6 +1684,14 @@ function Settings:load_keymap_settings()
keymap_dialog:show()
end
end
+
+ ---@param self widget
+ function self.keybinds:update_positions()
+ textbox:set_position(0, 0)
+ textbox:set_size(self:get_width() - self.border.width * 2)
+ listbox:set_position(0, textbox:get_bottom())
+ listbox:set_size(self:get_width() - self.border.width * 2, self:get_height() - textbox:get_height())
+ end
end
function Settings:setup_about()
@@ -1819,6 +1848,10 @@ function Settings:update()
end
end
+ if self.keybinds:is_visible() then
+ self.keybinds:update_positions()
+ end
+
if self.about:is_visible() then
self.about:update_positions()
end
diff --git a/plugins/spellcheck.lua b/plugins/spellcheck.lua
index 29db94c..fbe40f9 100644
--- a/plugins/spellcheck.lua
+++ b/plugins/spellcheck.lua
@@ -5,6 +5,7 @@ local config = require "core.config"
local command = require "core.command"
local common = require "core.common"
local DocView = require "core.docview"
+local Highlighter = require "core.doc.highlighter"
local Doc = require "core.doc"
local platform_dictionary_file
@@ -24,6 +25,58 @@ local last_input_time = 0
local word_pattern = "%a+"
local words
+local spell_cache = setmetatable({}, { __mode = "k" })
+local font_canary
+local font_size_canary
+
+
+-- Move cache to make space for new lines
+local prev_insert_notify = Highlighter.insert_notify
+function Highlighter:insert_notify(line, n, ...)
+ prev_insert_notify(self, line, n, ...)
+ local blanks = { }
+ if not spell_cache[self] then
+ spell_cache[self] = {}
+ end
+ for i = 1, n do
+ blanks[i] = false
+ end
+ common.splice(spell_cache[self], line, 0, blanks)
+end
+
+
+-- Close the cache gap created by removed lines
+local prev_remove_notify = Highlighter.remove_notify
+function Highlighter:remove_notify(line, n, ...)
+ prev_remove_notify(self, line, n, ...)
+ if not spell_cache[self] then
+ spell_cache[self] = {}
+ end
+ common.splice(spell_cache[self], line, n)
+end
+
+
+-- Remove changed lines from the cache
+local prev_tokenize_line = Highlighter.tokenize_line
+function Highlighter:tokenize_line(idx, state, ...)
+ local res = prev_tokenize_line(self, idx, state, ...)
+ if not spell_cache[self] then
+ spell_cache[self] = {}
+ end
+ spell_cache[self][idx] = false
+ return res
+end
+
+local function reset_cache()
+ for i=1,#spell_cache do
+ local cache = spell_cache[i]
+ for j=1,#cache do
+ cache[j] = false
+ end
+ end
+end
+
+
local function load_dictionary()
core.add_thread(function()
local t = {}
@@ -61,7 +114,6 @@ end
local text_input = Doc.text_input
-
function Doc:text_input(...)
text_input(self, ...)
last_input_time = system.get_time()
@@ -69,7 +121,6 @@ end
local draw_line_text = DocView.draw_line_text
-
function DocView:draw_line_text(idx, x, y)
local lh = draw_line_text(self, idx, x, y)
@@ -83,20 +134,39 @@ function DocView:draw_line_text(idx, x, y)
return lh
end
- local s, e = 0, 0
- local text = self.doc.lines[idx]
-
- while true do
- s, e = text:find(word_pattern, e + 1)
- if not s then break end
- local word = text:sub(s, e):lower()
- if not words[word] and not active_word(self.doc, idx, e + 1) then
- local color = style.spellcheck_error or style.syntax.keyword2
- local x1, y1 = self:get_line_screen_position(idx, s)
- local x2, y2 = self:get_line_screen_position(idx, e + 1)
- local h = math.ceil(1 * SCALE)
- renderer.draw_rect(x1, y1 + self:get_line_height() - h, x2 - x1, h, color)
+ if font_canary ~= style.code_font
+ or font_size_canary ~= style.code_font:get_size()
+ then
+ spell_cache[self.doc.highlighter] = {}
+ font_canary = style.code_font
+ font_size_canary = style.code_font:get_size()
+ reset_cache()
+ end
+ if not spell_cache[self.doc.highlighter][idx] then
+ local calculated = {}
+ local s, e = 0, 0
+ local text = self.doc.lines[idx]
+
+ while true do
+ s, e = text:find(word_pattern, e + 1)
+ if not s then break end
+ local word = text:sub(s, e):lower()
+ if not words[word] and not active_word(self.doc, idx, e + 1) then
+ table.insert(calculated, self:get_col_x_offset(idx, s))
+ table.insert(calculated, self:get_col_x_offset(idx, e + 1))
+ end
end
+
+ spell_cache[self.doc.highlighter][idx] = calculated
+ end
+
+ local color = style.spellcheck_error or style.syntax.keyword2
+ local h = math.ceil(1 * SCALE)
+ local lh = self:get_line_height()
+ local calculated = spell_cache[self.doc.highlighter][idx]
+ for i=1,#calculated,2 do
+ local x1, x2 = calculated[i] + x, calculated[i+1] + x
+ renderer.draw_rect(x1, y + lh - h, x2 - x1, h, color)
end
return lh
end