diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/textadept/command_entry.lua | 3 | ||||
-rw-r--r-- | modules/textadept/find.lua | 96 | ||||
-rw-r--r-- | modules/textadept/keys.lua | 8 | ||||
-rw-r--r-- | modules/textadept/macros.lua | 2 | ||||
-rw-r--r-- | modules/textadept/menu.lua | 9 |
5 files changed, 35 insertions, 83 deletions
diff --git a/modules/textadept/command_entry.lua b/modules/textadept/command_entry.lua index eda71b94..b1227c27 100644 --- a/modules/textadept/command_entry.lua +++ b/modules/textadept/command_entry.lua @@ -7,8 +7,7 @@ local M = ui.command_entry --- -- Textadept's Command Entry. -- It supports multiple modes that each have their own functionality (such as --- running Lua code, searching for text incrementally, and filtering text --- through shell commands) and history. +-- running Lua code and filtering text through shell commands) and history. -- @field height (number) -- The height in pixels of the command entry. module('ui.command_entry')]] diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua index 75de0dee..f221f642 100644 --- a/modules/textadept/find.lua +++ b/modules/textadept/find.lua @@ -22,6 +22,9 @@ local M = ui.find -- @field in_files (bool) -- Find search text in a list of files. -- The default value is `false`. +-- @field incremental (bool) +-- Find search text incrementally as it is typed. +-- The default value is `false`. -- @field find_label_text (string, Write-only) -- The text of the "Find" label. -- This is primarily used for localization. @@ -97,7 +100,9 @@ M.find_in_files_filters = {} -- Keep track of find text and found text so that "replace all" works as -- expected during a find session ("replace all" with selected text normally --- does "replace in selection"). +-- does "replace in selection"). Also track find text for incremental find (if +-- text has changed, the user is still typing; if text is the same, the user +-- clicked "Find Next" or "Find Prev"). local find_text, found_text -- Returns a bit-mask of search flags to use in Scintilla search functions based @@ -142,6 +147,18 @@ local function find(text, next, flags, no_wrap, wrapped) if flags >= 1 << 31 then M.find_in_files() return end -- not performed here local first_visible_line = view.first_visible_line -- for 'no results found' + if M.incremental and not wrapped then + if type(M.incremental) == 'boolean' then + -- Starting a new incremental search, anchor at current pos. + M.incremental = buffer.current_pos + elseif text == find_text then + -- "Find Next" or "Find Prev" clicked, anchor at new current pos. + M.incremental = buffer:position_relative( + buffer.current_pos, next and 1 or -1) + end + buffer:goto_pos(M.incremental or 1) + end + -- If text is selected, assume it is from the current search and move the -- caret appropriately for the next search. buffer:goto_pos(next and buffer.selection_end or buffer.selection_start) @@ -152,7 +169,8 @@ local function find(text, next, flags, no_wrap, wrapped) local pos = f(buffer, flags, text) view:ensure_visible_enforce_policy(buffer:line_from_position(pos)) view:scroll_range(buffer.anchor, buffer.current_pos) - find_text, found_text = text, buffer:get_sel_text() -- track for "replace all" + -- Track find text and found text for "replace all" and incremental find. + find_text, found_text = text, buffer:get_sel_text() -- If nothing was found, wrap the search. if pos == -1 and not no_wrap then @@ -190,78 +208,14 @@ local function find(text, next, flags, no_wrap, wrapped) return pos end events.connect(events.FIND, find) +events.connect(events.FIND_TEXT_CHANGED, function() + if not M.incremental then return end + events.emit(events.FIND, M.find_entry_text, true) + return true -- redraw in CURSES +end) events.connect( events.FIND_WRAPPED, function() ui.statusbar_text = _L['Search wrapped'] end) -local incremental_start - --- Finds and selects text incrementally in the current buffer from a starting --- position. --- Flags other than `FIND_MATCHCASE` are ignored. --- @param text The text to find. --- @param next Flag indicating whether or not the search direction is forward. --- @param anchor Flag indicating whether or not to search from the current --- position. -local function find_incremental(text, next, anchor) - local orig_pos = buffer.current_pos - if anchor then - incremental_start = buffer:position_relative(orig_pos, next and 1 or -1) - end - buffer:goto_pos(incremental_start or 1) - -- Note: even though `events.FIND` does not support a flags parameter, the - -- default handler has one, so make use of it. - events.emit( - events.FIND, text, next, M.match_case and buffer.FIND_MATCHCASE or 0) - if buffer.selection_empty and anchor then buffer:goto_pos(orig_pos) end -end - ---- --- Begins an incremental search using the command entry if *text* is `nil`. --- Otherwise, continues an incremental search by searching for the next or --- previous instance of string *text*, depending on boolean *next*. --- *anchor* indicates whether or not to search for *text* starting from the --- caret position instead of the position where the incremental search began. --- Only the `match_case` find option is recognized. Normal command entry --- functionality is unavailable until the search is finished or by pressing --- `Esc`. --- @param text The text to incrementally search for, or `nil` to begin an --- incremental search. --- @param next Flag indicating whether or not the search direction is forward. --- Only applicable when *text* is not `nil`. --- @param anchor Optional flag indicating whether or not to start searching from --- the caret position. The default value is `false`. --- @name find_incremental -function M.find_incremental(text, next, anchor) - assert_type(text, 'string/nil', 1) - if text then find_incremental(text, next, anchor) return end - incremental_start = buffer.current_pos - ui.command_entry:set_text('') - ui.command_entry.run(nil, M.find_incremental_keys) -end - ---- --- Table of key bindings used when searching for text incrementally. --- @class table --- @name find_incremental_keys -M.find_incremental_keys = setmetatable({ - ['\n'] = function() - M.find_entry_text = ui.command_entry:get_text() -- save - M.find_incremental(ui.command_entry:get_text(), true, true) - end, - ['\b'] = function() - local e = ui.command_entry:position_before(ui.command_entry.length + 1) - M.find_incremental(ui.command_entry:text_range(1, e), true) - return false -- propagate - end -}, {__index = function(_, k) - -- Add the character for any key pressed without modifiers to incremental - -- find. - if #k == 1 or not k:find('ctrl%+') and not k:find('alt%+') and - not k:find('meta%+') and not k:find('shift%+') then - M.find_incremental(ui.command_entry:get_text() .. k, true) - end -end}) - --- -- Searches directory *dir* or the user-specified directory for files that match -- search text and search options (subject to optional filter *filter*), and diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua index 90cb2000..e105d57b 100644 --- a/modules/textadept/keys.lua +++ b/modules/textadept/keys.lua @@ -349,7 +349,8 @@ local bindings = { -- Find Prev is ap when find pane is focused in GUI. -- Replace is ar when find pane is focused in GUI. -- Replace All is aa when find pane is focused in GUI. - [ui.find.find_incremental] = {'ctrl+alt+f', 'ctrl+cmd+f', 'ctrl+meta+f'}, + [m_search[_L['Find Incremental']][2]] = + {'ctrl+alt+f', 'ctrl+cmd+f', 'ctrl+meta+f'}, [m_search[_L['Find in Files']][2]] = {'ctrl+F', 'cmd+F', nil}, -- Find in Files is ai when find pane is focused in GUI. [m_search[_L['Goto Next File Found']][2]] = {'ctrl+alt+g', 'ctrl+cmd+g', nil}, @@ -529,9 +530,4 @@ end -- not propagate it. if OSX then keys.fn = function() return true end end --- Reverse incremental find. -ui.find.find_incremental_keys['ctrl+r'] = function() - ui.find.find_incremental(ui.command_entry:get_text(), false, true) -end - return M diff --git a/modules/textadept/macros.lua b/modules/textadept/macros.lua index a3636e6f..ff802475 100644 --- a/modules/textadept/macros.lua +++ b/modules/textadept/macros.lua @@ -18,7 +18,7 @@ events.connect(events.INITIALIZED, function() local m_tools = textadept.menu.menubar[_L['Tools']] ignore = { textadept.menu.menubar[_L['Search']][_L['Find']][2], - ui.find.find_incremental, + textadept.menu.menubar[_L['Search']][_L['Find Incremental']][2], m_tools[_L['Select Command']][2], m_tools[_L['Macros']][_L['Start/Stop Recording']][2] } diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua index 98f0f1cc..14efd40f 100644 --- a/modules/textadept/menu.lua +++ b/modules/textadept/menu.lua @@ -139,17 +139,20 @@ local default_menubar = { { title = _L['Search'], {_L['Find'], function() - ui.find.in_files = false + ui.find.in_files, ui.find.incremental = false, false ui.find.focus() end}, {_L['Find Next'], ui.find.find_next}, {_L['Find Previous'], ui.find.find_prev}, {_L['Replace'], ui.find.replace}, {_L['Replace All'], ui.find.replace_all}, - {_L['Find Incremental'], ui.find.find_incremental}, + {_L['Find Incremental'], function() + ui.find.in_files, ui.find.incremental = false, true + ui.find.focus() + end}, SEPARATOR, {_L['Find in Files'], function() - ui.find.in_files = true + ui.find.in_files, ui.find.incremental = true, false ui.find.focus() end}, {_L['Goto Next File Found'], function() ui.find.goto_file_found(true) end}, |