Added addons folder with plugins and color schemes
This commit is contained in:
parent
fb3d36da43
commit
9908e129a6
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#073642" }
|
||||
style.background2 = { common.color "#073642" }
|
||||
style.background3 = { common.color "#073642" }
|
||||
style.text = { common.color "#00d1d1" }
|
||||
style.caret = { common.color "#f053f3" }
|
||||
style.accent = { common.color "#f053f3" }
|
||||
style.dim = { common.color "#586e75" }
|
||||
style.divider = { common.color "#6c71c4" }
|
||||
style.selection = { common.color "#415256" }
|
||||
style.line_number = { common.color "#586e75" }
|
||||
style.line_number2 = { common.color "#f053f3" }
|
||||
style.line_highlight = { common.color "#415256" }
|
||||
style.scrollbar = { common.color "#6c71c4" }
|
||||
style.scrollbar2 = { common.color "#6c71c4" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#00d1d1" }
|
||||
style.syntax["symbol"] = { common.color "#00ff7f" }
|
||||
style.syntax["comment"] = { common.color "#6c71c4" }
|
||||
style.syntax["keyword"] = { common.color "#6c71c4" }
|
||||
style.syntax["keyword2"] = { common.color "#6c71c4" }
|
||||
style.syntax["number"] = { common.color "#00ff7f" }
|
||||
style.syntax["literal"] = { common.color "#1586d2" }
|
||||
style.syntax["string"] = { common.color "#f7f97d" }
|
||||
style.syntax["operator"] = { common.color "#00ff7f" }
|
||||
style.syntax["function"] = { common.color "#55ffff" }
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#282a36" }
|
||||
style.background2 = { common.color "#21222b" }
|
||||
style.background3 = { common.color "#21222b" }
|
||||
style.text = { common.color "#7b81a6" }
|
||||
style.caret = { common.color "#f8f8f0" }
|
||||
style.accent = { common.color "#8be9fd" }
|
||||
style.dim = { common.color "#4f5873" }
|
||||
style.divider = { common.color "#1f2029" }
|
||||
style.selection = { common.color "#44475a" }
|
||||
style.line_number = { common.color "#53576e" }
|
||||
style.line_number2 = { common.color "#f8f8f0" }
|
||||
style.line_highlight = { common.color "#313442" }
|
||||
style.scrollbar = { common.color "#44475a" }
|
||||
style.scrollbar2 = { common.color "#ff79c6" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#f8f8f2" }
|
||||
style.syntax["symbol"] = { common.color "#f8f8f2" }
|
||||
style.syntax["comment"] = { common.color "#6272a4" }
|
||||
style.syntax["keyword"] = { common.color "#ff79c6" }
|
||||
style.syntax["keyword2"] = { common.color "#ff79c6" }
|
||||
style.syntax["number"] = { common.color "#bd93f9" }
|
||||
style.syntax["literal"] = { common.color "#f1fa8c" }
|
||||
style.syntax["string"] = { common.color "#f1fa8c" }
|
||||
style.syntax["operator"] = { common.color "#ff79c6" }
|
||||
style.syntax["function"] = { common.color "#50fa7b" }
|
|
@ -0,0 +1,37 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
math.randomseed(os.time())
|
||||
|
||||
local color = {
|
||||
math.random(90, 255),
|
||||
math.random(90, 255),
|
||||
math.random(90, 255)
|
||||
}
|
||||
|
||||
style.background = { common.color "#151515" }
|
||||
style.background2 = { common.color "#151515" }
|
||||
style.background3 = { common.color "#151515" }
|
||||
style.text = { common.color "#707070" }
|
||||
style.caret = { common.color "#dfdfdf" }
|
||||
style.accent = { common.color "#d0d0d0" }
|
||||
style.dim = { common.color "#303030" }
|
||||
style.divider = { common.color "#151515" }
|
||||
style.selection = { common.color "#303030" }
|
||||
style.line_number = { common.color "#252525" }
|
||||
style.line_number2 = { common.color "#444444" }
|
||||
style.line_highlight = { common.color "#101010" }
|
||||
style.scrollbar = { common.color "#252525" }
|
||||
style.scrollbar2 = { common.color "#444444" }
|
||||
|
||||
style.syntax = {}
|
||||
style.syntax["normal"] = { common.color "#a0a0a0" }
|
||||
style.syntax["symbol"] = { common.color "#a0a0a0" }
|
||||
style.syntax["comment"] = { common.color "#404040" }
|
||||
style.syntax["keyword"] = { common.color "#dfdfdf" }
|
||||
style.syntax["keyword2"] = { common.color "#dfdfdf" }
|
||||
style.syntax["number"] = { common.color "#dfdfdf" }
|
||||
style.syntax["literal"] = { common.color "#dfdfdf" }
|
||||
style.syntax["string"] = { common.color "#dfdfdf" }
|
||||
style.syntax["operator"] = color
|
||||
style.syntax["function"] = color
|
|
@ -0,0 +1,29 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#151515" }
|
||||
style.background2 = { common.color "#151515" }
|
||||
style.background3 = { common.color "#151515" }
|
||||
style.text = { common.color "#707070" }
|
||||
style.caret = { common.color "#dfdfdf" }
|
||||
style.accent = { common.color "#d0d0d0" }
|
||||
style.dim = { common.color "#303030" }
|
||||
style.divider = { common.color "#151515" }
|
||||
style.selection = { common.color "#242424" }
|
||||
style.line_number = { common.color "#252525" }
|
||||
style.line_number2 = { common.color "#444444" }
|
||||
style.line_highlight = { common.color "#101010" }
|
||||
style.scrollbar = { common.color "#252525" }
|
||||
style.scrollbar2 = { common.color "#444444" }
|
||||
|
||||
style.syntax = {}
|
||||
style.syntax["normal"] = { common.color "#a0a0a0" }
|
||||
style.syntax["symbol"] = { common.color "#a0a0a0" }
|
||||
style.syntax["comment"] = { common.color "#404040" }
|
||||
style.syntax["keyword"] = { common.color "#dfdfdf" }
|
||||
style.syntax["keyword2"] = { common.color "#dfdfdf" }
|
||||
style.syntax["number"] = { common.color "#dfdfdf" }
|
||||
style.syntax["literal"] = { common.color "#dfdfdf" }
|
||||
style.syntax["string"] = { common.color "#dfdfdf" }
|
||||
style.syntax["operator"] = { common.color "#01A870" }
|
||||
style.syntax["function"] = { common.color "#01A870" }
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#282828" }
|
||||
style.background2 = { common.color "#1d2021" }
|
||||
style.background3 = { common.color "#1d2021" }
|
||||
style.text = { common.color "#928374" }
|
||||
style.caret = { common.color "#fbf1c7" }
|
||||
style.accent = { common.color "#ebdbb2" }
|
||||
style.dim = { common.color "#928374" }
|
||||
style.divider = { common.color "#1d2021" }
|
||||
style.selection = { common.color "#3c3836" }
|
||||
style.line_number = { common.color "#928374" }
|
||||
style.line_number2 = { common.color "#ebdbb2" }
|
||||
style.line_highlight = { common.color "#32302f" }
|
||||
style.scrollbar = { common.color "#928374" }
|
||||
style.scrollbar2 = { common.color "#fbf1c7" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#ebdbb2" }
|
||||
style.syntax["symbol"] = { common.color "#ebdbb2" }
|
||||
style.syntax["comment"] = { common.color "#928374" }
|
||||
style.syntax["keyword"] = { common.color "#fb4934" }
|
||||
style.syntax["keyword2"] = { common.color "#83a598" }
|
||||
style.syntax["number"] = { common.color "#d3869b" }
|
||||
style.syntax["literal"] = { common.color "#d3869b" }
|
||||
style.syntax["string"] = { common.color "#b8bb26" }
|
||||
style.syntax["operator"] = { common.color "#ebdbb2" }
|
||||
style.syntax["function"] = { common.color "#8ec07c" }
|
|
@ -0,0 +1,32 @@
|
|||
-- Liqube Dark Code for Lite <liqube.com>
|
||||
|
||||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#13171e" }
|
||||
style.background2 = { common.color "#21252b" }
|
||||
style.background3 = { common.color "#21252b" }
|
||||
style.text = { common.color "#abb2bf" }
|
||||
style.caret = { common.color "#abb2bf" }
|
||||
style.accent = { common.color "#ffffff" }
|
||||
style.dim = { common.color "#545e70" }
|
||||
style.divider = { common.color "#242223" }
|
||||
style.selection = { common.color "#3e4451" }
|
||||
style.line_number = { common.color "#323641" }
|
||||
style.line_number2 = { common.color "#596275" }
|
||||
style.line_highlight = { common.color "#1c1f25" }
|
||||
style.scrollbar = { common.color "#3d3f43" }
|
||||
style.scrollbar2 = { common.color "#595b5f" }
|
||||
style.guide = { common.color "#1c1f25" } -- indentguide
|
||||
|
||||
style.syntax["normal"] = { common.color "#abb2bf" }
|
||||
style.syntax["symbol"] = { common.color "#71a9d7" }
|
||||
style.syntax["comment"] = { common.color "#5c6370" }
|
||||
style.syntax["keyword"] = { common.color "#98c875" }
|
||||
style.syntax["keyword2"] = { common.color "#ffffff" }
|
||||
style.syntax["number"] = { common.color "#ffffff" }
|
||||
style.syntax["literal"] = { common.color "#ea5964" }
|
||||
style.syntax["string"] = { common.color "#ea5964" }
|
||||
style.syntax["operator"] = { common.color "#657085" }
|
||||
style.syntax["function"] = { common.color "#ffffff" }
|
||||
style.syntax["preprocessor"] = { common.color "#98c875" } -- thinking ahead
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#303841" }
|
||||
style.background2 = { common.color "#1d2227" }
|
||||
style.background3 = { common.color "#1d2227" }
|
||||
style.text = { common.color "#9ea191" }
|
||||
style.caret = { common.color "#61efce" }
|
||||
style.accent = { common.color "#ffd152" }
|
||||
style.dim = { common.color "#4c5863" }
|
||||
style.divider = { common.color "#242223" }
|
||||
style.selection = { common.color "#4c5863" }
|
||||
style.line_number = { common.color "#bfc5d0" }
|
||||
style.line_number2 = { common.color "#848b95" }
|
||||
style.line_highlight = { common.color "#303841" }
|
||||
style.scrollbar = { common.color "#696f75" }
|
||||
style.scrollbar2 = { common.color "#444b53" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#d7dde9" }
|
||||
style.syntax["symbol"] = { common.color "#d8dee9" }
|
||||
style.syntax["comment"] = { common.color "#a6acb9" }
|
||||
style.syntax["keyword"] = { common.color "#e55e66" }
|
||||
style.syntax["keyword2"] = { common.color "#ef6179" }
|
||||
style.syntax["number"] = { common.color "#ffd152" }
|
||||
style.syntax["literal"] = { common.color "#e75550" }
|
||||
style.syntax["string"] = { common.color "#939d5d" }
|
||||
style.syntax["operator"] = { common.color "#c2674f" }
|
||||
style.syntax["function"] = { common.color "#6699ca" }
|
|
@ -0,0 +1,29 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#080808" }
|
||||
style.background2 = { common.color "#080808" }
|
||||
style.background3 = { common.color "#101010" }
|
||||
style.text = { common.color "#707070" }
|
||||
style.caret = { common.color "#ffffff" }
|
||||
style.accent = { common.color "#d0d0d0" }
|
||||
style.dim = { common.color "#303030" }
|
||||
style.divider = { common.color "#080808" }
|
||||
style.selection = { common.color "#242424" }
|
||||
style.line_number = { common.color "#202020" }
|
||||
style.line_number2 = { common.color "#707070" }
|
||||
style.line_highlight = { common.color "#101010" }
|
||||
style.scrollbar = { common.color "#252525" }
|
||||
style.scrollbar2 = { common.color "#303030" }
|
||||
|
||||
style.syntax = {}
|
||||
style.syntax["normal"] = { common.color "#a0a0a0" }
|
||||
style.syntax["symbol"] = { common.color "#a0a0a0" }
|
||||
style.syntax["comment"] = { common.color "#404040" }
|
||||
style.syntax["keyword"] = { common.color "#f0f0f0" }
|
||||
style.syntax["keyword2"] = { common.color "#f0f0f0" }
|
||||
style.syntax["number"] = { common.color "#f0f0f0" }
|
||||
style.syntax["literal"] = { common.color "#f0f0f0" }
|
||||
style.syntax["string"] = { common.color "#f0f0f0" }
|
||||
style.syntax["operator"] = { common.color "#f0f0f0" }
|
||||
style.syntax["function"] = { common.color "#a0a0a0" }
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#272822" }
|
||||
style.background2 = { common.color "#22231C" }
|
||||
style.background3 = { common.color "#22231C" }
|
||||
style.text = { common.color "#9ea191" }
|
||||
style.caret = { common.color "#F8F8F0" }
|
||||
style.accent = { common.color "#F8F8F2" }
|
||||
style.dim = { common.color "#5e6052" }
|
||||
style.divider = { common.color "#1b1c17" }
|
||||
style.selection = { common.color "#49483E" }
|
||||
style.line_number = { common.color "#75715E" }
|
||||
style.line_number2 = { common.color "#d2d0c6" }
|
||||
style.line_highlight = { common.color "#36372f" }
|
||||
style.scrollbar = { common.color "#49483E" }
|
||||
style.scrollbar2 = { common.color "#636254" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#F8F8F2" }
|
||||
style.syntax["symbol"] = { common.color "#F8F8F2" }
|
||||
style.syntax["comment"] = { common.color "#75715E" }
|
||||
style.syntax["keyword"] = { common.color "#F92672" }
|
||||
style.syntax["keyword2"] = { common.color "#66DAEF" }
|
||||
style.syntax["number"] = { common.color "#AE81FF" }
|
||||
style.syntax["literal"] = { common.color "#AE81FF" }
|
||||
style.syntax["string"] = { common.color "#E6DB74" }
|
||||
style.syntax["operator"] = { common.color "#F8F8F2" }
|
||||
style.syntax["function"] = { common.color "#A6E22E" }
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#282923" }
|
||||
style.background2 = { common.color "#181915" }
|
||||
style.background3 = { common.color "#181915" }
|
||||
style.text = { common.color "#9ea191" }
|
||||
style.caret = { common.color "#f8f8f2" }
|
||||
style.accent = { common.color "#f8f8f2" }
|
||||
style.dim = { common.color "#5e6052" }
|
||||
style.divider = { common.color "#1b1c17" }
|
||||
style.selection = { common.color "#3a3a32" }
|
||||
style.line_number = { common.color "#90918b" }
|
||||
style.line_number2 = { common.color "#d2d0c6" }
|
||||
style.line_highlight = { common.color "#282923" }
|
||||
style.scrollbar = { common.color "#63635f" }
|
||||
style.scrollbar2 = { common.color "#3d3d38" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#f8f8f2" }
|
||||
style.syntax["symbol"] = { common.color "#f8f8f2" }
|
||||
style.syntax["comment"] = { common.color "#75715E" }
|
||||
style.syntax["keyword"] = { common.color "#f92472" }
|
||||
style.syntax["keyword2"] = { common.color "#f92472" }
|
||||
style.syntax["number"] = { common.color "#ac80ff" }
|
||||
style.syntax["literal"] = { common.color "#e7db74" }
|
||||
style.syntax["string"] = { common.color "#e7db74" }
|
||||
style.syntax["operator"] = { common.color "#f92472" }
|
||||
style.syntax["function"] = { common.color "#5cd5ef" }
|
|
@ -0,0 +1,39 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
local config = require "core.config"
|
||||
|
||||
style.background = { common.color "#2E3440" }
|
||||
style.background2 = { common.color "#2E3440" }
|
||||
style.background3 = { common.color "#3B4252" }
|
||||
style.text = { common.color "#D8DEE9" }
|
||||
style.caret = { common.color "#D8DEE9" }
|
||||
style.accent = { common.color "#88C0D0" }
|
||||
style.dim = { common.color "#d8dee966" }
|
||||
style.divider = { common.color "#3B4252" }
|
||||
style.selection = { common.color "#434C5ECC" }
|
||||
style.line_number = { common.color "#4C566A" }
|
||||
style.line_number2 = { common.color "#D8DEE9" }
|
||||
style.line_highlight = { common.color "#3B4252" }
|
||||
style.scrollbar = { common.color "#434c5eaa" }
|
||||
style.scrollbar2 = { common.color "#434c5e" }
|
||||
style.good = { common.color "#72b886cc" }
|
||||
style.warn = { common.color "#d08770" }
|
||||
style.error = { common.color "#bf616a" }
|
||||
style.modified = { common.color "#ebcb8b" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#ECEFF4" }
|
||||
style.syntax["symbol"] = { common.color "#D8DEE9" }
|
||||
style.syntax["comment"] = { common.color "#616E88" }
|
||||
style.syntax["keyword"] = { common.color "#81A1C1" }
|
||||
style.syntax["keyword2"] = { common.color "#81A1C1" }
|
||||
style.syntax["number"] = { common.color "#B48EAD" }
|
||||
style.syntax["literal"] = { common.color "#81A1C1" }
|
||||
style.syntax["string"] = { common.color "#A3BE8C" }
|
||||
style.syntax["operator"] = { common.color "#81A1C1" }
|
||||
style.syntax["function"] = { common.color "#88C0D0" }
|
||||
|
||||
config.highlight_current_line = "no_selection"
|
||||
|
||||
style.guide = { common.color "#434c5eb3" }
|
||||
style.bracketmatch_color = { common.color "#8fbcbb" }
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#282c34" }
|
||||
style.background2 = { common.color "#21252B" }
|
||||
style.background3 = { common.color "#21252B" }
|
||||
style.text = { common.color "#abb2bf" }
|
||||
style.caret = { common.color "#528bff" }
|
||||
style.accent = { common.color "#ffffff" }
|
||||
style.dim = { common.color "#4f5873" }
|
||||
style.divider = { common.color "#181A1F" }
|
||||
style.selection = { common.color "#383D49" }
|
||||
style.line_number = { common.color "#53576e" }
|
||||
style.line_number2 = { common.color "#666B76" }
|
||||
style.line_highlight = { common.color "#2C333E" }
|
||||
style.scrollbar = { common.color "#4f5873" }
|
||||
style.scrollbar2 = { common.color "#3060C1" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#abb2bf" }
|
||||
style.syntax["symbol"] = { common.color "#abb2bf" }
|
||||
style.syntax["comment"] = { common.color "#5f697a" }
|
||||
style.syntax["keyword"] = { common.color "#cd74e8" }
|
||||
style.syntax["keyword2"] = { common.color "#eb6772" }
|
||||
style.syntax["number"] = { common.color "#db9d63" }
|
||||
style.syntax["literal"] = { common.color "#e6c07b" }
|
||||
style.syntax["string"] = { common.color "#9acc76" }
|
||||
style.syntax["operator"] = { common.color "#abb2bf" }
|
||||
style.syntax["function"] = { common.color "#5cb3fa" }
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#242424" }
|
||||
style.background2 = { common.color "#252528" }
|
||||
style.background3 = { common.color "#44475A" }
|
||||
|
||||
style.text = { common.color "#fffff0" }
|
||||
style.caret = { common.color "#69FF94" }
|
||||
style.accent = { common.color "#ff0fff" }
|
||||
|
||||
style.dim = { common.color "#0fffff" }
|
||||
style.divider = { common.color "#7b7f8b" }
|
||||
style.selection = { common.color "#48484f" }
|
||||
style.selectionhighlight = { common.color "#dddeee" }
|
||||
style.line_number = { common.color "#525259" }
|
||||
style.line_number2 = { common.color "#f6f6e0" }
|
||||
style.line_highlight = { common.color "#343438" }
|
||||
style.scrollbar = { common.color "#414146" }
|
||||
style.scrollbar2 = { common.color "#4b4bff" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#e1e1e6" }
|
||||
style.syntax["symbol"] = { common.color "#97e1f1" }
|
||||
style.syntax["comment"] = { common.color "#676b6f" }
|
||||
style.syntax["keyword"] = { common.color "#E58AC9" }
|
||||
style.syntax["keyword2"] = { common.color "#F77483" }
|
||||
style.syntax["number"] = { common.color "#FFA94D" }
|
||||
style.syntax["literal"] = { common.color "#ee6666" }
|
||||
style.syntax["string"] = { common.color "#f7c95c" }
|
||||
style.syntax["operator"] = { common.color "#93DDFA" }
|
||||
style.syntax["function"] = { common.color "#bf9eee" }
|
|
@ -0,0 +1,37 @@
|
|||
-- Most of the colors are taken from:
|
||||
-- https://github.com/microsoft/vscode/tree/master/extensions/theme-defaults/themes
|
||||
|
||||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#1E1E1E" }
|
||||
style.background2 = { common.color "#252526" }
|
||||
style.background3 = { common.color "#252526" }
|
||||
style.text = { common.color "#D4D4D4" }
|
||||
style.caret = { common.color "#FFFFFF" }
|
||||
style.accent = { common.color "#76BCFF" } -- Text in autocomplete and command, col(>80) in satusbar
|
||||
style.dim = { common.color "#7A7A7A" } -- Text of nonactive tabs, prefix in log
|
||||
style.divider = { common.color "#1E1E1E" }
|
||||
style.selection = { common.color "#264F78" }
|
||||
style.line_number = { common.color "#707070" }
|
||||
style.line_number2 = { common.color "#A0A0A0" } -- Number on line with caret
|
||||
style.line_highlight = { common.color "#333A40"}
|
||||
style.scrollbar = { common.color "#404040" }
|
||||
style.scrollbar2 = { common.color "#707070" } -- Hovered
|
||||
|
||||
style.syntax["normal"] = { common.color "#D4D4D4" }
|
||||
style.syntax["symbol"] = { common.color "#D4D4D4" }
|
||||
style.syntax["comment"] = { common.color "#6A9955" }
|
||||
style.syntax["keyword"] = { common.color "#569CD6" } -- local function end, if case
|
||||
style.syntax["keyword2"] = { common.color "#C586C0" } -- self, int float
|
||||
style.syntax["number"] = { common.color "#B5CEA8" }
|
||||
style.syntax["literal"] = { common.color "#569CD6" }
|
||||
style.syntax["string"] = { common.color "#CE9178" }
|
||||
style.syntax["operator"] = { common.color "#8590A5"} -- = + - / < >
|
||||
style.syntax["function"] = { common.color "#DCDCAA" }
|
||||
|
||||
-- PLUGINS
|
||||
style.linter_warning = { common.color "#B89500" } -- linter
|
||||
style.bracketmatch_color = { common.color "#76BCFF" } -- bracketmatch
|
||||
style.guide = { common.color "#404040" } -- indentguide
|
||||
style.guide_width = 1 -- indentguide
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#282a36" }
|
||||
style.background2 = { common.color "#22242e" }
|
||||
style.background3 = { common.color "#22242e" }
|
||||
style.text = { common.color "#aab3e6" }
|
||||
style.caret = { common.color "#f5faff" }
|
||||
style.accent = { common.color "#ffb86c" }
|
||||
style.dim = { common.color "#4f526b" }
|
||||
style.divider = { common.color "#22242e" }
|
||||
style.selection = { common.color "#4c5163" }
|
||||
style.line_number = { common.color "#44475a" }
|
||||
style.line_number2 = { common.color "#717796" }
|
||||
style.line_highlight = { common.color "#2d303d" }
|
||||
style.scrollbar = { common.color "#44475a" }
|
||||
style.scrollbar2 = { common.color "#4c5163" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#f5faff" }
|
||||
style.syntax["symbol"] = { common.color "#f5faff" }
|
||||
style.syntax["comment"] = { common.color "#6272a4" }
|
||||
style.syntax["keyword"] = { common.color "#ff79c6" }
|
||||
style.syntax["keyword2"] = { common.color "#8be9fd" }
|
||||
style.syntax["number"] = { common.color "#bd93f9" }
|
||||
style.syntax["literal"] = { common.color "#bd93f9" }
|
||||
style.syntax["string"] = { common.color "#f1fa8c" }
|
||||
style.syntax["operator"] = { common.color "#ff79c6" }
|
||||
style.syntax["function"] = { common.color "#8be9fd" }
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#404040" }
|
||||
style.background2 = { common.color "#3d3d3d" }
|
||||
style.background3 = { common.color "#2b2b2b" }
|
||||
style.text = { common.color "#dcdccc" }
|
||||
style.caret = { common.color "#f8f8f0" }
|
||||
style.accent = { common.color "#dcdccc" }
|
||||
style.dim = { common.color "#8f8f8f" }
|
||||
style.divider = { common.color "#383838" }
|
||||
style.selection = { common.color "#2f2f2f" }
|
||||
style.line_number = { common.color "#545454" }
|
||||
style.line_number2 = { common.color "#545454" }
|
||||
style.line_highlight = { common.color "#383838" }
|
||||
style.scrollbar = { common.color "#4c4c4c" }
|
||||
style.scrollbar2 = { common.color "#5e5e5e" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#dcdccc" }
|
||||
style.syntax["symbol"] = { common.color "#dcdccc" }
|
||||
style.syntax["comment"] = { common.color "#7f9f7f" }
|
||||
style.syntax["keyword"] = { common.color "#f0dfaf" }
|
||||
style.syntax["keyword2"] = { common.color "#dfdfbf" }
|
||||
style.syntax["number"] = { common.color "#8cd0d3" }
|
||||
style.syntax["literal"] = { common.color "#dfaf8f" }
|
||||
style.syntax["string"] = { common.color "#cc9393" }
|
||||
style.syntax["operator"] = { common.color "#f0efd0" }
|
||||
style.syntax["function"] = { common.color "#efef8f" }
|
Binary file not shown.
|
@ -0,0 +1,31 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
-- GitHubs style varies from language to language so its hard to get perfect
|
||||
-- Originally written by thebirk, 2019
|
||||
|
||||
style.background = { common.color "#fbfbfb" }
|
||||
style.background2 = { common.color "#f2f2f2" }
|
||||
style.background3 = { common.color "#f2f2f2" }
|
||||
style.text = { common.color "#404040" }
|
||||
style.caret = { common.color "#181818" }
|
||||
style.accent = { common.color "#0366d6" }
|
||||
style.dim = { common.color "#b0b0b0" }
|
||||
style.divider = { common.color "#e8e8e8" }
|
||||
style.selection = { common.color "#b7dce8" }
|
||||
style.line_number = { common.color "#d0d0d0" }
|
||||
style.line_number2 = { common.color "#808080" }
|
||||
style.line_highlight = { common.color "#f2f2f2" }
|
||||
style.scrollbar = { common.color "#e0e0e0" }
|
||||
style.scrollbar2 = { common.color "#c0c0c0" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#24292e" }
|
||||
style.syntax["symbol"] = { common.color "#24292e" }
|
||||
style.syntax["comment"] = { common.color "#6a737d" }
|
||||
style.syntax["keyword"] = { common.color "#d73a49" }
|
||||
style.syntax["keyword2"] = { common.color "#d73a49" }
|
||||
style.syntax["number"] = { common.color "#005cc5" }
|
||||
style.syntax["literal"] = { common.color "#005cc5" }
|
||||
style.syntax["string"] = { common.color "#032f62" }
|
||||
style.syntax["operator"] = { common.color "#d73a49" }
|
||||
style.syntax["function"] = { common.color "#005cc5" }
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#f7f9f9" }
|
||||
style.background2 = { common.color "#f7f9f9" }
|
||||
style.background3 = { common.color "#f7f9f9" }
|
||||
style.text = { common.color "#404040" }
|
||||
style.caret = { common.color "#ff5971" }
|
||||
style.accent = { common.color "#ff5971" }
|
||||
style.dim = { common.color "#b0b0b0" }
|
||||
style.divider = { common.color "#e8e8e8" }
|
||||
style.selection = { common.color "#fde6eb" }
|
||||
style.line_number = { common.color "#d0d0d0" }
|
||||
style.line_number2 = { common.color "#808080" }
|
||||
style.line_highlight = { common.color "#f2f2f2" }
|
||||
style.scrollbar = { common.color "#e0e0e0" }
|
||||
style.scrollbar2 = { common.color "#c0c0c0" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#181818" }
|
||||
style.syntax["symbol"] = { common.color "#181818" }
|
||||
style.syntax["comment"] = { common.color "#43cdbd" }
|
||||
style.syntax["keyword"] = { common.color "#5f7dcd" }
|
||||
style.syntax["keyword2"] = { common.color "#9c53c6" }
|
||||
style.syntax["number"] = { common.color "#3daee9" }
|
||||
style.syntax["literal"] = { common.color "#3daee9" }
|
||||
style.syntax["string"] = { common.color "#3daee9" }
|
||||
style.syntax["operator"] = { common.color "#5f7dcd" }
|
||||
style.syntax["function"] = { common.color "#9c53c6" }
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#fdf6e3" }
|
||||
style.background2 = { common.color "#eee8d5" }
|
||||
style.background3 = { common.color "#eee8d5" }
|
||||
style.text = { common.color "#657b83" }
|
||||
style.caret = { common.color "#657b83" }
|
||||
style.accent = { common.color "#002b36" }
|
||||
style.dim = { common.color "#93a1a1" }
|
||||
style.divider = { common.color "#e0dbc8" }
|
||||
style.selection = { common.color "#eee8d5" }
|
||||
style.line_number = { common.color "#93a1a1" }
|
||||
style.line_number2 = { common.color "#002b36" }
|
||||
style.line_highlight = { common.color "#eee8d5" }
|
||||
style.scrollbar = { common.color "#e0dbc8" }
|
||||
style.scrollbar2 = { common.color "#bfbbaa" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#657b83" }
|
||||
style.syntax["symbol"] = { common.color "#657b83" }
|
||||
style.syntax["comment"] = { common.color "#93a1a1" }
|
||||
style.syntax["keyword"] = { common.color "#859900" }
|
||||
style.syntax["keyword2"] = { common.color "#268bd2" }
|
||||
style.syntax["number"] = { common.color "#d33682" }
|
||||
style.syntax["literal"] = { common.color "#2aa198" }
|
||||
style.syntax["string"] = { common.color "#2aa198" }
|
||||
style.syntax["operator"] = { common.color "#859900" }
|
||||
style.syntax["function"] = { common.color "#268bd2" }
|
|
@ -0,0 +1,28 @@
|
|||
local style = require "core.style"
|
||||
local common = require "core.common"
|
||||
|
||||
style.background = { common.color "#fdf6e3" }
|
||||
style.background2 = { common.color "#2e2c29" }
|
||||
style.background3 = { common.color "#3e3c37" }
|
||||
style.text = { common.color "#b2ada1" }
|
||||
style.caret = { common.color "#b2ada1" }
|
||||
style.accent = { common.color "#6c71c4" }
|
||||
style.dim = { common.color "#b2ada1" }
|
||||
style.divider = { common.color "#201f1d" }
|
||||
style.selection = { common.color "#eee8d5" }
|
||||
style.line_number = { common.color "#93a1a1" }
|
||||
style.line_number2 = { common.color "#002b36" }
|
||||
style.line_highlight = { common.color "#fcefcd" }
|
||||
style.scrollbar = { common.color "#e0dbc8" }
|
||||
style.scrollbar2 = { common.color "#9d9988" }
|
||||
|
||||
style.syntax["normal"] = { common.color "#3e3c37" }
|
||||
style.syntax["symbol"] = { common.color "#4c4f82" }
|
||||
style.syntax["comment"] = { common.color "#93a1a1" }
|
||||
style.syntax["keyword"] = { common.color "#d33682" }
|
||||
style.syntax["keyword2"] = { common.color "#6c71c4" }
|
||||
style.syntax["number"] = { common.color "#859900" }
|
||||
style.syntax["literal"] = { common.color "#b58900" }
|
||||
style.syntax["string"] = { common.color "#cb4b16" }
|
||||
style.syntax["operator"] = { common.color "#859900" }
|
||||
style.syntax["function"] = { common.color "#268bd2" }
|
Binary file not shown.
|
@ -0,0 +1,115 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local translate = require "core.doc.translate"
|
||||
local config = require "core.config"
|
||||
local DocView = require "core.docview"
|
||||
local command = require "core.command"
|
||||
local keymap = require "core.keymap"
|
||||
|
||||
|
||||
config.autoinsert_map = {
|
||||
["["] = "]",
|
||||
["{"] = "}",
|
||||
["("] = ")",
|
||||
['"'] = '"',
|
||||
["'"] = "'",
|
||||
["`"] = "`",
|
||||
}
|
||||
|
||||
|
||||
local function is_closer(chr)
|
||||
for _, v in pairs(config.autoinsert_map) do
|
||||
if v == chr then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function count_char(text, chr)
|
||||
local count = 0
|
||||
for _ in text:gmatch(chr) do
|
||||
count = count + 1
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
|
||||
local on_text_input = DocView.on_text_input
|
||||
|
||||
function DocView:on_text_input(text)
|
||||
local mapping = config.autoinsert_map[text]
|
||||
|
||||
-- prevents plugin from operating on `CommandView`
|
||||
if getmetatable(self) ~= DocView then
|
||||
return on_text_input(self, text)
|
||||
end
|
||||
|
||||
-- wrap selection if we have a selection
|
||||
if mapping and self.doc:has_selection() then
|
||||
local l1, c1, l2, c2, swap = self.doc:get_selection(true)
|
||||
self.doc:insert(l2, c2, mapping)
|
||||
self.doc:insert(l1, c1, text)
|
||||
self.doc:set_selection(l1, c1, l2, c2 + 2, swap)
|
||||
return
|
||||
end
|
||||
|
||||
-- skip inserting closing text
|
||||
local chr = self.doc:get_char(self.doc:get_selection())
|
||||
if text == chr and is_closer(chr) then
|
||||
self.doc:move_to(1)
|
||||
return
|
||||
end
|
||||
|
||||
-- don't insert closing quote if we have a non-even number on this line
|
||||
local line = self.doc:get_selection()
|
||||
if text == mapping and count_char(self.doc.lines[line], text) % 2 == 1 then
|
||||
return on_text_input(self, text)
|
||||
end
|
||||
|
||||
-- auto insert closing bracket
|
||||
if mapping and (chr:find("%s") or is_closer(chr) and chr ~= '"') then
|
||||
on_text_input(self, text)
|
||||
on_text_input(self, mapping)
|
||||
self.doc:move_to(-1)
|
||||
return
|
||||
end
|
||||
|
||||
on_text_input(self, text)
|
||||
end
|
||||
|
||||
|
||||
|
||||
local function predicate()
|
||||
return getmetatable(core.active_view) == DocView
|
||||
and not core.active_view.doc:has_selection()
|
||||
end
|
||||
|
||||
command.add(predicate, {
|
||||
["autoinsert:backspace"] = function()
|
||||
local doc = core.active_view.doc
|
||||
local l, c = doc:get_selection()
|
||||
local chr = doc:get_char(l, c)
|
||||
if config.autoinsert_map[doc:get_char(l, c - 1)] and is_closer(chr) then
|
||||
doc:delete_to(1)
|
||||
end
|
||||
command.perform "doc:backspace"
|
||||
end,
|
||||
|
||||
["autoinsert:delete-to-previous-word-start"] = function()
|
||||
local doc = core.active_view.doc
|
||||
local le, ce = translate.previous_word_start(doc, doc:get_selection())
|
||||
while true do
|
||||
local l, c = doc:get_selection()
|
||||
if l == le and c == ce then
|
||||
break
|
||||
end
|
||||
command.perform "autoinsert:backspace"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
keymap.add {
|
||||
["backspace"] = "autoinsert:backspace",
|
||||
["ctrl+backspace"] = "autoinsert:delete-to-previous-word-start",
|
||||
["ctrl+shift+backspace"] = "autoinsert:delete-to-previous-word-start",
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
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
|
|
@ -0,0 +1,73 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local style = require "core.style"
|
||||
local command = require "core.command"
|
||||
local common = require "core.common"
|
||||
local config = require "core.config"
|
||||
local View = require "core.view"
|
||||
|
||||
|
||||
config.bigclock_time_format = "%H:%M:%S"
|
||||
config.bigclock_date_format = "%A, %d %B %Y"
|
||||
config.bigclock_scale = 1
|
||||
|
||||
|
||||
local ClockView = View:extend()
|
||||
|
||||
|
||||
function ClockView:new()
|
||||
ClockView.super.new(self)
|
||||
self.time_text = ""
|
||||
self.date_text = ""
|
||||
end
|
||||
|
||||
|
||||
function ClockView:get_name()
|
||||
return "Big Clock"
|
||||
end
|
||||
|
||||
|
||||
function ClockView:update_fonts()
|
||||
local size = math.floor(self.size.x * 0.15 / 15) * 15 * config.bigclock_scale
|
||||
if self.font_size ~= size then
|
||||
self.time_font = renderer.font.load(DATADIR .. "/fonts/font.ttf", size)
|
||||
self.date_font = renderer.font.load(DATADIR .. "/fonts/font.ttf", size * 0.3)
|
||||
self.font_size = size
|
||||
collectgarbage()
|
||||
end
|
||||
return self.font
|
||||
end
|
||||
|
||||
|
||||
function ClockView:update()
|
||||
local time_text = os.date(config.bigclock_time_format)
|
||||
local date_text = os.date(config.bigclock_date_format)
|
||||
if self.time_text ~= time_text or self.date_text ~= date_text then
|
||||
core.redraw = true
|
||||
self.time_text = time_text
|
||||
self.date_text = date_text
|
||||
end
|
||||
ClockView.super.update(self)
|
||||
end
|
||||
|
||||
|
||||
function ClockView:draw()
|
||||
self:update_fonts()
|
||||
self:draw_background(style.background)
|
||||
local x, y = self.position.x, self.position.y
|
||||
local w, h = self.size.x, self.size.y
|
||||
local _, y = common.draw_text(self.time_font, style.text, self.time_text, "center", x, y, w, h)
|
||||
local th = self.date_font:get_height()
|
||||
common.draw_text(self.date_font, style.dim, self.date_text, "center", x, y, w, th)
|
||||
end
|
||||
|
||||
|
||||
command.add(nil, {
|
||||
["big-clock:open"] = function()
|
||||
local node = core.root_view:get_active_node()
|
||||
node:add_view(ClockView())
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
return ClockView
|
|
@ -0,0 +1,118 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local style = require "core.style"
|
||||
local command = require "core.command"
|
||||
local keymap = require "core.keymap"
|
||||
local DocView = require "core.docview"
|
||||
|
||||
local bracket_maps = {
|
||||
-- [ ] ( ) { }
|
||||
{ [91] = 93, [40] = 41, [123] = 125, step = 1 },
|
||||
-- ] [ ) ( } {
|
||||
{ [93] = 91, [41] = 40, [125] = 123, step = -1 },
|
||||
}
|
||||
|
||||
|
||||
local function get_matching_bracket(doc, line, col, line_limit, open_byte, close_byte, step)
|
||||
local end_line = line + line_limit * step
|
||||
local depth = 0
|
||||
|
||||
while line ~= end_line do
|
||||
local byte = doc.lines[line]:byte(col)
|
||||
if byte == open_byte then
|
||||
depth = depth + 1
|
||||
elseif byte == close_byte then
|
||||
depth = depth - 1
|
||||
if depth == 0 then return line, col end
|
||||
end
|
||||
|
||||
local prev_line, prev_col = line, col
|
||||
line, col = doc:position_offset(line, col, step)
|
||||
if line == prev_line and col == prev_col then
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
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()
|
||||
local change_id = doc:get_change_id()
|
||||
if state.doc == doc and state.line == line and state.col == col
|
||||
and state.change_id == change_id and state.limit == line_limit then
|
||||
return
|
||||
end
|
||||
|
||||
-- find matching bracket if we're on a bracket
|
||||
local line2, col2
|
||||
for _, map in ipairs(bracket_maps) do
|
||||
for i = 0, -1, -1 do
|
||||
local line, col = doc:position_offset(line, col, i)
|
||||
local open = doc.lines[line]:byte(col)
|
||||
local close = map[open]
|
||||
if close then
|
||||
line2, col2 = get_matching_bracket(doc, line, col, line_limit, open, close, map.step)
|
||||
goto found
|
||||
end
|
||||
end
|
||||
end
|
||||
::found::
|
||||
|
||||
-- update
|
||||
state = {
|
||||
change_id = change_id,
|
||||
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 = math.ceil(1 * SCALE)
|
||||
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" }
|
|
@ -0,0 +1,54 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local common = require "core.common"
|
||||
local DocView = require "core.docview"
|
||||
|
||||
|
||||
local white = { common.color "#ffffff" }
|
||||
local black = { common.color "#000000" }
|
||||
local tmp = {}
|
||||
|
||||
|
||||
local function draw_color_previews(self, idx, x, y, ptn, base, nibbles)
|
||||
local text = self.doc.lines[idx]
|
||||
local s, e = 0, 0
|
||||
|
||||
while true do
|
||||
s, e = text:find(ptn, e + 1)
|
||||
if not s then break end
|
||||
|
||||
local str = text:sub(s, e)
|
||||
local r, g, b = str:match(ptn)
|
||||
r, g, b = tonumber(r, base), tonumber(g, base), tonumber(b, base)
|
||||
|
||||
-- #123 becomes #112233
|
||||
if nibbles then
|
||||
r = r * 16
|
||||
g = g * 16
|
||||
b = b * 16
|
||||
end
|
||||
|
||||
local x1 = x + self:get_col_x_offset(idx, s)
|
||||
local x2 = x + self:get_col_x_offset(idx, e + 1)
|
||||
local oy = self:get_line_text_y_offset()
|
||||
|
||||
local text_color = math.max(r, g, b) < 128 and white or black
|
||||
tmp[1], tmp[2], tmp[3] = r, g, b
|
||||
|
||||
local l1, _, l2, _ = self.doc:get_selection(true)
|
||||
|
||||
if not (self.doc:has_selection() and idx >= l1 and idx <= l2) then
|
||||
renderer.draw_rect(x1, y, x2 - x1, self:get_line_height(), tmp)
|
||||
renderer.draw_text(self:get_font(), str, x1, y + oy, text_color)
|
||||
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)
|
||||
draw_color_previews(self, idx, x, y, "#(%x%x)(%x%x)(%x%x)%f[%W]", 16)
|
||||
draw_color_previews(self, idx, x, y, "#(%x)(%x)(%x)%f[%W]", 16, true) -- support #fff css format
|
||||
draw_color_previews(self, idx, x, y, "rgba?%((%d+)%D+(%d+)%D+(%d+).-%)", 10)
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local command = require "core.command"
|
||||
local Doc = require "core.doc"
|
||||
|
||||
local function eof_newline(doc)
|
||||
local leof, neof = #doc.lines, #doc.lines
|
||||
for i = leof, 1, -1 do
|
||||
if not string.match(doc.lines[i], "^%s*$") then break end
|
||||
neof = i
|
||||
end
|
||||
if neof ~= leof then
|
||||
doc:remove(neof, 1, leof, math.huge)
|
||||
return
|
||||
end
|
||||
if "\n" ~= doc.lines[leof] then doc:insert(leof, math.huge, "\n") end
|
||||
end
|
||||
|
||||
command.add("core.docview", {
|
||||
["eof-newline:eof-newline"] = function()
|
||||
eof_newline(core.active_view.doc)
|
||||
end,
|
||||
})
|
||||
|
||||
local save = Doc.save
|
||||
function Doc:save(...)
|
||||
eof_newline(self)
|
||||
save(self, ...)
|
||||
end
|
|
@ -0,0 +1,45 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local command = require "core.command"
|
||||
local RootView = require "core.rootview"
|
||||
local DocView = require "core.docview"
|
||||
local Doc = require "core.doc"
|
||||
|
||||
local open_doc = RootView.open_doc
|
||||
function RootView:open_doc(doc)
|
||||
local node = self:get_active_node_default()
|
||||
local ephemeral, existing_ephemeral = node.views, nil
|
||||
for i, view in ipairs(node.views) do
|
||||
if view.doc == doc then
|
||||
ephemeral = false
|
||||
end
|
||||
if view.doc and view.doc.ephemeral then
|
||||
existing_ephemeral = view
|
||||
end
|
||||
end
|
||||
if ephemeral and existing_ephemeral then
|
||||
node:close_view(self.root_node, existing_ephemeral)
|
||||
end
|
||||
local view = open_doc(self, doc)
|
||||
if ephemeral then
|
||||
view.doc.ephemeral = #node.views > 1
|
||||
end
|
||||
return view
|
||||
end
|
||||
|
||||
local get_name = DocView.get_name
|
||||
function DocView:get_name()
|
||||
return self.doc and self.doc.ephemeral and ("-- " .. get_name(self) .. " --") or get_name(self)
|
||||
end
|
||||
|
||||
local doc_insert = Doc.insert
|
||||
function Doc:insert(...)
|
||||
doc_insert(self, ...)
|
||||
self.ephemeral = false
|
||||
end
|
||||
|
||||
local doc_remove = Doc.remove
|
||||
function Doc:remove(...)
|
||||
doc_remove(self, ...)
|
||||
self.ephemeral = false
|
||||
end
|
|
@ -0,0 +1,78 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local command = require "core.command"
|
||||
local keymap = require "core.keymap"
|
||||
|
||||
|
||||
local html = [[
|
||||
<html>
|
||||
<style>
|
||||
body {
|
||||
margin:80 auto 100 auto;
|
||||
max-width: 750px;
|
||||
line-height: 1.6;
|
||||
font-family: Open Sans, Arial;
|
||||
color: #444;
|
||||
padding: 0 10px;
|
||||
}
|
||||
h1, h2, h3 { line-height: 1.2; padding-top: 14px; }
|
||||
hr { border: 0px; border-top: 1px solid #ddd; }
|
||||
code, pre { background: #f3f3f3; padding: 8px; }
|
||||
code { padding: 4px; }
|
||||
a { text-decoration: none; color: #0366d6; }
|
||||
a:hover { text-decoration: underline; }
|
||||
table { border-collapse: collapse; }
|
||||
table, th, td { border: 1px solid #ddd; padding: 6px; }
|
||||
</style>
|
||||
<head>
|
||||
<title>${title}</title>
|
||||
<head>
|
||||
<body>
|
||||
<script>
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.open("POST", "https://api.github.com/markdown/raw");
|
||||
xhr.setRequestHeader("Content-Type", "text/plain");
|
||||
xhr.onload = function() { document.body.innerHTML = xhr.responseText; };
|
||||
xhr.send("${content}");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
]]
|
||||
|
||||
|
||||
command.add("core.docview", {
|
||||
["ghmarkdown:show-preview"] = function()
|
||||
local dv = core.active_view
|
||||
|
||||
local content = dv.doc:get_text(1, 1, math.huge, math.huge)
|
||||
local esc = { ['"'] = '\\"', ["\n"] = '\\n' }
|
||||
local text = html:gsub("${(.-)}", {
|
||||
title = dv:get_name(),
|
||||
content = content:gsub(".", esc)
|
||||
})
|
||||
|
||||
local htmlfile = core.temp_filename(".html")
|
||||
local fp = io.open(htmlfile, "w")
|
||||
fp:write(text)
|
||||
fp:close()
|
||||
|
||||
core.log("Opening markdown preview for \"%s\"", dv:get_name())
|
||||
if PLATFORM == "Windows" then
|
||||
system.exec("start " .. htmlfile)
|
||||
elseif PLATFORM == "AmigaOS 4" then
|
||||
-- print("LUA DBG: " .. tostring(htmlfile))
|
||||
system.exec('urlopen "file=' .. htmlfile .. '"')
|
||||
else
|
||||
system.exec(string.format("xdg-open %q", htmlfile))
|
||||
end
|
||||
|
||||
core.add_thread(function()
|
||||
coroutine.yield(5)
|
||||
os.remove(htmlfile)
|
||||
end)
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
keymap.add { ["ctrl+shift+m"] = "ghmarkdown:show-preview" }
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local style = require "core.style"
|
||||
local DocView = require "core.docview"
|
||||
|
||||
DocView.draw_line_gutter = function() end
|
||||
DocView.get_gutter_width = function() return style.padding.x end
|
|
@ -0,0 +1,50 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
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
|
||||
local n = 0
|
||||
for i = s, e do
|
||||
n = n + (text:byte(i) == 9 and config.indent_size or 1)
|
||||
end
|
||||
return n
|
||||
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 w = math.ceil(1 * SCALE)
|
||||
local h = self:get_line_height()
|
||||
local sspaces = ""
|
||||
local font = self:get_font()
|
||||
local ss = font:subpixel_scale()
|
||||
for _ = 0, spaces - 1, config.indent_size do
|
||||
local color = style.guide or style.selection
|
||||
local sw = font:get_width_subpixel(sspaces) / ss
|
||||
renderer.draw_rect(x + sw, y, w, h, color)
|
||||
sspaces = sspaces .. (' '):rep(config.indent_size)
|
||||
end
|
||||
draw_line_text(self, idx, x, y)
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local syntax = require "core.syntax"
|
||||
|
||||
syntax.add {
|
||||
files = { "Makefile", "makefile", "%.mk$" },
|
||||
comment = "#",
|
||||
patterns = {
|
||||
{ pattern = "#.*\n", type = "comment" },
|
||||
{ pattern = [[\.]], type = "normal" },
|
||||
{ pattern = "$[@^<%%?+|*]", type = "keyword2" },
|
||||
{ pattern = "$%(.-%)", type = "variable" },
|
||||
{ pattern = "%f[%w_][%d%.]+%f[^%w_]", type = "number" },
|
||||
{ pattern = "%..*:", type = "keyword2" },
|
||||
{ pattern = ".*:", type = "function" },
|
||||
},
|
||||
symbols = {
|
||||
},
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local syntax = require "core.syntax"
|
||||
|
||||
syntax.add {
|
||||
files = { "%.sh$" },
|
||||
headers = "^#!.*bin.*sh\n",
|
||||
comment = "#",
|
||||
patterns = {
|
||||
{ pattern = "#.*\n", type = "comment" },
|
||||
{ pattern = [[\.]], type = "normal" },
|
||||
{ pattern = { '"', '"', '\\' }, type = "string" },
|
||||
{ pattern = { "'", "'", '\\' }, type = "string" },
|
||||
{ pattern = { '`', '`', '\\' }, type = "string" },
|
||||
{ pattern = "%f[%w_][%d%.]+%f[^%w_]", type = "number" },
|
||||
{ pattern = "[!<>|&%[%]=*]", type = "operator" },
|
||||
{ pattern = "%f[%S]%-[%w%-_]+", type = "function" },
|
||||
{ pattern = "${.-}", type = "keyword2" },
|
||||
{ pattern = "$[%a_@*][%w_]*", type = "keyword2" },
|
||||
{ pattern = "[%a_][%w_]*", type = "symbol" },
|
||||
},
|
||||
symbols = {
|
||||
["case"] = "keyword",
|
||||
["do"] = "keyword",
|
||||
["done"] = "keyword",
|
||||
["elif"] = "keyword",
|
||||
["else"] = "keyword",
|
||||
["esac"] = "keyword",
|
||||
["fi"] = "keyword",
|
||||
["for"] = "keyword",
|
||||
["function"] = "keyword",
|
||||
["if"] = "keyword",
|
||||
["in"] = "keyword",
|
||||
["select"] = "keyword",
|
||||
["then"] = "keyword",
|
||||
["time"] = "keyword",
|
||||
["until"] = "keyword",
|
||||
["while"] = "keyword",
|
||||
["echo"] = "keyword",
|
||||
["true"] = "literal",
|
||||
["false"] = "literal",
|
||||
},
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local command = require "core.command"
|
||||
local common = require "core.common"
|
||||
local config = require "core.config"
|
||||
local keymap = require "core.keymap"
|
||||
|
||||
config.lfautoinsert_map = {
|
||||
["{%s*\n"] = "}",
|
||||
["%(%s*\n"] = ")",
|
||||
["%f[[]%[%s*\n"] = "]",
|
||||
["=%s*\n"] = false,
|
||||
[":%s*\n"] = false,
|
||||
["->%s*\n"] = false,
|
||||
["^%s*<([^/][^%s>]*)[^>]*>%s*\n"] = "</$TEXT>",
|
||||
["/%*%s*\n"] = "*/",
|
||||
["c/c++"] = {
|
||||
file_patterns = {
|
||||
"%.c$", "%.h$", "%.inl$", "%.cpp$", "%.hpp$",
|
||||
"%.cc$", "%.C$", "%.cxx$", "%.c++$", "%.hh$",
|
||||
"%.H$", "%.hxx$", "%.h++$"
|
||||
},
|
||||
map = {
|
||||
["^#if.*\n"] = "#endif",
|
||||
["^#else.*\n"] = "#endif",
|
||||
}
|
||||
},
|
||||
["lua"] = {
|
||||
file_patterns = { "%.lua$" },
|
||||
map = {
|
||||
["%f[%w]do%s*\n"] = "end",
|
||||
["%f[%w]then%s*\n"] = "end",
|
||||
["%f[%w]else%s*\n"] = "end",
|
||||
["%f[%w]repeat%s*\n"] = "until",
|
||||
["%f[%w]function.*%)%s*\n"] = "end",
|
||||
["%[%[%s*\n"] = "]]"
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
local function get_autoinsert_map(filename)
|
||||
local map = {}
|
||||
for pattern, closing in pairs(config.lfautoinsert_map) do
|
||||
if type(closing) == "table" then
|
||||
if common.match_pattern(filename, closing.file_patterns) then
|
||||
for p, e in pairs(closing.map) do
|
||||
map[p] = e
|
||||
end
|
||||
end
|
||||
else
|
||||
map[pattern] = closing
|
||||
end
|
||||
end
|
||||
|
||||
return map
|
||||
end
|
||||
|
||||
|
||||
local function indent_size(doc, line)
|
||||
local text = doc.lines[line] or ""
|
||||
local s, e = text:find("^[\t ]*")
|
||||
return e - s
|
||||
end
|
||||
|
||||
command.add("core.docview", {
|
||||
["autoinsert:newline"] = function()
|
||||
command.perform("doc:newline")
|
||||
|
||||
local doc = core.active_view.doc
|
||||
local line, col = doc:get_selection()
|
||||
local text = doc.lines[line - 1]
|
||||
|
||||
for ptn, close in pairs(get_autoinsert_map(doc.filename)) do
|
||||
local s, _, str = text:find(ptn)
|
||||
if s then
|
||||
if close
|
||||
and col == #doc.lines[line]
|
||||
and indent_size(doc, line + 1) <= indent_size(doc, line - 1)
|
||||
then
|
||||
close = str and close:gsub("$TEXT", str) or close
|
||||
command.perform("doc:newline")
|
||||
core.active_view:on_text_input(close)
|
||||
command.perform("doc:move-to-previous-line")
|
||||
if doc.lines[line+1] == doc.lines[line+2] then
|
||||
doc:remove(line+1, 1, line+2, 1)
|
||||
end
|
||||
elseif col < #doc.lines[line] then
|
||||
command.perform("doc:newline")
|
||||
command.perform("doc:move-to-previous-line")
|
||||
end
|
||||
command.perform("doc:indent")
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
keymap.add {
|
||||
["return"] = { "command:submit", "autoinsert:newline" }
|
||||
}
|
||||
|
||||
return {
|
||||
add = function(file_patterns, map)
|
||||
table.insert(
|
||||
config.lfautoinsert_map,
|
||||
{ file_patterns = file_patterns, map=map }
|
||||
)
|
||||
end
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
-- Markers plugin for lite text editor
|
||||
-- original implementation by Petri Häkkinen
|
||||
|
||||
local core = require "core"
|
||||
local command = require "core.command"
|
||||
local keymap = require "core.keymap"
|
||||
local style = require "core.style"
|
||||
local DocView = require "core.docview"
|
||||
local Doc = require "core.doc"
|
||||
|
||||
local cache = {} -- this table contains subtables for each document, each subtable is a set of line numbers
|
||||
setmetatable(cache, {
|
||||
__mode = "k",
|
||||
__index = function(t, k)
|
||||
t[k] = {}
|
||||
return t[k]
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
local function shift_lines(doc, at, diff)
|
||||
if diff == 0 then return end
|
||||
local t = {}
|
||||
for line in pairs(cache[doc]) do
|
||||
line = line >= at and line + diff or line
|
||||
t[line] = true
|
||||
end
|
||||
cache[doc] = t
|
||||
end
|
||||
|
||||
|
||||
local raw_insert = Doc.raw_insert
|
||||
|
||||
function Doc:raw_insert(line, col, text, ...)
|
||||
raw_insert(self, line, col, text, ...)
|
||||
local line_count = 0
|
||||
for _ in text:gmatch("\n") do
|
||||
line_count = line_count + 1
|
||||
end
|
||||
shift_lines(self, line, line_count)
|
||||
end
|
||||
|
||||
|
||||
local raw_remove = Doc.raw_remove
|
||||
|
||||
function Doc:raw_remove(line1, col1, line2, col2, ...)
|
||||
raw_remove(self, line1, col1, line2, col2, ...)
|
||||
shift_lines(self, line2, line1 - line2)
|
||||
end
|
||||
|
||||
|
||||
local draw_line_gutter = DocView.draw_line_gutter
|
||||
|
||||
function DocView:draw_line_gutter(idx, x, y)
|
||||
if cache[self.doc] and cache[self.doc][idx] then
|
||||
local h = self:get_line_height()
|
||||
renderer.draw_rect(x, y, style.padding.x * 0.4, h, style.selection)
|
||||
end
|
||||
draw_line_gutter(self, idx, x, y)
|
||||
end
|
||||
|
||||
|
||||
command.add("core.docview", {
|
||||
["markers:toggle-marker"] = function()
|
||||
local doc = core.active_view.doc
|
||||
local line = doc:get_selection()
|
||||
local markers = cache[doc]
|
||||
|
||||
if markers[line] then
|
||||
markers[line] = nil
|
||||
else
|
||||
markers[line] = true
|
||||
end
|
||||
end,
|
||||
|
||||
["markers:go-to-next-marker"] = function()
|
||||
local doc = core.active_view.doc
|
||||
local line = doc:get_selection()
|
||||
local markers = cache[doc]
|
||||
|
||||
local first_marker = math.huge
|
||||
local next_marker = math.huge
|
||||
for l, _ in pairs(markers) do
|
||||
if l > line and l < next_marker then
|
||||
next_marker = l
|
||||
end
|
||||
first_marker = math.min(first_marker, l)
|
||||
end
|
||||
if next_marker == math.huge then
|
||||
next_marker = first_marker
|
||||
end
|
||||
if next_marker ~= math.huge then
|
||||
doc:set_selection(next_marker, 1)
|
||||
core.active_view:scroll_to_line(next_marker, true)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
keymap.add {
|
||||
["ctrl+f2"] = "markers:toggle-marker",
|
||||
["f2"] = "markers:go-to-next-marker",
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
-- original implementation by AqilCont
|
||||
local style = require "core.style"
|
||||
local StatusView = require "core.statusview"
|
||||
|
||||
local get_items = StatusView.get_items
|
||||
|
||||
function StatusView:get_items()
|
||||
local left, right = get_items(self)
|
||||
local t = {
|
||||
style.text, (math.floor(collectgarbage("count") / 10.24) / 100) .. " MB",
|
||||
style.dim, self.separator2,
|
||||
}
|
||||
for i, item in ipairs(t) do
|
||||
table.insert(right, i, item)
|
||||
end
|
||||
return left, right
|
||||
end
|
||||
|
|
@ -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
|
||||
})
|
|
@ -0,0 +1,47 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local config = require "core.config"
|
||||
local style = require "core.style"
|
||||
local DocView = require "core.docview"
|
||||
|
||||
config.motiontrail_steps = 50
|
||||
|
||||
|
||||
local function lerp(a, b, t)
|
||||
return a + (b - a) * t
|
||||
end
|
||||
|
||||
|
||||
local function get_caret_rect(dv)
|
||||
local line, col = dv.doc:get_selection()
|
||||
local x, y = dv:get_line_screen_position(line)
|
||||
x = x + dv:get_col_x_offset(line, col)
|
||||
return x, y, style.caret_width, dv:get_line_height()
|
||||
end
|
||||
|
||||
|
||||
local last_x, last_y, last_view
|
||||
|
||||
local draw = DocView.draw
|
||||
|
||||
function DocView:draw(...)
|
||||
draw(self, ...)
|
||||
if self ~= core.active_view then return end
|
||||
|
||||
local x, y, w, h = get_caret_rect(self)
|
||||
|
||||
if last_view == self and (x ~= last_x or y ~= last_y) then
|
||||
local lx = x
|
||||
for i = 0, 1, 1 / config.motiontrail_steps do
|
||||
local ix = lerp(x, last_x, i)
|
||||
local iy = lerp(y, last_y, i)
|
||||
local iw = math.max(w, math.ceil(math.abs(ix - lx)))
|
||||
renderer.draw_rect(ix, iy, iw, h, style.caret)
|
||||
lx = ix
|
||||
end
|
||||
core.redraw = true
|
||||
end
|
||||
|
||||
last_view, last_x, last_y = self, x, y
|
||||
end
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
|
||||
local core = require "core"
|
||||
local common = require "core.common"
|
||||
local command = require "core.command"
|
||||
local keymap = require "core.keymap"
|
||||
local Doc = require "core.doc"
|
||||
local DocView = require "core.docview"
|
||||
|
||||
local navigate = {
|
||||
list = {},
|
||||
current = nil,
|
||||
index = 0
|
||||
}
|
||||
|
||||
--
|
||||
-- Private functions
|
||||
--
|
||||
local function get_active_view()
|
||||
if getmetatable(core.active_view) == DocView then
|
||||
return core.active_view
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Solution to safely remove elements from array table:
|
||||
-- found at https://stackoverflow.com/a/53038524
|
||||
local function array_remove(t, fnKeep)
|
||||
local j, n = 1, #t;
|
||||
|
||||
for i=1, n do
|
||||
if (fnKeep(t, i, j)) then
|
||||
if (i ~= j) then
|
||||
t[j] = t[i];
|
||||
t[i] = nil;
|
||||
end
|
||||
j = j + 1;
|
||||
else
|
||||
t[i] = nil;
|
||||
end
|
||||
end
|
||||
|
||||
return t;
|
||||
end
|
||||
|
||||
local function add(doc)
|
||||
-- Make new navigation point last in list
|
||||
if navigate.index > 0 and navigate.index < #navigate.list then
|
||||
local remove_start = navigate.index + 1
|
||||
local remove_end = #navigate.list
|
||||
array_remove(navigate.list, function(_, i)
|
||||
if i >= remove_start and i <= remove_end then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end)
|
||||
end
|
||||
|
||||
local line, col = doc:get_selection()
|
||||
table.insert(navigate.list, {
|
||||
filename = doc.filename,
|
||||
line = line,
|
||||
col = col
|
||||
})
|
||||
|
||||
navigate.current = navigate.list[#navigate.list]
|
||||
navigate.index = #navigate.list
|
||||
end
|
||||
|
||||
local function open_doc(doc)
|
||||
core.root_view:open_doc(
|
||||
core.open_doc(
|
||||
common.home_expand(
|
||||
doc.filename
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
local av_doc = get_active_view().doc
|
||||
local line, col = av_doc:get_selection()
|
||||
if doc.line ~= line or doc.col ~= col then
|
||||
av_doc:set_selection(doc.line, doc.col, doc.line, doc.col)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Public functions
|
||||
--
|
||||
function navigate.next()
|
||||
if navigate.index < #navigate.list then
|
||||
navigate.index = navigate.index + 1
|
||||
navigate.current = navigate.list[navigate.index]
|
||||
open_doc(navigate.current)
|
||||
end
|
||||
end
|
||||
|
||||
function navigate.prev()
|
||||
if navigate.index > 1 then
|
||||
navigate.index = navigate.index - 1
|
||||
navigate.current = navigate.list[navigate.index]
|
||||
open_doc(navigate.current)
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Thread
|
||||
--
|
||||
core.add_thread(function()
|
||||
while true do
|
||||
local av = get_active_view()
|
||||
if av and av.doc and av.doc.filename then
|
||||
local doc = av.doc
|
||||
local line, col = doc:get_selection()
|
||||
local current = navigate.current
|
||||
if
|
||||
not current
|
||||
or
|
||||
current.filename ~= doc.filename
|
||||
or
|
||||
current.line ~= line
|
||||
then
|
||||
add(doc)
|
||||
else
|
||||
current.col = col
|
||||
end
|
||||
end
|
||||
coroutine.yield(0.5)
|
||||
end
|
||||
end)
|
||||
|
||||
--
|
||||
-- Patching
|
||||
--
|
||||
local doc_on_close = Doc.on_close
|
||||
|
||||
function Doc:on_close()
|
||||
local filename = self.filename
|
||||
-- remove all positions referencing closed file
|
||||
array_remove(navigate.list, function(t, i)
|
||||
if t[i].filename == filename then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end)
|
||||
|
||||
doc_on_close(self)
|
||||
end
|
||||
|
||||
--
|
||||
-- Commands
|
||||
--
|
||||
command.add("core.docview", {
|
||||
["navigate:previous"] = function()
|
||||
navigate.prev()
|
||||
end,
|
||||
|
||||
["navigate:next"] = function()
|
||||
navigate.next()
|
||||
end,
|
||||
})
|
||||
|
||||
--
|
||||
-- Default Keybindings
|
||||
--
|
||||
keymap.add {
|
||||
["alt+left"] = "navigate:previous",
|
||||
["alt+right"] = "navigate:next",
|
||||
}
|
||||
|
||||
return navigate
|
|
@ -0,0 +1,59 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
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"}
|
|
@ -0,0 +1,55 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
-- Not perfect, because we can't actually figure out when something closes, but should be good enough, so long as we check the list of open views.
|
||||
-- Maybe find a better way to get at "Node"?
|
||||
local core = require "core"
|
||||
local RootView = require "core.rootview"
|
||||
local command = require "core.command"
|
||||
local keymap = require "core.keymap"
|
||||
|
||||
local update = RootView.update
|
||||
local initialized_tab_system = false
|
||||
|
||||
local tab_history = { }
|
||||
local history_size = 10
|
||||
|
||||
RootView.update = function(self)
|
||||
update(self)
|
||||
if not initialized_tab_system then
|
||||
local Node = getmetatable(self.root_node)
|
||||
local old_close = Node.close_view
|
||||
|
||||
Node.close_view = function(self, root, view)
|
||||
if view.doc and view.doc.abs_filename then
|
||||
local closing_filename = view.doc.abs_filename
|
||||
for i,filename in ipairs(tab_history) do
|
||||
if filename == closing_filename then
|
||||
table.remove(tab_history, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
table.insert(tab_history, closing_filename)
|
||||
if #tab_history > history_size then
|
||||
table.remove(tab_history, 1)
|
||||
end
|
||||
end
|
||||
old_close(self, root, view)
|
||||
end
|
||||
|
||||
initialized_tab_system = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
command.add("core.docview", {
|
||||
["restore-tabs:restore-tab"] = function()
|
||||
if #tab_history > 0 then
|
||||
local file = tab_history[#tab_history]
|
||||
core.root_view:open_doc(core.open_doc(file))
|
||||
table.remove(tab_history)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
keymap.add {
|
||||
["ctrl+shift+t"] = "restore-tabs:restore-tab"
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local style = require "core.style"
|
||||
local DocView = require "core.docview"
|
||||
local config = require "core.config"
|
||||
|
||||
-- originally written by luveti
|
||||
|
||||
local function draw_box(x, y, w, h, color)
|
||||
local r = renderer.draw_rect
|
||||
local s = math.ceil(SCALE)
|
||||
r(x, y, w, s, color)
|
||||
r(x, y + h - s, w, s, color)
|
||||
r(x, y + s, s, h - s * 2, color)
|
||||
r(x + w - s, y + s, s, h - s * 2, color)
|
||||
end
|
||||
|
||||
|
||||
local draw_line_body = DocView.draw_line_body
|
||||
|
||||
function DocView:draw_line_body(idx, x, y)
|
||||
local line1, col1, line2, col2 = self.doc:get_selection(true)
|
||||
local selection = self.doc:get_text(line1, col1, line2, col2)
|
||||
if line1 == line2 and col1 ~= col2 and not selection:match("^%s+$") then
|
||||
local lh = self:get_line_height()
|
||||
local selected_text = self.doc.lines[line1]:sub(col1, col2 - 1)
|
||||
local current_line_text = self.doc.lines[idx]
|
||||
local last_col = 1
|
||||
while true do
|
||||
local start_col, end_col = current_line_text:find(
|
||||
selected_text, last_col, true
|
||||
)
|
||||
if start_col == nil then break end
|
||||
local x1 = x + self:get_col_x_offset(idx, start_col)
|
||||
local x2 = x + self:get_col_x_offset(idx, end_col + 1)
|
||||
local color = style.selectionhighlight or style.syntax.comment
|
||||
draw_box(x1, y, x2 - x1, lh, color)
|
||||
last_col = end_col + 1
|
||||
end
|
||||
end
|
||||
draw_line_body(self, idx, x, y)
|
||||
end
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
-- mod-version:1 -- lite-xl 1.16
|
||||
local core = require "core"
|
||||
local common = require "core.common"
|
||||
local command = require "core.command"
|
||||
local config = require "core.config"
|
||||
local keymap = require "core.keymap"
|
||||
local style = require "core.style"
|
||||
local View = require "core.view"
|
||||
|
||||
|
||||
local TodoTreeView = View:extend()
|
||||
|
||||
config.todo_tags = {"TODO", "BUG", "FIX", "FIXME", "IMPROVEMENT"}
|
||||
|
||||
-- Paths or files to be ignored
|
||||
config.ignore_paths = {}
|
||||
|
||||
-- Tells if the plugin should start with the nodes expanded
|
||||
config.todo_expanded = true
|
||||
|
||||
-- 'tag' mode can be used to group the todos by tags
|
||||
-- 'file' mode can be used to group the todos by files
|
||||
config.todo_mode = "tag"
|
||||
|
||||
config.treeview_size = 200 * SCALE -- default size
|
||||
|
||||
function TodoTreeView:new()
|
||||
TodoTreeView.super.new(self)
|
||||
self.scrollable = true
|
||||
self.focusable = false
|
||||
self.visible = false
|
||||
self.times_cache = {}
|
||||
self.cache = {}
|
||||
self.cache_updated = false
|
||||
self.init_size = true
|
||||
|
||||
-- Items are generated from cache according to the mode
|
||||
self.items = {}
|
||||
end
|
||||
|
||||
local function is_file_ignored(filename)
|
||||
for _, path in ipairs(config.ignore_paths) do
|
||||
local s, _ = filename:find(path)
|
||||
if s then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
function TodoTreeView:refresh_cache()
|
||||
local items = {}
|
||||
if not next(self.items) then
|
||||
items = self.items
|
||||
end
|
||||
self.updating_cache = true
|
||||
|
||||
core.add_thread(function()
|
||||
for _, item in ipairs(core.project_files) do
|
||||
local ignored = is_file_ignored(item.filename)
|
||||
if not ignored and item.type == "file" then
|
||||
local cached = self:get_cached(item)
|
||||
|
||||
if config.todo_mode == "file" then
|
||||
items[cached.filename] = cached
|
||||
else
|
||||
for _, todo in ipairs(cached.todos) do
|
||||
local tag = todo.tag
|
||||
if not items[tag] then
|
||||
local t = {}
|
||||
t.expanded = config.todo_expanded
|
||||
t.type = "group"
|
||||
t.todos = {}
|
||||
t.tag = tag
|
||||
items[tag] = t
|
||||
end
|
||||
|
||||
table.insert(items[tag].todos, todo)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Copy expanded from old items
|
||||
if config.todo_mode == "tag" and next(self.items) then
|
||||
for tag, data in pairs(self.items) do
|
||||
if items[tag] then
|
||||
items[tag].expanded = data.expanded
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.items = items
|
||||
core.redraw = true
|
||||
self.cache_updated = true
|
||||
self.updating_cache = false
|
||||
end, self)
|
||||
end
|
||||
|
||||
|
||||
local function find_file_todos(t, filename)
|
||||
local fp = io.open(filename)
|
||||
if not fp then return t end
|
||||
local n = 1
|
||||
for line in fp:lines() do
|
||||
for _, todo_tag in ipairs(config.todo_tags) do
|
||||
local match_str = "[^a-zA-Z_\"'`]"..todo_tag.."[^\"'a-zA-Z_`]+"
|
||||
local s, e = line:find(match_str)
|
||||
if s then
|
||||
local d = {}
|
||||
d.tag = todo_tag
|
||||
d.filename = filename
|
||||
d.text = line:sub(e+1)
|
||||
d.line = n
|
||||
d.col = s
|
||||
table.insert(t, d)
|
||||
end
|
||||
core.redraw = true
|
||||
end
|
||||
if n % 100 == 0 then coroutine.yield() end
|
||||
n = n + 1
|
||||
core.redraw = true
|
||||
end
|
||||
fp:close()
|
||||
end
|
||||
|
||||
|
||||
function TodoTreeView:get_cached(item)
|
||||
local t = self.cache[item.filename]
|
||||
if not t then
|
||||
t = {}
|
||||
t.expanded = config.todo_expanded
|
||||
t.filename = item.filename
|
||||
t.abs_filename = system.absolute_path(item.filename)
|
||||
t.type = item.type
|
||||
t.todos = {}
|
||||
find_file_todos(t.todos, t.filename)
|
||||
self.cache[t.filename] = t
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
|
||||
function TodoTreeView:get_name()
|
||||
return "Todo Tree"
|
||||
end
|
||||
|
||||
function TodoTreeView:set_target_size(axis, value)
|
||||
if axis == "x" then
|
||||
config.treeview_size = value
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function TodoTreeView:get_item_height()
|
||||
return style.font:get_height() + style.padding.y
|
||||
end
|
||||
|
||||
|
||||
function TodoTreeView:get_cached_time(doc)
|
||||
local t = self.times_cache[doc]
|
||||
if not t then
|
||||
local info = system.get_file_info(doc.filename)
|
||||
if not info then return nil end
|
||||
self.times_cache[doc] = info.modified
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
|
||||
function TodoTreeView:check_cache()
|
||||
for _, doc in ipairs(core.docs) do
|
||||
if doc.filename then
|
||||
local info = system.get_file_info(doc.filename)
|
||||
local cached = self:get_cached_time(doc)
|
||||
if not info and cached then
|
||||
-- document deleted
|
||||
self.times_cache[doc] = nil
|
||||
self.cache[doc.filename] = nil
|
||||
self.cache_updated = false
|
||||
elseif cached and cached ~= info.modified then
|
||||
-- document modified
|
||||
self.times_cache[doc] = info.modified
|
||||
self.cache[doc.filename] = nil
|
||||
self.cache_updated = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if core.project_files ~= self.last_project_files then
|
||||
self.last_project_files = core.project_files
|
||||
self.cache_updated = false
|
||||
end
|
||||
end
|
||||
|
||||
function TodoTreeView:each_item()
|
||||
self:check_cache()
|
||||
if not self.updating_cache and not self.cache_updated then
|
||||
self:refresh_cache()
|
||||
end
|
||||
|
||||
return coroutine.wrap(function()
|
||||
local ox, oy = self:get_content_offset()
|
||||
local y = oy + style.padding.y
|
||||
local w = self.size.x
|
||||
local h = self:get_item_height()
|
||||
|
||||
for _, item in pairs(self.items) do
|
||||
if #item.todos > 0 then
|
||||
coroutine.yield(item, ox, y, w, h)
|
||||
y = y + h
|
||||
|
||||
for _, todo in ipairs(item.todos) do
|
||||
if item.expanded then
|
||||
coroutine.yield(todo, ox, y, w, h)
|
||||
y = y + h
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
function TodoTreeView:on_mouse_moved(px, py)
|
||||
self.hovered_item = nil
|
||||
for item, x,y,w,h in self:each_item() do
|
||||
if px > x and py > y and px <= x + w and py <= y + h then
|
||||
self.hovered_item = item
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function TodoTreeView:on_mouse_pressed(button, x, y)
|
||||
if not self.hovered_item then
|
||||
return
|
||||
elseif self.hovered_item.type == "file"
|
||||
or self.hovered_item.type == "group" then
|
||||
self.hovered_item.expanded = not self.hovered_item.expanded
|
||||
else
|
||||
core.try(function()
|
||||
local i = self.hovered_item
|
||||
local dv = core.root_view:open_doc(core.open_doc(i.filename))
|
||||
core.root_view.root_node:update_layout()
|
||||
dv.doc:set_selection(i.line, i.col)
|
||||
dv:scroll_to_line(i.line, false, true)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function TodoTreeView:update()
|
||||
self.scroll.to.y = math.max(0, self.scroll.to.y)
|
||||
|
||||
-- update width
|
||||
local dest = self.visible and config.treeview_size or 0
|
||||
if self.init_size then
|
||||
self.size.x = dest
|
||||
self.init_size = false
|
||||
else
|
||||
self:move_towards(self.size, "x", dest)
|
||||
end
|
||||
|
||||
TodoTreeView.super.update(self)
|
||||
end
|
||||
|
||||
|
||||
function TodoTreeView:draw()
|
||||
self:draw_background(style.background2)
|
||||
|
||||
--local h = self:get_item_height()
|
||||
local icon_width = style.icon_font:get_width("D")
|
||||
local spacing = style.font:get_width(" ") * 2
|
||||
local root_depth = 0
|
||||
|
||||
for item, x,y,w,h in self:each_item() do
|
||||
local color = style.text
|
||||
|
||||
-- hovered item background
|
||||
if item == self.hovered_item then
|
||||
renderer.draw_rect(x, y, w, h, style.line_highlight)
|
||||
color = style.accent
|
||||
end
|
||||
|
||||
-- icons
|
||||
local item_depth = 0
|
||||
x = x + (item_depth - root_depth) * style.padding.x + style.padding.x
|
||||
if item.type == "file" then
|
||||
local icon1 = item.expanded and "-" or "+"
|
||||
common.draw_text(style.icon_font, color, icon1, nil, x, y, 0, h)
|
||||
x = x + style.padding.x
|
||||
common.draw_text(style.icon_font, color, "f", nil, x, y, 0, h)
|
||||
x = x + icon_width
|
||||
elseif item.type == "group" then
|
||||
local icon1 = item.expanded and "-" or ">"
|
||||
common.draw_text(style.icon_font, color, icon1, nil, x, y, 0, h)
|
||||
x = x + icon_width / 2
|
||||
else
|
||||
if config.todo_mode == "tag" then
|
||||
x = x + style.padding.x
|
||||
else
|
||||
x = x + style.padding.x * 1.5
|
||||
end
|
||||
common.draw_text(style.icon_font, color, "i", nil, x, y, 0, h)
|
||||
x = x + icon_width
|
||||
end
|
||||
|
||||
-- text
|
||||
x = x + spacing
|
||||
if item.type == "file" then
|
||||
common.draw_text(style.font, color, item.filename, nil, x, y, 0, h)
|
||||
elseif item.type == "group" then
|
||||
common.draw_text(style.font, color, item.tag, nil, x, y, 0, h)
|
||||
else
|
||||
if config.todo_mode == "file" then
|
||||
common.draw_text(style.font, color, item.tag.." - "..item.text, nil, x, y, 0, h)
|
||||
else
|
||||
common.draw_text(style.font, color, item.text, nil, x, y, 0, h)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- init
|
||||
local view = TodoTreeView()
|
||||
local node = core.root_view:get_active_node()
|
||||
view.size.x = config.treeview_size
|
||||
node:split("right", view, {x=true}, true)
|
||||
|
||||
-- register commands and keymap
|
||||
command.add(nil, {
|
||||
["todotreeview:toggle"] = function()
|
||||
view.visible = not view.visible
|
||||
end,
|
||||
|
||||
["todotreeview:expand-items"] = function()
|
||||
for _, item in pairs(view.items) do
|
||||
item.expanded = true
|
||||
end
|
||||
end,
|
||||
|
||||
["todotreeview:hide-items"] = function()
|
||||
for _, item in pairs(view.items) do
|
||||
item.expanded = false
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
keymap.add { ["ctrl+shift+t"] = "todotreeview:toggle" }
|
||||
keymap.add { ["ctrl+shift+e"] = "todotreeview:expand-items" }
|
||||
keymap.add { ["ctrl+shift+h"] = "todotreeview:hide-items" }
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue