aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorrxi <rxi@users.noreply.github.com>2020-04-23 20:49:37 +0100
committerrxi <rxi@users.noreply.github.com>2020-04-23 20:49:37 +0100
commit676f04945010aeb2ae71325bf2d1d6f336a5e162 (patch)
tree31b2e18df5e84fbc731840e5f1b28c974eea868a /plugins
parent9049e189d49440939192874d54af15a21eebbafb (diff)
downloadlite-xl-plugins-676f04945010aeb2ae71325bf2d1d6f336a5e162.tar.gz
lite-xl-plugins-676f04945010aeb2ae71325bf2d1d6f336a5e162.zip
Moved all plugins to `plugins` dir
Diffstat (limited to 'plugins')
-rw-r--r--plugins/autowrap.lua35
-rw-r--r--plugins/bracketmatch.lua103
-rw-r--r--plugins/eval.lua23
-rw-r--r--plugins/gofmt.lua49
-rw-r--r--plugins/indentguide.lua40
-rw-r--r--plugins/language_fe.lua33
-rw-r--r--plugins/language_go.lua71
-rw-r--r--plugins/language_jiyu.lua91
-rw-r--r--plugins/language_odin.lua159
-rw-r--r--plugins/language_php.lua97
-rw-r--r--plugins/language_psql.lua90
-rw-r--r--plugins/language_rust.lua84
-rw-r--r--plugins/language_wren.lua43
-rw-r--r--plugins/macmodkeys.lua18
-rw-r--r--plugins/sort.lua20
-rw-r--r--plugins/spellcheck.lua62
-rw-r--r--plugins/titleize.lua11
-rw-r--r--plugins/togglesnakecamel.lua32
18 files changed, 1061 insertions, 0 deletions
diff --git a/plugins/autowrap.lua b/plugins/autowrap.lua
new file mode 100644
index 0000000..85d4c24
--- /dev/null
+++ b/plugins/autowrap.lua
@@ -0,0 +1,35 @@
+require "plugins.reflow"
+local config = require "core.config"
+local command = require "core.command"
+local DocView = require "core.docview"
+
+config.autowrap_files = { "%.md$", "%.txt$" }
+
+
+local on_text_input = DocView.on_text_input
+
+DocView.on_text_input = function(self, ...)
+ on_text_input(self, ...)
+
+ -- early-exit if the filename does not match a file type pattern
+ local filename = self.doc.filename or ""
+ local matched = false
+ for _, ptn in ipairs(config.autowrap_files) do
+ if filename:match(ptn) then
+ matched = true
+ break
+ end
+ end
+ if not matched then return end
+
+ -- do automatic reflow on line if we're typing at the end of the line and have
+ -- reached the line limit
+ local line, col = self.doc:get_selection()
+ local text = self.doc:get_text(line, 1, line, math.huge)
+ if #text >= config.line_limit and col > #text then
+ command.perform("doc:select-lines")
+ command.perform("reflow:reflow")
+ command.perform("doc:move-to-next-char")
+ command.perform("doc:move-to-previous-char")
+ end
+end
diff --git a/plugins/bracketmatch.lua b/plugins/bracketmatch.lua
new file mode 100644
index 0000000..b05e8ab
--- /dev/null
+++ b/plugins/bracketmatch.lua
@@ -0,0 +1,103 @@
+local core = require "core"
+local style = require "core.style"
+local config = require "core.config"
+local command = require "core.command"
+local keymap = require "core.keymap"
+local DocView = require "core.docview"
+
+local bracket_map = { ["["] = "]", ["("] = ")", ["{"] = "}" }
+
+
+local state = {}
+
+local function update_state(line_limit)
+ line_limit = line_limit or math.huge
+
+ -- reset if we don't have a document (eg. DocView isn't focused)
+ local doc = core.active_view.doc
+ if not doc then
+ state = {}
+ return
+ end
+
+ -- early exit if nothing has changed since the last call
+ local line, col = doc:get_selection()
+ if state.doc == doc and state.line == line and state.col == col
+ and state.limit == line_limit then
+ return
+ end
+
+ -- find matching rbracket if we have an lbracket
+ local line2, col2
+ local chr = doc:get_text(line, col - 1, line, col)
+ local rbracket = bracket_map[chr]
+
+ if rbracket then
+ local ptn = "[%" .. chr .. "%" .. rbracket .. "]"
+ local offset = col - 1
+ local depth = 1
+
+ for i = line, math.min(#doc.lines, line + line_limit) do
+ while offset do
+ local n = doc.lines[i]:find(ptn, offset + 1)
+ if n then
+ local match = doc.lines[i]:sub(n, n)
+ if match == chr then
+ depth = depth + 1
+ elseif match == rbracket then
+ depth = depth - 1
+ if depth == 0 then line2, col2 = i, n end
+ end
+ end
+ offset = n
+ end
+ if line2 then break end
+ offset = 0
+ end
+ end
+
+ -- update
+ state = {
+ doc = doc,
+ line = line,
+ col = col,
+ line2 = line2,
+ col2 = col2,
+ limit = line_limit,
+ }
+end
+
+
+local update = DocView.update
+
+function DocView:update(...)
+ update(self, ...)
+ update_state(100)
+end
+
+
+local draw_line_text = DocView.draw_line_text
+
+function DocView:draw_line_text(idx, x, y)
+ draw_line_text(self, idx, x, y)
+
+ if self.doc == state.doc and idx == state.line2 then
+ local color = style.bracketmatch_color or style.syntax["function"]
+ local x1 = x + self:get_col_x_offset(idx, state.col2)
+ local x2 = x + self:get_col_x_offset(idx, state.col2 + 1)
+ local h = style.divider_size
+ renderer.draw_rect(x1, y + self:get_line_height() - h, x2 - x1, h, color)
+ end
+end
+
+
+command.add("core.docview", {
+ ["bracket-match:move-to-matching"] = function()
+ update_state()
+ if state.line2 then
+ core.active_view.doc:set_selection(state.line2, state.col2)
+ end
+ end,
+})
+
+keymap.add { ["ctrl+m"] = "bracket-match:move-to-matching" }
diff --git a/plugins/eval.lua b/plugins/eval.lua
new file mode 100644
index 0000000..54e08ba
--- /dev/null
+++ b/plugins/eval.lua
@@ -0,0 +1,23 @@
+local core = require "core"
+local command = require "core.command"
+
+
+local function eval(str)
+ local fn, err = load("return " .. str)
+ if not fn then fn, err = load(str) end
+ assert(fn, err)
+ return tostring(fn())
+end
+
+
+command.add("core.docview", {
+ ["eval:insert"] = function()
+ core.command_view:enter("Evaluate And Insert Result", function(cmd)
+ core.active_view.doc:text_input(eval(cmd))
+ end)
+ end,
+
+ ["eval:replace"] = function()
+ core.active_view.doc:replace(eval)
+ end,
+})
diff --git a/plugins/gofmt.lua b/plugins/gofmt.lua
new file mode 100644
index 0000000..11c90b9
--- /dev/null
+++ b/plugins/gofmt.lua
@@ -0,0 +1,49 @@
+local core = require "core"
+local command = require "core.command"
+local keymap = require "core.keymap"
+
+local function exec(cmd)
+ local fp = io.popen(cmd, "r")
+ local res = fp:read("*a")
+ local success = fp:close()
+ return res:gsub("%\n$", ""), success
+end
+
+local function get_cmd_text(cmd, doc)
+ local active_filename = doc and system.absolute_path(doc.filename or "")
+ return exec(string.format("%s %s", cmd, active_filename))
+end
+
+local function update_doc(cmd, doc)
+ local text, success = get_cmd_text(cmd, doc)
+ if success == nil then
+ local err_text = "Command '%s' not found in the system"
+ core.error(string.format(err_text, cmd))
+ return
+ end
+
+ local sel = { doc:get_selection() }
+ doc:remove(1, 1, math.huge, math.huge)
+ doc:insert(1, 1, text)
+ doc:set_selection(table.unpack(sel))
+end
+
+command.add("core.docview", {
+ ["gofmt:gofmt"] = function()
+ update_doc("gofmt", core.active_view.doc)
+ end,
+
+ ["gofmt:goimports"] = function()
+ update_doc("goimports", core.active_view.doc)
+ end,
+
+ ["gofmt:goreturns"] = function()
+ update_doc("goreturns", core.active_view.doc)
+ end,
+})
+
+keymap.add {
+ ["ctrl+i"] = "gofmt:gofmt",
+ ["ctrl+h"] = "gofmt:goimports",
+ ["ctrl+u"] = "gofmt:goreturns",
+}
diff --git a/plugins/indentguide.lua b/plugins/indentguide.lua
new file mode 100644
index 0000000..9d903b7
--- /dev/null
+++ b/plugins/indentguide.lua
@@ -0,0 +1,40 @@
+local style = require "core.style"
+local config = require "core.config"
+local DocView = require "core.docview"
+
+
+local function get_line_spaces(doc, idx, dir)
+ local text = doc.lines[idx]
+ if not text then
+ return 0
+ end
+ local s, e = text:find("^%s*")
+ if e == #text then
+ return get_line_spaces(doc, idx + dir, dir)
+ end
+ return e - s + 1
+end
+
+
+local function get_line_indent_guide_spaces(doc, idx)
+ if doc.lines[idx]:find("^%s*\n") then
+ return math.max(
+ get_line_spaces(doc, idx - 1, -1),
+ get_line_spaces(doc, idx + 1, 1))
+ end
+ return get_line_spaces(doc, idx)
+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 sw = self:get_font():get_width(" ")
+ local h = self:get_line_height()
+ for i = 0, spaces - 1, config.indent_size do
+ local color = style.guide or style.selection
+ renderer.draw_rect(x + sw * i, y, style.divider_size, h, color)
+ end
+ draw_line_text(self, idx, x, y)
+end
diff --git a/plugins/language_fe.lua b/plugins/language_fe.lua
new file mode 100644
index 0000000..f97e73b
--- /dev/null
+++ b/plugins/language_fe.lua
@@ -0,0 +1,33 @@
+local syntax = require "core.syntax"
+
+syntax.add {
+ files = "%.fe$",
+ comment = ";",
+ patterns = {
+ { pattern = ";.-\n", type = "comment" },
+ { pattern = { '"', '"', '\\' }, type = "string" },
+ { pattern = "0x[%da-fA-F]+", type = "number" },
+ { pattern = "-?%d+[%d%.]*", type = "number" },
+ { pattern = "-?%.?%d+", type = "number" },
+ { pattern = "'", type = "symbol" },
+ { pattern = "%f[^(][^()'%s\"]+", type = "function" },
+ { pattern = "[^()'%s\"]+", type = "symbol" },
+ },
+ symbols = {
+ ["if"] = "keyword2",
+ ["let"] = "keyword2",
+ ["do"] = "keyword2",
+ ["fn"] = "keyword2",
+ ["mac"] = "keyword2",
+ ["'"] = "keyword2",
+ ["print"] = "keyword",
+ ["while"] = "keyword",
+ ["car"] = "keyword",
+ ["cdr"] = "keyword",
+ ["not"] = "keyword",
+ ["setcdr"] = "keyword",
+ ["setcar"] = "keyword",
+ ["nil"] = "literal",
+ ["t"] = "literal",
+ }
+}
diff --git a/plugins/language_go.lua b/plugins/language_go.lua
new file mode 100644
index 0000000..488725f
--- /dev/null
+++ b/plugins/language_go.lua
@@ -0,0 +1,71 @@
+local syntax = require "core.syntax"
+
+syntax.add {
+ files = { "%.go$" },
+ comment = "//",
+ patterns = {
+ { pattern = "//.-\n", type = "comment" },
+ { pattern = { "/%*", "%*/" }, type = "comment" },
+ { pattern = { '"', '"', '\\' }, type = "string" },
+ { pattern = { "`", "`", '\\' }, type = "string" },
+ { pattern = "0[oO_][0-7]+", type = "number" },
+ { pattern = "-?0x[%x_]+", type = "number" },
+ { pattern = "-?%d+_%d", type = "number" },
+ { pattern = "-?%d+[%d%.eE]*f?", type = "number" },
+ { pattern = "-?%.?%d+f?", type = "number" },
+ { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
+ { pattern = ":=", type = "operator" },
+ { pattern = "[%a_][%w_]*%f[(]", type = "function" },
+ { pattern = "[%a_][%w_]*", type = "symbol" },
+ },
+ symbols = {
+ ["if"] = "keyword",
+ ["else"] = "keyword",
+ ["elseif"] = "keyword",
+ ["for"] = "keyword",
+ ["continue"] = "keyword",
+ ["return"] = "keyword",
+ ["struct"] = "keyword",
+ ["switch"] = "keyword",
+ ["case"] = "keyword",
+ ["default"] = "keyword",
+ ["const"] = "keyword",
+ ["package"] = "keyword",
+ ["import"] = "keyword",
+ ["func"] = "keyword",
+ ["var"] = "keyword",
+ ["type"] = "keyword",
+ ["interface"] = "keyword",
+ ["select"] = "keyword",
+ ["break"] = "keyword",
+ ["range"] = "keyword",
+ ["chan"] = "keyword",
+ ["defer"] = "keyword",
+ ["go"] = "keyword",
+ ["int"] = "keyword2",
+ ["int64"] = "keyword2",
+ ["int32"] = "keyword2",
+ ["int16"] = "keyword2",
+ ["int8"] = "keyword2",
+ ["uint"] = "keyword2",
+ ["uint64"] = "keyword2",
+ ["uint32"] = "keyword2",
+ ["uint16"] = "keyword2",
+ ["uint8"] = "keyword2",
+ ["uintptr"] = "keyword2",
+ ["float64"] = "keyword2",
+ ["float32"] = "keyword2",
+ ["map"] = "keyword2",
+ ["string"] = "keyword2",
+ ["rune"] = "keyword2",
+ ["bool"] = "keyword2",
+ ["byte"] = "keyword2",
+ ["error"] = "keyword2",
+ ["complex64"] = "keyword2",
+ ["complex128"] = "keyword2",
+ ["true"] = "literal",
+ ["false"] = "literal",
+ ["nil"] = "literal",
+ },
+}
+
diff --git a/plugins/language_jiyu.lua b/plugins/language_jiyu.lua
new file mode 100644
index 0000000..1cf94dc
--- /dev/null
+++ b/plugins/language_jiyu.lua
@@ -0,0 +1,91 @@
+local syntax = require "core.syntax"
+
+syntax.add {
+ files = { "%.jiyu$", "%.jyu$" },
+ comment = "//",
+ patterns = {
+ { pattern = "//.-\n", type = "comment" },
+ { pattern = { "/%*", "%*/" }, type = "comment" },
+ { pattern = { "\"\"\"", "\"\"\"" }, type = "string" },
+ { pattern = { '"', '"', '\\' }, type = "string" },
+ { pattern = { "'", "'", '\\' }, type = "string" },
+ { pattern = "0b[0-1]+", type = "number" },
+ { pattern = "0x[%da-fA-F]+", type = "number" },
+ { pattern = "-?%d+[%d%.]*", type = "number" },
+ { pattern = "-?%.?%d+?", type = "number" },
+ { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
+ { pattern = "[<>~=+-*/]=", type = "operator" },
+ { pattern = "[..]", type = "operator" },
+ { pattern = "[%a_][%w_]*%f[(]", type = "function" },
+ { pattern = "[#@]?[%a_][%w_]*", type = "symbol" },
+ },
+ symbols = {
+ -- Keywords
+ ["func"] = "keyword",
+ ["if"] = "keyword",
+ ["else"] = "keyword",
+ ["for"] = "keyword",
+ ["while"] = "keyword",
+ ["defer"] = "keyword",
+ ["return"] = "keyword",
+ ["switch"] = "keyword",
+ ["case"] = "keyword",
+ ["break"] = "keyword",
+ ["continue"] = "keyword",
+ ["fallthrough"] = "keyword",
+ ["struct"] = "keyword",
+ ["union"] = "keyword",
+ ["enum"] = "keyword",
+ ["using"] = "keyword",
+ ["var"] = "keyword",
+ ["let"] = "keyword",
+ ["typealias"] = "keyword",
+ ["library"] = "keyword",
+ ["framework"] = "keyword",
+ ["temporary_c_vararg"] = "keyword2";
+ -- Builtin procedures and directives
+ ["cast"] = "keyword2",
+ ["sizeof"] = "keyword2",
+ ["alignof"] = "keyword2",
+ ["strideof"] = "keyword2",
+ ["offsetof"] = "keyword2",
+ ["type_of"] = "keyword2",
+ ["type_info"] = "keyword2",
+ ["#if"] = "keyword2",
+ ["#load"] = "keyword2",
+ ["#import"] = "keyword2",
+ ["#clang_import"] = "keyword2",
+ ["#file"] = "keyword2",
+ ["#filepath"] = "keyword2",
+ ["#line"] = "keyword2",
+
+ ["@c_function"] = "keyword2",
+ ["@export"] = "keyword2",
+ ["@flags"] = "keyword2",
+ ["@metaprogram"] = "keyword2",
+ -- Types
+ ["string"] = "keyword2",
+ ["int"] = "keyword2",
+ ["uint"] = "keyword2",
+ ["uint8"] = "keyword2",
+ ["uint16"] = "keyword2",
+ ["uint32"] = "keyword2",
+ ["uint64"] = "keyword2",
+ ["uint128"] = "keyword2",
+ ["int8"] = "keyword2",
+ ["int16"] = "keyword2",
+ ["int32"] = "keyword2",
+ ["int64"] = "keyword2",
+ ["int128"] = "keyword2",
+ ["float"] = "keyword2",
+ ["double"] = "keyword2",
+ ["void"] = "keyword2",
+ ["bool"] = "keyword2",
+ ["Type"] = "keyword2",
+
+ -- Literals
+ ["true"] = "literal",
+ ["false"] = "literal",
+ ["null"] = "literal",
+ }
+}
diff --git a/plugins/language_odin.lua b/plugins/language_odin.lua
new file mode 100644
index 0000000..6f393c8
--- /dev/null
+++ b/plugins/language_odin.lua
@@ -0,0 +1,159 @@
+local syntax = require "core.syntax"
+
+syntax.add {
+ files = "%.odin$",
+ comment = "//",
+ patterns = {
+ { pattern = "//.-\n", type = "comment" },
+ { pattern = { "/%*", "%*/" }, type = "comment" },
+ { pattern = { '"', '"', '\\' }, type = "string" },
+ { pattern = { "'", "'", '\\' }, type = "string" },
+ { pattern = { "`", "`", '\\' }, type = "string" },
+ { pattern = "0b[0-1]+", type = "number" },
+ { pattern = "0o[0-7]+", type = "number" },
+ { pattern = "0d[%d]+", type = "number" },
+ { pattern = "0z[%d]+", type = "number" },
+ { pattern = "0x[%da-fA-F]+", type = "number" },
+ { pattern = "-?%d+[%d%.]*", type = "number" },
+ { pattern = "-?%.?%d+?", type = "number" },
+ { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
+ { pattern = "[<>~=+-*/]=", type = "operator" },
+ { pattern = "[::][:=]", type = "operator" },
+ { pattern = "[:]", type = "operator" },
+ { pattern = "$[TE]", type = "operator" },
+ { pattern = "[%a_][%w_]*%f[(]", type = "function" },
+ { pattern = "[#@]?[%a_][%w_]*", type = "symbol" },
+ },
+ symbols = {
+ -- Keywords
+ ["package"] = "keyword",
+ ["import"] = "keyword",
+ ["foreign"] = "keyword",
+ ["when"] = "keyword",
+ ["if"] = "keyword",
+ ["else"] = "keyword",
+ ["for"] = "keyword",
+ ["defer"] = "keyword",
+ ["return"] = "keyword",
+ ["switch"] = "keyword",
+ ["case"] = "keyword",
+ ["in"] = "keyword",
+ ["notin"] = "keyword",
+ ["do"] = "keyword",
+ ["break"] = "keyword",
+ ["continue"] = "keyword",
+ ["fallthrough"] = "keyword",
+ ["proc"] = "keyword",
+ ["struct"] = "keyword",
+ ["union"] = "keyword",
+ ["enum"] = "keyword",
+ ["bit_set"] = "keyword",
+ ["map"] = "keyword",
+ ["dynamic"] = "keyword",
+ ["using"] = "keyword",
+ ["inline"] = "keyword",
+ ["no_inline"] = "keyword",
+ ["context"] = "keyword",
+ ["distinct"] = "keyword",
+ ["opaque"] = "keyword",
+ ["macro"] = "keyword", -- Reserved, not yet used
+ ["const"] = "keyword", -- Reserved, not yet used
+ -- Builtin procedures and directives
+ ["cast"] = "keyword2",
+ ["auto_cast"] = "keyword2",
+ ["transmute"] = "keyword2",
+ ["len"] = "keyword2",
+ ["cap"] = "keyword2",
+ ["size_of"] = "keyword2",
+ ["align_of"] = "keyword2",
+ ["offset_of"] = "keyword2",
+ ["typeid_of"] = "keyword2",
+ ["type_of"] = "keyword2",
+ ["type_info_of"] = "keyword2",
+ ["type_info_base"] = "keyword2",
+ ["swizzle"] = "keyword2",
+ ["complex"] = "keyword2",
+ ["real"] = "keyword2",
+ ["imag"] = "keyword2",
+ ["conj"] = "keyword2",
+ ["min"] = "keyword2",
+ ["max"] = "keyword2",
+ ["abs"] = "keyword2",
+ ["clamp"] = "keyword2",
+ ["assert"] = "keyword2",
+ ["#assert"] = "keyword2",
+ ["#location"] = "keyword2",
+ ["#caller_location"] = "keyword2",
+ ["#packed"] = "keyword2",
+ ["#raw_union"] = "keyword2",
+ ["#align"] = "keyword2",
+ ["#no_nil"] = "keyword2",
+ ["#complete"] = "keyword2",
+ ["#no_alias"] = "keyword2",
+ ["#align"] = "keyword2",
+ ["#load"] = "keyword2",
+ ["#location"] = "keyword2",
+ ["#file"] = "keyword2",
+ ["#line"] = "keyword2",
+ ["#procedure"] = "keyword2",
+ ["#defined"] = "keyword2",
+ ["#no_bounds_check"] = "keyword2",
+ ["#bounds_check"] = "keyword2",
+ ["#type"] = "keyword2",
+ ["@private"] = "keyword2",
+ -- Types
+ ["rawptr"] = "keyword2",
+ ["typeid"] = "keyword2",
+ ["any"] = "keyword2",
+ ["string"] = "keyword2",
+ ["cstring"] = "keyword2",
+ ["int"] = "keyword2",
+ ["uint"] = "keyword2",
+ ["uintptr"] = "keyword2",
+ ["rune"] = "keyword2",
+ ["byte"] = "keyword2",
+ ["u8"] = "keyword2",
+ ["u16"] = "keyword2",
+ ["u32"] = "keyword2",
+ ["u64"] = "keyword2",
+ ["u128"] = "keyword2",
+ ["i8"] = "keyword2",
+ ["i16"] = "keyword2",
+ ["i32"] = "keyword2",
+ ["i64"] = "keyword2",
+ ["i128"] = "keyword2",
+ ["f16"] = "keyword2",
+ ["f32"] = "keyword2",
+ ["f64"] = "keyword2",
+ ["u16le"] = "keyword2",
+ ["u32le"] = "keyword2",
+ ["u64le"] = "keyword2",
+ ["u128le"] = "keyword2",
+ ["i16le"] = "keyword2",
+ ["i32le"] = "keyword2",
+ ["i64le"] = "keyword2",
+ ["i128le"] = "keyword2",
+ ["u16be"] = "keyword2",
+ ["u32be"] = "keyword2",
+ ["u64be"] = "keyword2",
+ ["u128be"] = "keyword2",
+ ["i16be"] = "keyword2",
+ ["i32be"] = "keyword2",
+ ["i64be"] = "keyword2",
+ ["i128be"] = "keyword2",
+ ["complex32"] = "keyword2",
+ ["complex64"] = "keyword2",
+ ["complex128"] = "keyword2",
+ ["quaternion128"] = "keyword2",
+ ["quaternion256"] = "keyword2",
+ ["bool"] = "keyword2",
+ ["b8"] = "keyword2",
+ ["b32"] = "keyword2",
+ ["b64"] = "keyword2",
+ ["b128"] = "keyword2",
+ -- Literals
+ ["true"] = "literal",
+ ["false"] = "literal",
+ ["nil"] = "literal",
+ }
+}
diff --git a/plugins/language_php.lua b/plugins/language_php.lua
new file mode 100644
index 0000000..55597d6
--- /dev/null
+++ b/plugins/language_php.lua
@@ -0,0 +1,97 @@
+local syntax = require "core.syntax"
+
+syntax.add {
+ files = { "%.php$", "%.phtml" },
+ comment = "//",
+ patterns = {
+ { pattern = "//.-\n", type = "comment" },
+ { pattern = { "/%*", "%*/" }, type = "comment" },
+ -- I dont know why the '//' are needed but I leave it here for now
+ { pattern = { '"', '"', '\\' }, type = "string" },
+ { pattern = { "'", "'", '\\' }, type = "string" },
+ { pattern = "%\\x[%da-fA-F]+", type = "number" },
+ { pattern = "-?%d+[%d%.eE]*", type = "number" },
+ { pattern = "-?%.?%d+", type = "number" },
+ { pattern = "[%.%+%-=/%*%^%%<>!~|&]", type = "operator" },
+ { pattern = "[%a_][%w_]*%f[(]", type = "function" },
+ { pattern = "[%a_][%w_]*", type = "symbol" },
+ -- To indicate variables.
+ { pattern = "%$", type = "operator" },
+ },
+ symbols = {
+ ["return"] = "keyword",
+ ["if"] = "keyword",
+ ["else"] = "keyword",
+ ["elseif"] = "keyword",
+ ["endif"] = "keyword",
+ ["declare"] = "keyword",
+ ["enddeclare"] = "keyword",
+ ["switch"] = "keyword",
+ ["endswitch"] = "keyword",
+ ["as"] = "keyword",
+ ["do"] = "keyword",
+ ["for"] = "keyword",
+ ["endfor"] = "keyword",
+ ["foreach"] = "keyword",
+ ["endforeach"] = "keyword",
+ ["while"] = "keyword",
+ ["endwhile"] = "keyword",
+ ["switch"] = "keyword",
+ ["case"] = "keyword",
+ ["continue"] = "keyword",
+ ["default"] = "keyword",
+ ["break"] = "keyword",
+ ["exit"] = "keyword",
+ ["goto"] = "keyword",
+
+ ["catch"] = "keyword",
+ ["throw"] = "keyword",
+ ["try"] = "keyword",
+ ["finally"] = "keyword",
+
+ ["class"] = "keyword",
+ ["trait"] = "keyword",
+ ["interface"] = "keyword",
+ ["public"] = "keyword",
+ ["static"] = "keyword",
+ ["protected"] = "keyword",
+ ["private"] = "keyword",
+ ["abstract"] = "keyword",
+ ["final"] = "keyword",
+
+ ["function"] = "keyword2",
+ ["global"] = "keyword2",
+ ["var"] = "keyword2",
+ ["const"] = "keyword2",
+ ["bool"] = "keyword2",
+ ["boolean"] = "keyword2",
+ ["int"] = "keyword2",
+ ["integer"] = "keyword2",
+ ["real"] = "keyword2",
+ ["double"] = "keyword2",
+ ["float"] = "keyword2",
+ ["string"] = "keyword2",
+ ["array"] = "keyword2",
+ ["object"] = "keyword2",
+ ["callable"] = "keyword2",
+ ["iterable"] = "keyword2",
+
+ ["namespace"] = "keyword2",
+ ["extends"] = "keyword2",
+ ["implements"] = "keyword2",
+ ["instanceof"] = "keyword2",
+ ["require"] = "keyword2",
+ ["require_once"] = "keyword2",
+ ["include"] = "keyword2",
+ ["include_once"] = "keyword2",
+ ["use"] = "keyword2",
+ ["new"] = "keyword2",
+ ["clone"] = "keyword2",
+
+ ["true"] = "literal",
+ ["false"] = "literal",
+ ["NULL"] = "literal",
+ ["parent"] = "literal",
+ ["self"] = "literal",
+ },
+}
diff --git a/plugins/language_psql.lua b/plugins/language_psql.lua
new file mode 100644
index 0000000..7c6c4b7
--- /dev/null
+++ b/plugins/language_psql.lua
@@ -0,0 +1,90 @@
+local syntax = require "core.syntax"
+
+-- In sql symbols can be lower case and upper case
+local keywords = {
+ "CREATE", "SELECT", "INSERT", "INTO", "UPDATE",
+ "DELETE", "TABLE", "DROP", "VALUES", "NOT",
+ "NULL", "PRIMARY", "KEY", "REFERENCES",
+ "DEFAULT", "UNIQUE", "CONSTRAINT", "CHECK",
+ "ON", "EXCLUDE", "WITH", "USING", "WHERE",
+ "GROUP", "BY", "HAVING", "DISTINCT", "LIMIT",
+ "OFFSET", "ONLY", "CROSS", "JOIN", "INNER",
+ "LEFT", "RIGHT", "FULL", "OUTER", "NATURAL",
+ "AND", "OR", "AS", "ORDER", "ORDINALITY",
+ "UNNEST", "FROM", "VIEW", "RETURNS", "SETOF",
+ "LANGUAGE", "SQL", "LIKE", "LATERAL",
+ "INTERVAL", "PARTITION", "UNION", "INTERSECT",
+ "EXCEPT", "ALL", "ASC", "DESC", "NULLS",
+ "FIRST", "LAST", "IN", "RECURSIVE", "ARRAY",
+ "RETURNING", "SET", "ALSO", "INSTEAD",
+ "ALTER", "SEQUENCE", "OWNED", "AT", "ZONE",
+ "WITHOUT", "TO", "TIMEZONE", "TYPE", "ENUM",
+ "DOCUMENT", "XMLPARSE", "XMLSERIALIZE",
+ "CONTENT", "OPTION", "INDEX", "ANY",
+ "EXTENSION", "ISNULL", "NOTNULL", "UNKNOWN",
+ "CASE", "THEN", "WHEN", "ELSE", "END",
+ "ROWS", "BETWEEN", "UNBOUNDED", "PRECEDING",
+ "UNBOUNDED", "FOLLOWING", "EXISTS", "SOME",
+ "COLLATION", "FOR", "TRIGGER", "BEFORE",
+ "EACH", "ROW", "EXECUTE", "PROCEDURE",
+ "FUNCTION", "DECLARE", "BEGIN", "LOOP",
+ "RAISE", "NOTICE", "LOOP", "EVENT",
+ "OPERATOR", "DOMAIN", "VARIADIC", "FOREIGN"
+}
+
+local types = {
+ "BIGINT", "INT8", "BIGSERIAL", "SERIAL8",
+ "BIT", "VARBIT", "BOOLEAN", "BOOL", "BOX",
+ "BYTEA", "CHARACTER", "CHAR", "VARCHAR",
+ "CIDR", "CIRCLE", "DATE", "DOUBLE",
+ "PRECISION", "FLOAT8", "INET", "INTEGER",
+ "INT", "INT4", "INTERVAL", "JSON", "JSONB",
+ "LINE", "LSEG", "MACADDR", "MONEY", "NUMERIC",
+ "DECIMAL", "PATH", "POINT", "POLYGON", "REAL",
+ "FLOAT4", "INT2", "SMALLINT", "SMALLSERIAL",
+ "SERIAL2", "SERIAL", "SERIAL4", "TEXT",
+ "TIME", "TIMEZ", "TIMESTAMP", "TIMESTAMPZ",
+ "TSQUERY", "TSVECTOR", "TXID_SNAPSHOT",
+ "UUID", "XML", "INT4RANGE", "INT8RANGE",
+ "NUMRANGE", "TSRANGE", "TSTZRANGE",
+ "DATERANGE", "PG_LSN"
+}
+
+local literals = {
+ "FALSE", "TRUE", "CURRENT_TIMESTAMP",
+ "CURRENT_TIME", "CURRENT_DATE", "LOCALTIME",
+ "LOCALTIMESTAMP"
+}
+
+local symbols = {}
+for _, keyword in ipairs(keywords) do
+ symbols[keyword:lower()] = "keyword"
+ symbols[keyword] = "keyword"
+end
+
+for _, type in ipairs(types) do
+ symbols[type:lower()] = "keyword2"
+ symbols[type] = "keyword2"
+end
+
+for _, literal in ipairs(literals) do
+ symbols[literal:lower()] = "literal"
+ symbols[literal] = "literal"
+end
+
+syntax.add {
+ files = { "%.sql$", "%.psql$" },
+ comment = "--",
+ patterns = {
+ { pattern = "%-%-.-\n", type = "comment" },
+ { pattern = { "/%*", "%*/" }, type = "comment" },
+ { pattern = { "'", "'", '\\' }, type = "string" },
+ { 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 = symbols,
+}
+
diff --git a/plugins/language_rust.lua b/plugins/language_rust.lua
new file mode 100644
index 0000000..321efc2
--- /dev/null
+++ b/plugins/language_rust.lua
@@ -0,0 +1,84 @@
+local syntax = require "core.syntax"
+
+syntax.add {
+ files = { "%.rs$" },
+ comment = "//",
+ patterns = {
+ { pattern = "//.-\n", type = "comment" },
+ { pattern = { "/%*", "%*/" }, type = "comment" },
+ { pattern = { '"', '"', '\\' }, type = "string" },
+ { pattern = { "`", "`", '\\' }, type = "string" },
+ { pattern = "0[oO_][0-7]+", type = "number" },
+ { pattern = "-?0x[%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" },
+ },
+ symbols = {
+ ["as"] = "keyword",
+ ["async"] = "keyword",
+ ["await"] = "keyword",
+ ["break"] = "keyword",
+ ["const"] = "keyword",
+ ["continue"] = "keyword",
+ ["crate"] = "keyword",
+ ["dyn"] = "keyword",
+ ["else"] = "keyword",
+ ["enum"] = "keyword",
+ ["extern"] = "keyword",
+ ["false"] = "keyword",
+ ["fn"] = "keyword",
+ ["for"] = "keyword",
+ ["if"] = "keyword",
+ ["impl"] = "keyword",
+ ["in"] = "keyword",
+ ["let"] = "keyword",
+ ["loop"] = "keyword",
+ ["match"] = "keyword",
+ ["mod"] = "keyword",
+ ["move"] = "keyword",
+ ["mut"] = "keyword",
+ ["pub"] = "keyword",
+ ["ref"] = "keyword",
+ ["return"] = "keyword",
+ ["Self"] = "keyword",
+ ["self"] = "keyword",
+ ["static"] = "keyword",
+ ["struct"] = "keyword",
+ ["super"] = "keyword",
+ ["trait"] = "keyword",
+ ["true"] = "keyword",
+ ["type"] = "keyword",
+ ["unsafe"] = "keyword",
+ ["use"] = "keyword",
+ ["where"] = "keyword",
+ ["while"] = "keyword",
+ ["i32"] = "keyword2",
+ ["i64"] = "keyword2",
+ ["i128"] = "keyword2",
+ ["i16"] = "keyword2",
+ ["i8"] = "keyword2",
+ ["u16"] = "keyword2",
+ ["u32"] = "keyword2",
+ ["u64"] = "keyword2",
+ ["usize"] = "keyword2",
+ ["isize"] = "keyword2",
+ ["f32"] = "keyword2",
+ ["f64"] = "keyword2",
+ ["f128"] = "keyword2",
+ ["String"] = "keyword2",
+ ["&str"] = "keyword2",
+ ["bool"] = "keyword2",
+ ["true"] = "literal",
+ ["false"] = "literal",
+ ["None"] = "literal",
+ ["Some"] = "literal",
+ ["Option"] = "literal",
+ ["Result"] = "literal",
+ },
+}
+
+
diff --git a/plugins/language_wren.lua b/plugins/language_wren.lua
new file mode 100644
index 0000000..ccd53db
--- /dev/null
+++ b/plugins/language_wren.lua
@@ -0,0 +1,43 @@
+local syntax = require "core.syntax"
+
+syntax.add {
+ files = { "%.wren$" },
+ comment = "//",
+ patterns = {
+ { pattern = "//.-\n", type = "comment" },
+ { pattern = { "/%*", "%*/" }, type = "comment" },
+ { pattern = { '"', '"', '\\' }, type = "string" },
+ { pattern = { "'", "'", '\\' }, type = "string" },
+ { pattern = "-?%.?%d+", type = "number" },
+ { pattern = "%.%.%.?", type = "operator" },
+ { pattern = "[<>!=]=", type = "operator" },
+ { pattern = "[%+%-=/%*%^%%<>!~|&?:]", type = "operator" },
+ { pattern = "[%a_][%w_]*%s*%f[(\"{]", type = "function" },
+ { pattern = "[%a_][%w_]*", type = "symbol" },
+ },
+ symbols = {
+ ["break"] = "keyword",
+ ["class"] = "keyword",
+ ["construct"] = "keyword",
+ ["else"] = "keyword",
+ ["false"] = "keyword",
+ ["for"] = "keyword",
+ ["foreign"] = "keyword",
+ ["if"] = "keyword",
+ ["import"] = "keyword",
+ ["in"] = "keyword",
+ ["is"] = "keyword",
+ ["null"] = "keyword",
+ ["return"] = "keyword",
+ ["static"] = "keyword",
+ ["super"] = "keyword",
+ ["this"] = "keyword",
+ ["true"] = "keyword",
+ ["var"] = "keyword",
+ ["while"] = "keyword",
+ ["this"] = "keyword2",
+ ["true"] = "literal",
+ ["false"] = "literal",
+ ["null"] = "literal",
+ },
+} \ No newline at end of file
diff --git a/plugins/macmodkeys.lua b/plugins/macmodkeys.lua
new file mode 100644
index 0000000..69028ab
--- /dev/null
+++ b/plugins/macmodkeys.lua
@@ -0,0 +1,18 @@
+local keymap = require "core.keymap"
+
+local on_key_pressed = keymap.on_key_pressed
+local on_key_released = keymap.on_key_released
+
+local function remap_key(k)
+ return k:gsub("command", "ctrl")
+ :gsub("option", "alt")
+end
+
+function keymap.on_key_pressed(k)
+ return on_key_pressed(remap_key(k))
+end
+
+function keymap.on_key_released(k)
+ return on_key_released(remap_key(k))
+end
+
diff --git a/plugins/sort.lua b/plugins/sort.lua
new file mode 100644
index 0000000..e104043
--- /dev/null
+++ b/plugins/sort.lua
@@ -0,0 +1,20 @@
+local core = require "core"
+local command = require "core.command"
+
+local function split_lines(text)
+ local res = {}
+ for line in (text .. "\n"):gmatch("(.-)\n") do
+ table.insert(res, line)
+ end
+ return res
+end
+
+command.add("core.docview", {
+ ["sort:sort"] = function()
+ core.active_view.doc:replace(function(text)
+ local lines = split_lines(text)
+ table.sort(lines, function(a, b) return a:lower() < b:lower() end)
+ return table.concat(lines, "\n")
+ end)
+ end,
+})
diff --git a/plugins/spellcheck.lua b/plugins/spellcheck.lua
new file mode 100644
index 0000000..bb6f835
--- /dev/null
+++ b/plugins/spellcheck.lua
@@ -0,0 +1,62 @@
+local core = require "core"
+local style = require "core.style"
+local config = require "core.config"
+local command = require "core.command"
+local DocView = require "core.docview"
+
+config.spellcheck_files = { "%.txt$", "%.md$", "%.markdown$" }
+config.dictionary_file = "/usr/share/dict/words"
+
+local words
+
+core.add_thread(function()
+ local t = {}
+ local i = 0
+ for line in io.lines(config.dictionary_file) do
+ for word in line:gmatch("%a+") do
+ t[word:lower()] = true
+ end
+ i = i + 1
+ if i % 1000 == 0 then coroutine.yield() end
+ end
+ words = t
+ core.redraw = true
+ core.log_quiet("Finished loading dictionary file: \"%s\"", config.dictionary_file)
+end)
+
+
+local function matches_any(filename, ptns)
+ for _, ptn in ipairs(ptns) do
+ if filename:find(ptn) then return true end
+ end
+end
+
+
+local draw_line_text = DocView.draw_line_text
+
+function DocView:draw_line_text(idx, x, y)
+ draw_line_text(self, idx, x, y)
+
+ if not words
+ or not matches_any(self.doc.filename or "", config.spellcheck_files) then
+ return
+ end
+
+ local s, e = 0, 0
+ local text = self.doc.lines[idx]
+ local l, c = self.doc:get_selection()
+
+ while true do
+ s, e = text:find("%a+", e + 1)
+ if not s then break end
+ local word = text:sub(s, e):lower()
+ if not words[word] and not (l == idx and c == e + 1) then
+ local color = style.spellcheck_error or style.syntax.keyword2
+ local x1 = x + self:get_col_x_offset(idx, s)
+ local x2 = x + self:get_col_x_offset(idx, e + 1)
+ local h = style.divider_size
+ renderer.draw_rect(x1, y + self:get_line_height() - h, x2 - x1, h, color)
+ end
+ end
+end
+
diff --git a/plugins/titleize.lua b/plugins/titleize.lua
new file mode 100644
index 0000000..2e4b52a
--- /dev/null
+++ b/plugins/titleize.lua
@@ -0,0 +1,11 @@
+local core = require "core"
+local command = require "core.command"
+
+command.add("core.docview", {
+ ["titleize:titleize"] = function()
+ core.active_view.doc:replace(function(text)
+ return text:gsub("%f[%w](%w)", string.upper)
+ end)
+ end,
+})
+
diff --git a/plugins/togglesnakecamel.lua b/plugins/togglesnakecamel.lua
new file mode 100644
index 0000000..236c22e
--- /dev/null
+++ b/plugins/togglesnakecamel.lua
@@ -0,0 +1,32 @@
+local core = require "core"
+local command = require "core.command"
+local keymap = require "core.keymap"
+
+
+local function f(x, y)
+ return x .. "_" .. string.lower(y)
+end
+
+
+local function toggle(symbol)
+ if not symbol:match("[a-z]") then
+ return
+ elseif symbol:match("_") then
+ return symbol:gsub("_(.)", string.upper)
+ elseif symbol:match("^[a-z]") then
+ return symbol:gsub("(.)([A-Z])", f):lower()
+ end
+end
+
+
+command.add("core.docview", {
+ ["toggle-snake-camel:toggle"] = function()
+ core.active_view.doc:replace(function(text)
+ return text:gsub("[%w][%w%d_]*", toggle)
+ end)
+ end,
+})
+
+keymap.add {
+ ["f6"] = "toggle-snake-camel:toggle",
+}