aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--plugins/rainbowparen.lua58
2 files changed, 59 insertions, 0 deletions
diff --git a/README.md b/README.md
index 502e1ed..0836c06 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,7 @@ Plugin | Description
[`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
[`projectmanager`](plugins/projectmanager.lua?raw=1) | Save projects and load/reload them quickly
+[`rainbowparen`](plugins/rainbowparen.lua?raw=1) | Show nesting of parentheses with rainbow colours
[`scale`](plugins/scale.lua?raw=1) | Provides support for dynamically adjusting the scale of the code font / UI (`ctrl+-`, `ctrl+=`)
[`scalestatus`](plugins/scalestatus.lua?raw=1) | Displays current scale (zoom) in status view (depends on scale plugin)
[`selectionhighlight`](plugins/selectionhighlight.lua?raw=1) | Highlights regions of code that match the current selection *([screenshot](https://user-images.githubusercontent.com/3920290/80710883-5f597c80-8ae7-11ea-97f0-76dfacc08439.png))*
diff --git a/plugins/rainbowparen.lua b/plugins/rainbowparen.lua
new file mode 100644
index 0000000..b2689f0
--- /dev/null
+++ b/plugins/rainbowparen.lua
@@ -0,0 +1,58 @@
+local tokenizer = require "core.tokenizer"
+local style = require "core.style"
+local common = require "core.common"
+
+local tokenize = tokenizer.tokenize
+local closers = {
+ ["("] = ")",
+ ["["] = "]",
+ ["{"] = "}"
+}
+local function parenstyle(parenstack)
+ return "paren" .. ((#parenstack % 5) + 1)
+end
+function tokenizer.tokenize(syntax, text, state)
+ state = state or {}
+ local res, istate = tokenize(syntax, text, state.istate)
+ local parenstack = state.parenstack or ""
+ local newres = {}
+ -- split parens out
+ -- the stock tokenizer can't do this because it merges identical adjacent tokens
+ for i, type, text in tokenizer.each_token(res) do
+ if type == "normal" or type == "symbol" then
+ for normtext1, paren, normtext2 in text:gmatch("([^%(%[{}%]%)]*)([%(%[{}%]%)]?)([^%(%[{}%]%)]*)") do
+ if #normtext1 > 0 then
+ table.insert(newres, type)
+ table.insert(newres, normtext1)
+ end
+ if #paren > 0 then
+ if paren == parenstack:sub(-1) then -- expected closer
+ parenstack = parenstack:sub(1, -2)
+ table.insert(newres, parenstyle(parenstack))
+ elseif closers[paren] then -- opener
+ table.insert(newres, parenstyle(parenstack))
+ parenstack = parenstack .. closers[paren]
+ else -- unexpected closer
+ table.insert(newres, "paren_unbalanced")
+ end
+ table.insert(newres, paren)
+ end
+ if #normtext2 > 0 then
+ table.insert(newres, type)
+ table.insert(newres, normtext2)
+ end
+ end
+ else
+ table.insert(newres, type)
+ table.insert(newres, text)
+ end
+ end
+ return newres, { parenstack = parenstack, istate = istate }
+end
+
+style.syntax.paren_unbalanced = style.syntax.paren_unbalanced or { common.color "#DC0408" }
+style.syntax.paren1 = style.syntax.paren1 or { common.color "#FC6F71"}
+style.syntax.paren2 = style.syntax.paren2 or { common.color "#fcb053"}
+style.syntax.paren3 = style.syntax.paren3 or { common.color "#fcd476"}
+style.syntax.paren4 = style.syntax.paren4 or { common.color "#52dab2"}
+style.syntax.paren5 = style.syntax.paren5 or { common.color "#5a98cf"}