aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mitchell <70453897+orbitalquark@users.noreply.github.com>2021-04-30 18:40:06 -0400
committerGravatar mitchell <70453897+orbitalquark@users.noreply.github.com>2021-04-30 18:40:06 -0400
commit715901363a02634f5336c0d3f18cbd9a9c080b4a (patch)
tree315146ace595595cefe4e6b4eae01c475a21a85b
parenta775e9fb4188f2638111c15623ea9bd5c804b3e2 (diff)
Replaced `events.FILE_{BEFORE,AFTER}_RELOAD` with `events.BUFFER_{BEFORE,AFTER}_REPLACE_TEXT`.
This allows more features to save/restore state when buffer contents are replaced (e.g. file reload, filter through, etc.)
-rw-r--r--core/.buffer.luadoc1
-rw-r--r--core/events.lua34
-rw-r--r--core/file_io.lua13
-rw-r--r--core/ui.lua4
-rw-r--r--docs/api.md29
-rw-r--r--docs/changelog.md6
-rw-r--r--docs/manual.md6
-rw-r--r--modules/lua/ta_api6
-rw-r--r--modules/lua/ta_tags4
-rw-r--r--modules/textadept/bookmarks.lua7
-rw-r--r--modules/textadept/history.lua33
-rw-r--r--test/test.lua5
12 files changed, 77 insertions, 71 deletions
diff --git a/core/.buffer.luadoc b/core/.buffer.luadoc
index 33b02bd5..2463a4bc 100644
--- a/core/.buffer.luadoc
+++ b/core/.buffer.luadoc
@@ -1671,7 +1671,6 @@ function style_of_name(buffer, style_name) end
---
-- Reloads the buffer's file contents, discarding any changes.
--- Emits `FILE_BEFORE_RELOAD` and `FILE_AFTER_RELOAD` events if the buffer is the current one.
-- @param buffer A buffer.
-- @name reload
function reload(buffer) end
diff --git a/core/events.lua b/core/events.lua
index 07829919..d9b263d4 100644
--- a/core/events.lua
+++ b/core/events.lua
@@ -59,10 +59,20 @@ local M = {}
-- Emitted right after switching to another buffer.
-- The buffer being switched to is `buffer`.
-- Emitted by [`view.goto_buffer()`]().
+-- @field BUFFER_BEFORE_REPLACE_TEXT (string)
+-- Emitted before replacing the contents of the current buffer.
+-- Note that it is not guaranteed that [`events.BUFFER_AFTER_REPLACE_TEXT`]() will be emitted
+-- shortly after this event.
+-- The buffer **must not** be modified during this event.
-- @field BUFFER_BEFORE_SWITCH (string)
-- Emitted right before switching to another buffer.
-- The buffer being switched from is `buffer`.
-- Emitted by [`view.goto_buffer()`]().
+-- @field BUFFER_AFTER_REPLACE_TEXT (string)
+-- Emitted after replacing the contents of the current buffer.
+-- Note that it is not guaranteed that [`events.BUFFER_BEFORE_REPLACE_TEXT`]() was emitted
+-- previously.
+-- The buffer **must not** be modified during this event.
-- @field BUFFER_DELETED (string)
-- Emitted after deleting a buffer.
-- Emitted by [`buffer.delete()`]().
@@ -383,8 +393,30 @@ end)
-- Set event constants.
for _, v in pairs(_SCINTILLA.events) do M[v[1]:upper()] = v[1] end
-- LuaFormatter off
-local textadept_events = {'appleevent_odoc','buffer_after_switch','buffer_before_switch','buffer_deleted','buffer_new','csi','command_text_changed','error','find','find_text_changed','focus','initialized','keypress','menu_clicked','mouse','quit','replace','replace_all','reset_after','reset_before','resume','suspend', 'tab_clicked','unfocus','view_after_switch','view_before_switch','view_new'}
+local textadept_events = {'appleevent_odoc','buffer_after_replace_text','buffer_after_switch','buffer_before_replace_text','buffer_before_switch','buffer_deleted','buffer_new','csi','command_text_changed','error','find','find_text_changed','focus','initialized','keypress','menu_clicked','mouse','quit','replace','replace_all','reset_after','reset_before','resume','suspend', 'tab_clicked','unfocus','view_after_switch','view_before_switch','view_new'}
-- LuaFormatter on
for _, v in pairs(textadept_events) do M[v:upper()] = v end
+-- Implement `events.BUFFER_{BEFORE,AFTER}_REPLACE_TEXT` as a convenience in lieu of the
+-- undocumented `events.MODIFIED`.
+local DELETE, INSERT, UNDOREDO = _SCINTILLA.constants.MOD_BEFOREDELETE,
+ _SCINTILLA.constants.MOD_INSERTTEXT, _SCINTILLA.constants.MULTILINEUNDOREDO
+-- Helper function for emitting `events.BUFFER_AFTER_REPLACE_TEXT` after a full-buffer undo/redo
+-- operation, e.g. after reloading buffer contents and then performing an undo.
+local function emit_after_replace_text()
+ events.disconnect(events.UPDATE_UI, emit_after_replace_text)
+ events.emit(events.BUFFER_AFTER_REPLACE_TEXT)
+end
+-- Emits events prior to and after replacing buffer text.
+M.connect(M.MODIFIED, function(position, mod, text, length)
+ if mod & (DELETE | INSERT) == 0 or length ~= buffer.length then return end
+ if mod & (INSERT | UNDOREDO) > 0 then
+ -- Cannot emit BUFFER_AFTER_REPLACE_TEXT here because Scintilla will do things like update
+ -- the selection afterwards, which could undo what event handlers do.
+ events.connect(events.UPDATE_UI, emit_after_replace_text)
+ return
+ end
+ M.emit(mod & DELETE > 0 and M.BUFFER_BEFORE_REPLACE_TEXT or M.BUFFER_AFTER_REPLACE_TEXT)
+end)
+
return M
diff --git a/core/file_io.lua b/core/file_io.lua
index 9dde8550..7f0c9999 100644
--- a/core/file_io.lua
+++ b/core/file_io.lua
@@ -9,12 +9,6 @@
-- Arguments:
--
-- * _`filename`_: The opened file's filename.
--- @field _G.events.FILE_BEFORE_RELOAD (string)
--- Emitted before reloading the current file.
--- Emitted by [`buffer:reload()`]().
--- @field _G.events.FILE_AFTER_RELOAD (string)
--- Emitted after reloading the current file.
--- Emitted by [`buffer:reload()`]().
-- @field _G.events.FILE_BEFORE_SAVE (string)
-- Emitted right before saving a file to disk.
-- Emitted by [`buffer:save()`]().
@@ -42,7 +36,7 @@ module('io')]]
-- Events.
-- LuaFormatter off
-local file_io_events = {'file_opened','file_before_reload','file_after_reload','file_before_save','file_after_save','file_changed'}
+local file_io_events = {'file_opened','file_before_save','file_after_save','file_changed'}
-- LuaFormatter on
for _, v in ipairs(file_io_events) do events[v:upper()] = v end
@@ -157,16 +151,13 @@ end
local function reload(buffer)
if not buffer then buffer = _G.buffer end
if not buffer.filename then return end
- if buffer == _G.buffer then events.emit(events.FILE_BEFORE_RELOAD) end
local f = assert(io.open(buffer.filename, 'rb'))
local text = f:read('a')
f:close()
if buffer.encoding then text = text:iconv('UTF-8', buffer.encoding) end
- buffer:clear_all()
- buffer:append_text(text)
+ buffer:set_text(text)
buffer:set_save_point()
buffer.mod_time = lfs.attributes(buffer.filename, 'modification')
- if buffer == _G.buffer then events.emit(events.FILE_AFTER_RELOAD) end
end
-- LuaDoc is in core/.buffer.luadoc.
diff --git a/core/ui.lua b/core/ui.lua
index 2e0635fa..c8266775 100644
--- a/core/ui.lua
+++ b/core/ui.lua
@@ -358,7 +358,7 @@ local function save_buffer_state()
buffer._folds = folds
end
events.connect(events.BUFFER_BEFORE_SWITCH, save_buffer_state)
-events.connect(events.FILE_BEFORE_RELOAD, save_buffer_state)
+events.connect(events.BUFFER_BEFORE_REPLACE_TEXT, save_buffer_state)
-- Restore buffer properties.
local function restore_buffer_state()
@@ -375,7 +375,7 @@ local function restore_buffer_state()
view.x_offset = buffer._x_offset or 0
end
events.connect(events.BUFFER_AFTER_SWITCH, restore_buffer_state)
-events.connect(events.FILE_AFTER_RELOAD, restore_buffer_state)
+events.connect(events.BUFFER_AFTER_REPLACE_TEXT, restore_buffer_state)
-- Updates titlebar and statusbar.
local function update_bars()
diff --git a/docs/api.md b/docs/api.md
index 61d61dbe..c73bdf7a 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -2933,7 +2933,6 @@ Parameters:
#### `buffer.reload`(*buffer*)
Reloads the buffer's file contents, discarding any changes.
-Emits `FILE_BEFORE_RELOAD` and `FILE_AFTER_RELOAD` events if the buffer is the current one.
Parameters:
@@ -3711,6 +3710,14 @@ Emitted as items are highlighted in an autocompletion or user list.
* _`text`_: The current selection's text.
* _`position`_: The position the list was displayed at.
+<a id="events.BUFFER_AFTER_REPLACE_TEXT"></a>
+#### `events.BUFFER_AFTER_REPLACE_TEXT` (string)
+
+Emitted after replacing the contents of the current buffer.
+ Note that it is not guaranteed that [`events.BUFFER_BEFORE_REPLACE_TEXT`](#events.BUFFER_BEFORE_REPLACE_TEXT) was emitted
+ previously.
+ The buffer **must not** be modified during this event.
+
<a id="events.BUFFER_AFTER_SWITCH"></a>
#### `events.BUFFER_AFTER_SWITCH` (string)
@@ -3718,6 +3725,14 @@ Emitted right after switching to another buffer.
The buffer being switched to is `buffer`.
Emitted by [`view.goto_buffer()`](#view.goto_buffer).
+<a id="events.BUFFER_BEFORE_REPLACE_TEXT"></a>
+#### `events.BUFFER_BEFORE_REPLACE_TEXT` (string)
+
+Emitted before replacing the contents of the current buffer.
+ Note that it is not guaranteed that [`events.BUFFER_AFTER_REPLACE_TEXT`](#events.BUFFER_AFTER_REPLACE_TEXT) will be emitted
+ shortly after this event.
+ The buffer **must not** be modified during this event.
+
<a id="events.BUFFER_BEFORE_SWITCH"></a>
#### `events.BUFFER_BEFORE_SWITCH` (string)
@@ -4139,12 +4154,6 @@ Extends Lua's `io` library with Textadept functions for working with files.
### Fields defined by `io`
-<a id="events.FILE_AFTER_RELOAD"></a>
-#### `events.FILE_AFTER_RELOAD` (string)
-
-Emitted after reloading the current file.
- Emitted by [`buffer:reload()`](#buffer.reload).
-
<a id="events.FILE_AFTER_SAVE"></a>
#### `events.FILE_AFTER_SAVE` (string)
@@ -4155,12 +4164,6 @@ Emitted right after saving a file to disk.
* _`filename`_: The filename of the file being saved.
* _`saved_as`_: Whether or not the file was saved under a different filename.
-<a id="events.FILE_BEFORE_RELOAD"></a>
-#### `events.FILE_BEFORE_RELOAD` (string)
-
-Emitted before reloading the current file.
- Emitted by [`buffer:reload()`](#buffer.reload).
-
<a id="events.FILE_BEFORE_SAVE"></a>
#### `events.FILE_BEFORE_SAVE` (string)
diff --git a/docs/changelog.md b/docs/changelog.md
index b533f394..346a487a 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -221,8 +221,8 @@ Changes:
* Added support for jq language.
* Record directory in "Find in Files" searches.
* Added `ui.update()`, mainly for unit tests.
-* Added [`events.FILE_BEFORE_RELOAD`][] and [`events.FILE_AFTER_RELOAD`][] events, and
- save/restore bookmarks.
+* Added `events.FILE_BEFORE_RELOAD` and `events.FILE_AFTER_RELOAD` events, and save/restore
+ bookmarks.
* Added [`events.COMMAND_TEXT_CHANGED`][] for when command entry text changes.
* Added `_NOCOMPAT` option to disable temporary key shortcut compatibility checking.
* Updated Spanish translation.
@@ -240,8 +240,6 @@ Changes:
[building with Docker]: manual.html#compiling-using-docker
[`events.FIND_RESULT_FOUND`]: api.html#events.FIND_RESULT_FOUND
[`ui.find.active`]: api.html#ui.find.active
-[`events.FILE_BEFORE_RELOAD`]: api.html#events.FILE_BEFORE_RELOAD
-[`events.FILE_AFTER_RELOAD`]: api.html#events.FILE_AFTER_RELOAD
[`events.COMMAND_TEXT_CHANGED`]: api.html#events.COMMAND_TEXT_CHANGED
[`view.multi_edge_column`]: api.html#view.multi_edge_column
[Scintilla]: https://scintilla.org
diff --git a/docs/manual.md b/docs/manual.md
index 52e8fd6d..8036d184 100644
--- a/docs/manual.md
+++ b/docs/manual.md
@@ -1718,8 +1718,8 @@ vertical\_centre\_caret | Renamed | vertical\_center\_caret
**events**||
AUTO\_C\_CANCELLED | Renamed | AUTO\_C\_CANCELED
N/A | Added | [COMMAND_TEXT_CHANGED][]
-N/A | Added | [FILE_BEFORE_RELOAD][]
-N/A | Added | [FILE_AFTER_RELOAD][]
+N/A | Added | FILE_BEFORE_RELOAD
+N/A | Added | FILE_AFTER_RELOAD
N/A | Added | [FIND_RESULT_FOUND][]
N/A | Added | [FIND_TEXT_CHANGED][]
N/A | Added | [SESSION_SAVE][]
@@ -1784,8 +1784,6 @@ N/A | Added | _buffer functions and fields_<sup>d</sup>
[view:set_theme()]: api.html#view.set_theme
[name_of_style]: api.html#buffer.name_of_style
[COMMAND_TEXT_CHANGED]: api.html#events.COMMAND_TEXT_CHANGED
-[FILE_BEFORE_RELOAD]: api.html#events.FILE_BEFORE_RELOAD
-[FILE_AFTER_RELOAD]: api.html#events.FILE_AFTER_RELOAD
[FIND_RESULT_FOUND]: api.html#events.FIND_RESULT_FOUND
[FIND_TEXT_CHANGED]: api.html#events.FIND_TEXT_CHANGED
[SESSION_SAVE]: api.html#events.SESSION_SAVE
diff --git a/modules/lua/ta_api b/modules/lua/ta_api
index d1c83c0e..6e400e97 100644
--- a/modules/lua/ta_api
+++ b/modules/lua/ta_api
@@ -13,7 +13,9 @@ AUTO_C_COMPLETED events.AUTO_C_COMPLETED (string)\nEmitted after inserting an it
AUTO_C_SELECTION events.AUTO_C_SELECTION (string)\nEmitted after selecting an item from an autocompletion list, but before inserting that\nitem into the buffer.\nAutomatic insertion can be canceled by calling `buffer:auto_c_cancel()` before returning\nfrom the event handler.\nArguments:\n\n* _`text`_: The selection's text.\n* _`position`_: The autocompleted word's beginning position.
AUTO_C_SELECTION_CHANGE events.AUTO_C_SELECTION_CHANGE (string)\nEmitted as items are highlighted in an autocompletion or user list.\nArguments:\n\n* _`id`_: Either the *id* from `buffer.user_list_show()` or `0` for an autocompletion list.\n* _`text`_: The current selection's text.\n* _`position`_: The position the list was displayed at.
BSD _G.BSD (bool)\nWhether or not Textadept is running on BSD.
+BUFFER_AFTER_REPLACE_TEXT events.BUFFER_AFTER_REPLACE_TEXT (string)\nEmitted after replacing the contents of the current buffer.\nNote that it is not guaranteed that `events.BUFFER_BEFORE_REPLACE_TEXT` was emitted\npreviously.\nThe buffer **must not** be modified during this event.
BUFFER_AFTER_SWITCH events.BUFFER_AFTER_SWITCH (string)\nEmitted right after switching to another buffer.\nThe buffer being switched to is `buffer`.\nEmitted by `view.goto_buffer()`.
+BUFFER_BEFORE_REPLACE_TEXT events.BUFFER_BEFORE_REPLACE_TEXT (string)\nEmitted before replacing the contents of the current buffer.\nNote that it is not guaranteed that `events.BUFFER_AFTER_REPLACE_TEXT` will be emitted\nshortly after this event.\nThe buffer **must not** be modified during this event.
BUFFER_BEFORE_SWITCH events.BUFFER_BEFORE_SWITCH (string)\nEmitted right before switching to another buffer.\nThe buffer being switched from is `buffer`.\nEmitted by `view.goto_buffer()`.
BUFFER_DELETED events.BUFFER_DELETED (string)\nEmitted after deleting a buffer.\nEmitted by `buffer.delete()`.
BUFFER_NEW events.BUFFER_NEW (string)\nEmitted after creating a new buffer.\nThe new buffer is `buffer`.\nEmitted on startup and by `buffer.new()`.
@@ -62,9 +64,7 @@ EOL_CRLF buffer.EOL_CRLF (number, Read-only)\n
EOL_LF buffer.EOL_LF (number, Read-only)\n
ERROR events.ERROR (string)\nEmitted when an error occurs.\nArguments:\n\n* _`text`_: The error message text.
ERROR lexer.ERROR (string)\nThe token name for error tokens.
-FILE_AFTER_RELOAD events.FILE_AFTER_RELOAD (string)\nEmitted after reloading the current file.\nEmitted by `buffer:reload()`.
FILE_AFTER_SAVE events.FILE_AFTER_SAVE (string)\nEmitted right after saving a file to disk.\nEmitted by `buffer:save()` and `buffer:save_as()`.\nArguments:\n\n* _`filename`_: The filename of the file being saved.\n* _`saved_as`_: Whether or not the file was saved under a different filename.
-FILE_BEFORE_RELOAD events.FILE_BEFORE_RELOAD (string)\nEmitted before reloading the current file.\nEmitted by `buffer:reload()`.
FILE_BEFORE_SAVE events.FILE_BEFORE_SAVE (string)\nEmitted right before saving a file to disk.\nEmitted by `buffer:save()`.\nArguments:\n\n* _`filename`_: The filename of the file being saved.
FILE_CHANGED events.FILE_CHANGED (string)\nEmitted when Textadept detects that an open file was modified externally.\nWhen connecting to this event, connect with an index of 1 in order to override the default\nprompt to reload the file.\nArguments:\n\n* _`filename`_: The filename externally modified.
FILE_OPENED events.FILE_OPENED (string)\nEmitted after opening a file in a new buffer.\nEmitted by `io.open_file()`.\nArguments:\n\n* _`filename`_: The opened file's filename.
@@ -796,7 +796,7 @@ regex_label_text ui.find.regex_label_text (string, Write-only)\nThe text of the
register args.register(short, long, narg, f, description)\nRegisters a command line option with short and long versions *short* and *long*, respectively.\n*narg* is the number of arguments the option accepts, *f* is the function called when the\noption is set, and *description* is the option's description when displaying help.\n@param short The string short version of the option.\n@param long The string long version of the option.\n@param narg The number of expected parameters for the option.\n@param f The Lua function to run when the option is set. It is passed *narg* string arguments.\n@param description The string description of the option for command line help.
register_image view.register_image(view, type, xpm_data)\nRegisters XPM image *xpm_data* to type number *type* for use in autocompletion and user lists.\n@param view A view.\n@param type Integer type to register the image with.\n@param xpm_data The XPM data as described in `view.marker_define_pixmap()`.
register_rgba_image view.register_rgba_image(view, type, pixels)\nRegisters RGBA image *pixels* to type number *type* for use in autocompletion and user lists.\nThe dimensions for *pixels* (`view.rgba_image_width` and `view.rgba_image_height`) must\nhave already been defined. *pixels* is a sequence of 4 byte pixel values (red, blue, green,\nand alpha) defining the image line by line starting at the top-left pixel.\n@param view A view.\n@param type Integer type to register the image with.\n@param pixels The RGBA data as described in `view.marker_define_rgba_image()`.
-reload buffer.reload(buffer)\nReloads the buffer's file contents, discarding any changes.\nEmits `FILE_BEFORE_RELOAD` and `FILE_AFTER_RELOAD` events if the buffer is the current one.\n@param buffer A buffer.
+reload buffer.reload(buffer)\nReloads the buffer's file contents, discarding any changes.\n@param buffer A buffer.
replace ui.find.replace()\nMimics pressing the "Replace" button.
replace_all ui.find.replace_all()\nMimics pressing the "Replace All" button.
replace_all_button_text ui.find.replace_all_button_text (string, Write-only)\nThe text of the "Replace All" button.\nThis is primarily used for localization.
diff --git a/modules/lua/ta_tags b/modules/lua/ta_tags
index 5471b09f..453bd320 100644
--- a/modules/lua/ta_tags
+++ b/modules/lua/ta_tags
@@ -13,7 +13,9 @@ AUTO_C_COMPLETED _HOME/core/events.lua /^module('events')]]$/;" F class:events
AUTO_C_SELECTION _HOME/core/events.lua /^module('events')]]$/;" F class:events
AUTO_C_SELECTION_CHANGE _HOME/core/events.lua /^module('events')]]$/;" F class:events
BSD _HOME/core/init.lua /^module('_G')]]$/;" F
+BUFFER_AFTER_REPLACE_TEXT _HOME/core/events.lua /^module('events')]]$/;" F class:events
BUFFER_AFTER_SWITCH _HOME/core/events.lua /^module('events')]]$/;" F class:events
+BUFFER_BEFORE_REPLACE_TEXT _HOME/core/events.lua /^module('events')]]$/;" F class:events
BUFFER_BEFORE_SWITCH _HOME/core/events.lua /^module('events')]]$/;" F class:events
BUFFER_DELETED _HOME/core/events.lua /^module('events')]]$/;" F class:events
BUFFER_NEW _HOME/core/events.lua /^module('events')]]$/;" F class:events
@@ -62,9 +64,7 @@ EOL_CRLF _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer
EOL_LF _HOME/core/.buffer.luadoc /^module('buffer')$/;" F class:buffer
ERROR _HOME/core/events.lua /^module('events')]]$/;" F class:events
ERROR _HOME/lexers/lexer.lua /^module('lexer')]=]$/;" F class:lexer
-FILE_AFTER_RELOAD _HOME/core/file_io.lua /^module('io')]]$/;" F class:events
FILE_AFTER_SAVE _HOME/core/file_io.lua /^module('io')]]$/;" F class:events
-FILE_BEFORE_RELOAD _HOME/core/file_io.lua /^module('io')]]$/;" F class:events
FILE_BEFORE_SAVE _HOME/core/file_io.lua /^module('io')]]$/;" F class:events
FILE_CHANGED _HOME/core/file_io.lua /^module('io')]]$/;" F class:events
FILE_OPENED _HOME/core/file_io.lua /^module('io')]]$/;" F class:events
diff --git a/modules/textadept/bookmarks.lua b/modules/textadept/bookmarks.lua
index 532d1427..5f919e3d 100644
--- a/modules/textadept/bookmarks.lua
+++ b/modules/textadept/bookmarks.lua
@@ -80,10 +80,11 @@ function M.goto_mark(next)
end
local lines = {}
--- Save and restore bookmarks on buffer:reload().
-events.connect(events.FILE_BEFORE_RELOAD,
+-- Save and restore bookmarks when replacing buffer text (e.g. buffer:reload(),
+-- textadept.editing.filter_through()).
+events.connect(events.BUFFER_BEFORE_REPLACE_TEXT,
function() for line in bookmarks(buffer) do lines[#lines + 1] = line end end)
-events.connect(events.FILE_AFTER_RELOAD, function()
+events.connect(events.BUFFER_AFTER_REPLACE_TEXT, function()
for _, line in ipairs(lines) do buffer:marker_add(line, M.MARK_BOOKMARK) end
lines = {} -- clear
end)
diff --git a/modules/textadept/history.lua b/modules/textadept/history.lua
index 8c784c17..f6238a0d 100644
--- a/modules/textadept/history.lua
+++ b/modules/textadept/history.lua
@@ -33,36 +33,15 @@ local view_history = setmetatable({}, {
end
})
-local restore_position, pos, first_visible_line = false, nil, nil
--- Restore position after a full-buffer undo/redo operation, e.g. after replacing buffer contents
--- with a formatting command and then performing an undo.
-events.connect(events.UPDATE_UI, function(updated)
- if not restore_position or updated & buffer.UPDATE_SELECTION == 0 then return end
- restore_position = false
- buffer:goto_pos(pos)
- view.first_visible_line, pos, first_visible_line = first_visible_line, nil, nil
-end)
-
+local INSERT, DELETE = buffer.MOD_INSERTTEXT, buffer.MOD_DELETETEXT
+local UNDO, REDO = buffer.PERFORMED_UNDO, buffer.PERFORMED_REDO
-- Listens for text insertion and deletion events and records their locations.
events.connect(events.MODIFIED, function(position, mod, text, length)
- local buffer = buffer
- -- Only interested in text insertion or deletion.
- if mod & buffer.MOD_INSERTTEXT > 0 then
- if length == buffer.length then
- if mod & buffer.MULTILINEUNDOREDO > 0 then restore_position = true end
- return -- ignore file loading or replacing buffer contents
- end
- position = position + length
- elseif mod & buffer.MOD_DELETETEXT > 0 then
- if buffer.length == 0 then return end -- ignore replacing buffer contents
- elseif mod & (buffer.PERFORMED_UNDO | buffer.PERFORMED_REDO) > 0 and
- (mod & buffer.MOD_BEFOREDELETE > 0) and length == buffer.length then
- -- Save view state for potential undo before it's lost.
- pos, first_visible_line = buffer.current_pos, view.first_visible_line
- else
- return
+ if mod & (INSERT | DELETE) == 0 or buffer.length == (mod & INSERT > 0 and length or 0) then
+ return -- ignore non-insertion/deletion, file loading, and replacing buffer contents
end
- if mod & (buffer.PERFORMED_UNDO | buffer.PERFORMED_REDO) > 0 then return end -- ignore undo/redo
+ if mod & INSERT > 0 then position = position + length end
+ if mod & (UNDO | REDO) > 0 then return end -- ignore undo/redo
M.record(nil, buffer:line_from_position(position), buffer.column[position])
end)
diff --git a/test/test.lua b/test/test.lua
index ebb7344b..09caf59e 100644
--- a/test/test.lua
+++ b/test/test.lua
@@ -351,6 +351,8 @@ function test_file_io_reload_file()
assert(buffer:get_text() ~= text, 'buffer text is unchanged')
buffer:reload()
assert_equal(buffer:get_text(), text)
+ ui.update()
+ if CURSES then events.emit(events.UPDATE_UI, buffer.UPDATE_SELECTION) end
assert_equal(buffer.current_pos, pos)
buffer:close()
end
@@ -1237,6 +1239,8 @@ function test_bookmarks_reload()
assert(has_bookmark(2), 'line not bookmarked')
assert(has_bookmark(4), 'line not bookmarked')
buffer:reload()
+ ui.update()
+ if CURSES then events.emit(events.UPDATE_UI, buffer.UPDATE_SELECTION) end
assert(has_bookmark(2), 'bookmark not restored')
assert(has_bookmark(4), 'bookmark not restored')
buffer:close(true)
@@ -3047,6 +3051,7 @@ function test_menu_menu_functions()
textadept.menu.menubar[_L['Edit']][_L['Delete Word']][2]()
assert_equal(buffer:get_text(), '')
buffer:set_text('(foo)')
+ buffer:home()
textadept.menu.menubar[_L['Edit']][_L['Match Brace']][2]()
assert_equal(buffer.char_at[buffer.current_pos], string.byte(')'))
buffer:set_text('foo f')