diff options
author | mitchell <70453897+orbitalquark@users.noreply.github.com> | 2020-09-19 14:53:20 -0400 |
---|---|---|
committer | mitchell <70453897+orbitalquark@users.noreply.github.com> | 2020-09-19 14:53:20 -0400 |
commit | 14e524cf217250388d374433cf6f3241f66e4e01 (patch) | |
tree | baa0c6f3c45cbd1946403a9762cadcffdb530ef7 | |
parent | 28a73bcf0fe6fa9cd97e50734fb243c625284a89 (diff) |
Added `events.FILE_{BEFORE,AFTER}_RELOAD` and save/restore bookmarks.
Also moved buffer state save/restore into ui module.
-rw-r--r-- | core/.buffer.luadoc | 2 | ||||
-rw-r--r-- | core/file_io.lua | 15 | ||||
-rw-r--r-- | core/ui.lua | 12 | ||||
-rw-r--r-- | docs/api.md | 14 | ||||
-rw-r--r-- | docs/manual.md | 4 | ||||
-rw-r--r-- | modules/lua/ta_api | 4 | ||||
-rw-r--r-- | modules/lua/ta_tags | 2 | ||||
-rw-r--r-- | modules/textadept/bookmarks.lua | 24 | ||||
-rw-r--r-- | test/modules/textadept/bookmarks/foo | 4 | ||||
-rw-r--r-- | test/test.lua | 19 |
10 files changed, 86 insertions, 14 deletions
diff --git a/core/.buffer.luadoc b/core/.buffer.luadoc index 7a70b5c4..9ad6ee0d 100644 --- a/core/.buffer.luadoc +++ b/core/.buffer.luadoc @@ -1781,6 +1781,8 @@ 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/file_io.lua b/core/file_io.lua index d45372ec..71dd5af3 100644 --- a/core/file_io.lua +++ b/core/file_io.lua @@ -9,6 +9,12 @@ -- 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()`](). @@ -38,6 +44,8 @@ module('io')]] -- Events. local events, events_connect = events, events.connect events.FILE_OPENED = 'file_opened' +events.FILE_BEFORE_RELOAD = 'file_before_reload' +events.FILE_AFTER_RELOAD = 'file_after_reload' events.FILE_BEFORE_SAVE = 'file_before_save' events.FILE_AFTER_SAVE = 'file_after_save' events.FILE_CHANGED = 'file_changed' @@ -153,7 +161,7 @@ end local function reload(buffer) if not buffer then buffer = _G.buffer end if not buffer.filename then return end - local pos, first_visible_line = buffer.current_pos, view.first_visible_line + 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() @@ -161,10 +169,7 @@ local function reload(buffer) buffer:set_text(text) buffer:set_save_point() buffer.mod_time = lfs.attributes(buffer.filename, 'modification') - if buffer == _G.buffer then - buffer:goto_pos(pos) - view.first_visible_line = first_visible_line - end + 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 66828bc2..ef6e6ac9 100644 --- a/core/ui.lua +++ b/core/ui.lua @@ -347,7 +347,7 @@ events_connect(events.UPDATE_UI, function(updated) end) -- Save buffer properties. -events_connect(events.BUFFER_BEFORE_SWITCH, function() +local function save_buffer_state() -- Save view state. buffer._anchor, buffer._current_pos = buffer.anchor, buffer.current_pos local n = buffer.main_selection @@ -361,10 +361,12 @@ events_connect(events.BUFFER_BEFORE_SWITCH, function() folds[#folds + 1], i = i, view:contracted_fold_next(i + 1) end buffer._folds = folds -end) +end +events_connect(events.BUFFER_BEFORE_SWITCH, save_buffer_state) +events_connect(events.FILE_BEFORE_RELOAD, save_buffer_state) -- Restore buffer properties. -events_connect(events.BUFFER_AFTER_SWITCH, function() +local function restore_buffer_state() if not buffer._folds then return end -- Restore fold state. for i = 1, #buffer._folds do view:toggle_fold(buffer._folds[i]) end @@ -376,7 +378,9 @@ events_connect(events.BUFFER_AFTER_SWITCH, function() local _top_line, top_line = buffer._top_line, view.first_visible_line view:line_scroll(0, view:visible_from_doc_line(_top_line) - top_line) view.x_offset = buffer._x_offset or 0 -end) +end +events_connect(events.BUFFER_AFTER_SWITCH, restore_buffer_state) +events_connect(events.FILE_AFTER_RELOAD, restore_buffer_state) -- Updates titlebar and statusbar. local function update_bars() diff --git a/docs/api.md b/docs/api.md index e57c9b7c..99ca01ac 100644 --- a/docs/api.md +++ b/docs/api.md @@ -3060,6 +3060,8 @@ 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: @@ -4306,6 +4308,12 @@ 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) @@ -4317,6 +4325,12 @@ Emitted right after saving a file to disk. * _`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/manual.md b/docs/manual.md index 424e9681..3a2f91b5 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -1860,6 +1860,8 @@ set\_fold\_margin\_\*colour|Renamed |set\_fold\_margin\_\*color vertical\_centre\_caret |Renamed |vertical\_center\_caret **events** | | AUTO\_C\_CANCELLED |Renamed |AUTO\_C\_CANCELED +N/A |Added |[FILE_BEFORE_RELOAD][] +N/A |Added |[FILE_AFTER_RELOAD][] N/A |Added |[SESSION_SAVE][] N/A |Added |[SESSION_LOAD][] **io** | | @@ -1916,6 +1918,8 @@ section below. [view:set_theme()]: api.html#view.set_theme [name_of_style]: api.html#buffer.name_of_style +[FILE_BEFORE_RELOAD]: api.html#events.FILE_BEFORE_RELOAD +[FILE_AFTER_RELOAD]: api.html#events.FILE_AFTER_RELOAD [SESSION_SAVE]: api.html#events.SESSION_SAVE [SESSION_LOAD]: api.html#events.SESSION_LOAD [buffer:reload()]: api.html#buffer.reload diff --git a/modules/lua/ta_api b/modules/lua/ta_api index 6a7faa4e..315fe204 100644 --- a/modules/lua/ta_api +++ b/modules/lua/ta_api @@ -61,7 +61,9 @@ 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\n 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\noverride the default prompt 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. @@ -779,7 +781,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 switch with short and long versions *short* and\n*long*, respectively. *narg* is the number of arguments the switch accepts,\n*f* is the function called when the switch is tripped, and *description* is\nthe switch's description when displaying help.\n@param short The string short version of the switch.\n@param long The string long version of the switch.\n@param narg The number of expected parameters for the switch.\n@param f The Lua function to run when the switch is tripped. It is passed\n *narg* string arguments.\n@param description The string description of the switch for command line\n help. register_image view.register_image(view, type, xpm_data)\nRegisters XPM image *xpm_data* to type number *type* for use in\nautocompletion 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\nand user lists.\nThe dimensions for *pixels* (`view.rgba_image_width` and\n`view.rgba_image_height`) must have already been defined. *pixels* is a\nsequence of 4 byte pixel values (red, blue, green, and alpha) defining the\nimage 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\n `view.marker_define_rgba_image()`. -reload buffer.reload(buffer)\nReloads the buffer's file contents, discarding any changes.\n@param buffer A buffer. +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\nthe current one.\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 ecda2683..feb359d0 100644 --- a/modules/lua/ta_tags +++ b/modules/lua/ta_tags @@ -61,7 +61,9 @@ 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 a065baff..04ade1a4 100644 --- a/modules/textadept/bookmarks.lua +++ b/modules/textadept/bookmarks.lua @@ -26,6 +26,14 @@ end -- @name clear function M.clear() buffer:marker_delete_all(M.MARK_BOOKMARK) end +-- Returns an iterator for all bookmarks in the current buffer. +local function bookmarks() + return function(_, line) + line = buffer:marker_next(line + 1, 1 << M.MARK_BOOKMARK - 1) + return line >= 1 and line or nil + end, nil, 0 +end + --- -- Prompts the user to select a bookmarked line to move the caret to the -- beginning of unless *next* is given. @@ -36,10 +44,10 @@ function M.clear() buffer:marker_delete_all(M.MARK_BOOKMARK) end -- prompting the user for a bookmarked line to go to. -- @name goto_mark function M.goto_mark(next) - local BOOKMARK_BIT = 1 << M.MARK_BOOKMARK - 1 if next ~= nil then local f = next and buffer.marker_next or buffer.marker_previous local current_line = buffer:line_from_position(buffer.current_pos) + local BOOKMARK_BIT = 1 << M.MARK_BOOKMARK - 1 local line = f(buffer, current_line + (next and 1 or -1), BOOKMARK_BIT) if line == -1 then line = f(buffer, (next and 1 or buffer.line_count), BOOKMARK_BIT) @@ -55,12 +63,10 @@ function M.goto_mark(next) local filename = buffer.filename or buffer._type or _L['Untitled'] if buffer.filename then filename = filename:iconv('UTF-8', _CHARSET) end local basename = buffer.filename and filename:match('[^/\\]+$') or filename - local line = buffer:marker_next(1, BOOKMARK_BIT) - while line >= 1 do + for line in bookmarks() do utf8_list[#utf8_list + 1] = string.format( '%s:%d: %s', basename, line, buffer:get_line(line):match('^[^\r\n]*')) buffers[#buffers + 1] = buffer - line = buffer:marker_next(line + 1, BOOKMARK_BIT) end ::continue:: end @@ -75,4 +81,14 @@ function M.goto_mark(next) textadept.editing.goto_line(tonumber(utf8_list[i]:match('^[^:]+:(%d+):'))) end +local lines = {} +-- Save and restore bookmarks on buffer:reload(). +events.connect(events.FILE_BEFORE_RELOAD, function() + for line in bookmarks() do lines[#lines + 1] = line end +end) +events.connect(events.FILE_AFTER_RELOAD, function() + for _, line in ipairs(lines) do buffer:marker_add(line, M.MARK_BOOKMARK) end + lines = {} -- clear +end) + return M diff --git a/test/modules/textadept/bookmarks/foo b/test/modules/textadept/bookmarks/foo new file mode 100644 index 00000000..94ebaf90 --- /dev/null +++ b/test/modules/textadept/bookmarks/foo @@ -0,0 +1,4 @@ +1 +2 +3 +4 diff --git a/test/test.lua b/test/test.lua index 321df0bc..f3715a16 100644 --- a/test/test.lua +++ b/test/test.lua @@ -1153,6 +1153,25 @@ function test_bookmarks_interactive() buffer:close(true) end +function test_bookmarks_reload() + local function has_bookmark(line) + return buffer:marker_get(line) & 1 << textadept.bookmarks.MARK_BOOKMARK - 1 > 0 + end + + io.open_file(_HOME .. '/test/modules/textadept/bookmarks/foo') + buffer:line_down() + textadept.bookmarks.toggle() + buffer:line_down() + buffer:line_down() + textadept.bookmarks.toggle() + assert(has_bookmark(2), 'line not bookmarked') + assert(has_bookmark(4), 'line not bookmarked') + buffer:reload() + assert(has_bookmark(2), 'bookmark not restored') + assert(has_bookmark(4), 'bookmark not restored') + buffer:close(true) +end + function test_command_entry_run() local command_run, tab_pressed = false, false ui.command_entry.run(function(command) command_run = command end, { |