From d1984942ea36f18d2462a08b2dc025f1b11d451c Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Mon, 5 Apr 2021 00:11:56 +0200 Subject: [PATCH 1/4] Add hook function for Doc changes --- data/core/doc/init.lua | 32 ++++++++++++++++++++++++-------- data/plugins/detectindent.lua | 12 ++++++------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index 6b63151a..6b880193 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -242,7 +242,7 @@ local function push_undo(undo_stack, time, type, ...) end -local function pop_undo(self, undo_stack, redo_stack) +local function pop_undo(self, undo_stack, redo_stack, modified) -- pop command local cmd = undo_stack[undo_stack.idx - 1] if not cmd then return end @@ -251,11 +251,11 @@ local function pop_undo(self, undo_stack, redo_stack) -- handle command if cmd.type == "insert" then local line, col, text = table.unpack(cmd) - self:raw_insert(line, col, text, redo_stack, cmd.time) + self:raw_insert(line, col, text, redo_stack, cmd.time, true) elseif cmd.type == "remove" then local line1, col1, line2, col2 = table.unpack(cmd) - self:raw_remove(line1, col1, line2, col2, redo_stack, cmd.time) + self:raw_remove(line1, col1, line2, col2, redo_stack, cmd.time, true) elseif cmd.type == "selection" then self.selection.a.line, self.selection.a.col = cmd[1], cmd[2] @@ -266,12 +266,16 @@ local function pop_undo(self, undo_stack, redo_stack) -- command and continue to execute it local next = undo_stack[undo_stack.idx - 1] if next and math.abs(cmd.time - next.time) < config.undo_merge_timeout then - return pop_undo(self, undo_stack, redo_stack) + return pop_undo(self, undo_stack, redo_stack, modified or cmd.type ~= "selection") + end + + if modified then + self:on_text_change("undo") end end -function Doc:raw_insert(line, col, text, undo_stack, time) +function Doc:raw_insert(line, col, text, undo_stack, time, quiet) -- split text into lines and merge with line at insertion point local lines = split_lines(text) local before = self.lines[line]:sub(1, col - 1) @@ -293,10 +297,14 @@ function Doc:raw_insert(line, col, text, undo_stack, time) -- update highlighter and assure selection is in bounds self.highlighter:invalidate(line) self:sanitize_selection() + + if not quiet then + self:on_text_change("insert") + end end -function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time) +function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time, quiet) -- push undo local text = self:get_text(line1, col1, line2, col2) push_undo(undo_stack, time, "selection", self:get_selection()) @@ -312,13 +320,17 @@ function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time) -- update highlighter and assure selection is in bounds self.highlighter:invalidate(line1) self:sanitize_selection() + + if not quiet then + self:on_text_change("remove") + end end function Doc:insert(line, col, text) self.redo_stack = { idx = 1 } line, col = self:sanitize_position(line, col) - self:raw_insert(line, col, text, self.undo_stack, system.get_time()) + self:raw_insert(line, col, text, self.undo_stack, system.get_time(), false) end @@ -327,7 +339,7 @@ function Doc:remove(line1, col1, line2, col2) line1, col1 = self:sanitize_position(line1, col1) line2, col2 = self:sanitize_position(line2, col2) line1, col1, line2, col2 = sort_positions(line1, col1, line2, col2) - self:raw_remove(line1, col1, line2, col2, self.undo_stack, system.get_time()) + self:raw_remove(line1, col1, line2, col2, self.undo_stack, system.get_time(), false) end @@ -398,5 +410,9 @@ function Doc:select_to(...) self:set_selection(line, col, line2, col2) end +-- For plugins to add custom actions of document change +function Doc:on_text_change(type) +end + return Doc diff --git a/data/plugins/detectindent.lua b/data/plugins/detectindent.lua index d323adb5..090f8d79 100644 --- a/data/plugins/detectindent.lua +++ b/data/plugins/detectindent.lua @@ -98,20 +98,20 @@ local function detect_indent_stat(doc) end -local doc_text_input = Doc.text_input +local doc_on_text_change = Doc.on_text_change local adjust_threshold = 4 local function update_cache(doc) local type, size, score = detect_indent_stat(doc) cache[doc] = { type = type, size = size, confirmed = (score >= adjust_threshold) } doc.indent_info = cache[doc] - if score < adjust_threshold and Doc.text_input == doc_text_input then - Doc.text_input = function(self, ...) - doc_text_input(self, ...) + if score < adjust_threshold and Doc.on_text_change == doc_on_text_change then + Doc.on_text_change = function(self, ...) + doc_on_text_change(self, ...) update_cache(self) end - elseif score >= adjust_threshold and Doc.text_input ~= doc_text_input then - Doc.text_input = doc_text_input + elseif score >= adjust_threshold and Doc.on_text_change ~= doc_on_text_change then + Doc.on_text_change = doc_on_text_change end end From e43c980e4a2bf46dd0c8d0bf911189027a78a465 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 6 Apr 2021 08:18:35 +0200 Subject: [PATCH 2/4] Simplifies previous commit Restore the previous signature of raw_insert/remove --- data/core/doc/init.lua | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index 6b880193..378f0896 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -251,11 +251,11 @@ local function pop_undo(self, undo_stack, redo_stack, modified) -- handle command if cmd.type == "insert" then local line, col, text = table.unpack(cmd) - self:raw_insert(line, col, text, redo_stack, cmd.time, true) + self:raw_insert(line, col, text, redo_stack, cmd.time) elseif cmd.type == "remove" then local line1, col1, line2, col2 = table.unpack(cmd) - self:raw_remove(line1, col1, line2, col2, redo_stack, cmd.time, true) + self:raw_remove(line1, col1, line2, col2, redo_stack, cmd.time) elseif cmd.type == "selection" then self.selection.a.line, self.selection.a.col = cmd[1], cmd[2] @@ -275,7 +275,7 @@ local function pop_undo(self, undo_stack, redo_stack, modified) end -function Doc:raw_insert(line, col, text, undo_stack, time, quiet) +function Doc:raw_insert(line, col, text, undo_stack, time) -- split text into lines and merge with line at insertion point local lines = split_lines(text) local before = self.lines[line]:sub(1, col - 1) @@ -297,14 +297,10 @@ function Doc:raw_insert(line, col, text, undo_stack, time, quiet) -- update highlighter and assure selection is in bounds self.highlighter:invalidate(line) self:sanitize_selection() - - if not quiet then - self:on_text_change("insert") - end end -function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time, quiet) +function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time) -- push undo local text = self:get_text(line1, col1, line2, col2) push_undo(undo_stack, time, "selection", self:get_selection()) @@ -320,17 +316,14 @@ function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time, quiet) -- update highlighter and assure selection is in bounds self.highlighter:invalidate(line1) self:sanitize_selection() - - if not quiet then - self:on_text_change("remove") - end end function Doc:insert(line, col, text) self.redo_stack = { idx = 1 } line, col = self:sanitize_position(line, col) - self:raw_insert(line, col, text, self.undo_stack, system.get_time(), false) + self:raw_insert(line, col, text, self.undo_stack, system.get_time()) + self:on_text_change("insert") end @@ -339,17 +332,18 @@ function Doc:remove(line1, col1, line2, col2) line1, col1 = self:sanitize_position(line1, col1) line2, col2 = self:sanitize_position(line2, col2) line1, col1, line2, col2 = sort_positions(line1, col1, line2, col2) - self:raw_remove(line1, col1, line2, col2, self.undo_stack, system.get_time(), false) + self:raw_remove(line1, col1, line2, col2, self.undo_stack, system.get_time()) + self:on_text_change("remove") end function Doc:undo() - pop_undo(self, self.undo_stack, self.redo_stack) + pop_undo(self, self.undo_stack, self.redo_stack, false) end function Doc:redo() - pop_undo(self, self.redo_stack, self.undo_stack) + pop_undo(self, self.redo_stack, self.undo_stack, false) end From 3721ace099b9360bd8e0fb36f299fe60126b4a02 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 6 Apr 2021 08:26:53 +0200 Subject: [PATCH 3/4] Fix logical error in on_text_change --- data/core/doc/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data/core/doc/init.lua b/data/core/doc/init.lua index 378f0896..3f1c39cd 100644 --- a/data/core/doc/init.lua +++ b/data/core/doc/init.lua @@ -262,11 +262,13 @@ local function pop_undo(self, undo_stack, redo_stack, modified) self.selection.b.line, self.selection.b.col = cmd[3], cmd[4] end + modified = modified or (cmd.type ~= "selection") + -- if next undo command is within the merge timeout then treat as a single -- command and continue to execute it local next = undo_stack[undo_stack.idx - 1] if next and math.abs(cmd.time - next.time) < config.undo_merge_timeout then - return pop_undo(self, undo_stack, redo_stack, modified or cmd.type ~= "selection") + return pop_undo(self, undo_stack, redo_stack, modified) end if modified then From 6e3cd41bd1274efa7e5eea2b376c3a5cc24743de Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Tue, 6 Apr 2021 08:27:35 +0200 Subject: [PATCH 4/4] Logical test simplification in detectindent --- data/plugins/detectindent.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/data/plugins/detectindent.lua b/data/plugins/detectindent.lua index 090f8d79..2a97e291 100644 --- a/data/plugins/detectindent.lua +++ b/data/plugins/detectindent.lua @@ -105,13 +105,14 @@ local function update_cache(doc) local type, size, score = detect_indent_stat(doc) cache[doc] = { type = type, size = size, confirmed = (score >= adjust_threshold) } doc.indent_info = cache[doc] - if score < adjust_threshold and Doc.on_text_change == doc_on_text_change then + if score < adjust_threshold and doc_on_text_change then Doc.on_text_change = function(self, ...) doc_on_text_change(self, ...) update_cache(self) end - elseif score >= adjust_threshold and Doc.on_text_change ~= doc_on_text_change then + elseif score >= adjust_threshold and doc_on_text_change then Doc.on_text_change = doc_on_text_change + doc_on_text_change = nil end end