aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuldoman <giulio.lettieri@gmail.com>2021-11-19 19:15:50 +0100
committerGuldoman <giulio.lettieri@gmail.com>2021-11-19 19:15:50 +0100
commit333388602d6be6a967d07f0324bc8cefb8351a17 (patch)
tree1096b3f9c914d004d6be2f3cc3219f4a07e73498
parentbc0a289a79294445de9b0001bdaada93d801dadd (diff)
downloadlite-xl-plugins-333388602d6be6a967d07f0324bc8cefb8351a17.tar.gz
lite-xl-plugins-333388602d6be6a967d07f0324bc8cefb8351a17.zip
Add `indent_convert`
-rw-r--r--README.md1
-rw-r--r--plugins/indent_convert.lua100
2 files changed, 101 insertions, 0 deletions
diff --git a/README.md b/README.md
index 6647e2a..c304cb2 100644
--- a/README.md
+++ b/README.md
@@ -44,6 +44,7 @@ Plugin | Description
[`hidelinenumbers`](plugins/hidelinenumbers.lua?raw=1) | Hides the line numbers on the left of documents *([screenshot](https://user-images.githubusercontent.com/3920290/81692043-b8b19c00-9455-11ea-8d74-ad99be4b9c5f.png))*
[`hidestatus`](plugins/hidestatus.lua?raw=1) | Hides the status bar at the bottom of the window
~~[`inanimate`](plugins/inanimate.lua?raw=1)~~ | Integrated in lite-xl using `config.transitions = false` ~~Disables all transition animations~~
+*[`indent_convert`](plugins/indent_convert.lua?raw=1)* | Convert between tabs and spaces indentation
*[`indentguide`](plugins/indentguide.lua?raw=1)* | Adds indent guides *([screenshot](https://user-images.githubusercontent.com/3920290/79640716-f9860000-818a-11ea-9c3b-26d10dd0e0c0.png))*
*[`Kinc Projects`](https://github.com/Kode-Community/kinc_plugin)** | Adds [Kinc](https://github.com/Kode/Kinc) Project generation with basic build commands(depends on [`console`](https://github.com/franko/console))
[`language_angelscript`](plugins/language_angelscript.lua?raw=1) | Syntax for the [Angelscript](https://www.angelcode.com/angelscript/) programming language
diff --git a/plugins/indent_convert.lua b/plugins/indent_convert.lua
new file mode 100644
index 0000000..103f271
--- /dev/null
+++ b/plugins/indent_convert.lua
@@ -0,0 +1,100 @@
+-- mod-version:2 -- lite-xl 2.0
+local core = require "core"
+local config = require "core.config"
+local command = require "core.command"
+
+config.plugins.indent_convert = {
+ update_indent_type = true -- set to false to avoid updating the document indent type
+}
+
+-- To replace N spaces with tabs, we match the last N spaces before the start of
+-- the actual code and replace them with a tab.
+-- We repeat this until we can't find any more spaces before the code.
+-- The problem we encounter with this method is that if we have less than N
+-- remaining spaces, those will end up at the start of the line.
+-- Eg:
+-- int main() {
+-- __printf("Hello world\n");
+-- ___return 0;
+-- }
+--
+-- Becomes
+-- int main() {
+-- #printf("Hello world\n");
+-- _#return 0;
+-- }
+--
+-- Instead of
+-- int main() {
+-- #printf("Hello world\n");
+-- #_return 0;
+-- }
+-- With regex we could do something like
+-- `regex.gsub("(^(?: {2})*)(?: {2})", "\\1\t")`
+-- but the implementation of `regex.gsub` is very slow.
+--
+-- The workaround is to find the longest possible repetition of N*X spaces and
+-- use that information to replace the longest repetition of spaces starting
+-- from the beginning of the line, then the second longest...
+local function spaces_replacer(text)
+ local spaces = string.rep(" ", config.indent_size)
+ local total = 0
+ local n
+ local reps = 0
+ -- find the longest repetition of indent_size*spaces
+ repeat
+ reps = reps + 1
+ local s, _ = string.find(text, "%f[^\0\n]"..string.rep(spaces, reps))
+ until not s
+ reps = reps - 1
+ while reps > 0 do
+ text, n = string.gsub(text,
+ "(%f[^\0\n])("..string.rep(spaces, reps)..")",
+ "%1"..string.rep("\t", reps))
+ total = total + n
+ reps = reps - 1
+ end
+ return text, total
+end
+
+local function tabs_replacer(text)
+ local spaces = string.rep(" ", config.indent_size)
+ local total = 0
+ local n
+ -- replace the last tab before the text until there aren't anymore
+ repeat
+ text, n = string.gsub(text, "(%f[^\0\n]\t*)(\t)", "%1"..spaces)
+ total = total + n
+ until n == 0
+ return text, total
+end
+
+local function tabs_to_spaces()
+ local doc = core.active_view.doc
+ doc:replace(tabs_replacer)
+ if config.plugins.indent_convert.update_indent_type then
+ doc.indent_info = {
+ type = "soft",
+ size = config.indent_size,
+ confirmed = true
+ }
+ end
+end
+
+local function spaces_to_tabs()
+ local doc = core.active_view.doc
+ doc:replace(spaces_replacer)
+ if config.plugins.indent_convert.update_indent_type then
+ doc.indent_info = {
+ type = "hard",
+ size = config.indent_size,
+ confirmed = true
+ }
+ end
+end
+
+command.add("core.docview", {
+ ["indent-convert:tabs-to-spaces"] = tabs_to_spaces,
+ ["indent-convert:spaces-to-tabs"] = spaces_to_tabs
+ }
+)