aboutsummaryrefslogtreecommitdiff
path: root/modules/textadept/find.lua
diff options
context:
space:
mode:
Diffstat (limited to 'modules/textadept/find.lua')
-rw-r--r--modules/textadept/find.lua95
1 files changed, 45 insertions, 50 deletions
diff --git a/modules/textadept/find.lua b/modules/textadept/find.lua
index 48601ee3..1b7a98c5 100644
--- a/modules/textadept/find.lua
+++ b/modules/textadept/find.lua
@@ -106,9 +106,8 @@ local find_text, found_text
-- @return search flag bit-mask
local function get_flags()
return (M.match_case and buffer.FIND_MATCHCASE or 0) +
- (M.whole_word and buffer.FIND_WHOLEWORD or 0) +
- (M.regex and buffer.FIND_REGEXP or 0) +
- (M.in_files and 0x1000000 or 0) -- next after 0x800000
+ (M.whole_word and buffer.FIND_WHOLEWORD or 0) +
+ (M.regex and buffer.FIND_REGEXP or 0) + (M.in_files and 1 << 31 or 0)
end
-- Finds and selects text in the current buffer.
@@ -116,7 +115,7 @@ end
-- @param next Flag indicating whether or not the search direction is forward.
-- @param flags Search flags. This is a bit-mask of 4 flags:
-- `buffer.FIND_MATCHCASE`, `buffer.FIND_WHOLEWORD`, `buffer.FIND_REGEXP`, and
--- 0x1000000 (in files), each joined with binary OR.
+-- 1 << 31 (in files), each joined with binary OR.
-- If `nil`, this is determined based on the checkboxes in the find box.
-- @param no_wrap Flag indicating whether or not the search will not wrap.
-- @param wrapped Utility flag indicating whether or not the search has wrapped
@@ -127,16 +126,16 @@ local function find(text, next, flags, no_wrap, wrapped)
-- Note: cannot use assert_type(), as event errors are handled silently.
if text == '' then return end
if not flags then flags = get_flags() end
- if flags >= 0x1000000 then M.find_in_files() return end -- not performed here
+ if flags >= 1 << 31 then M.find_in_files() return end -- not performed here
local first_visible_line = buffer.first_visible_line -- for 'no results found'
-- If text is selected, assume it is from the current search and move the
-- caret appropriately for the next search.
- buffer:goto_pos(buffer[next and 'selection_end' or 'selection_start'])
+ buffer:goto_pos(next and buffer.selection_end or buffer.selection_start)
-- Scintilla search.
buffer:search_anchor()
- local f = buffer['search_'..(next and 'next' or 'prev')]
+ local f = next and buffer.search_next or buffer.search_prev
local pos = f(buffer, flags, text)
buffer:ensure_visible_enforce_policy(buffer:line_from_position(pos))
buffer:scroll_range(buffer.anchor, buffer.current_pos)
@@ -160,8 +159,8 @@ local function find(text, next, flags, no_wrap, wrapped)
return pos
end
events.connect(events.FIND, find)
-events.connect(events.FIND_WRAPPED,
- function() ui.statusbar_text = _L['Search wrapped'] end)
+events.connect(
+ events.FIND_WRAPPED, function() ui.statusbar_text = _L['Search wrapped'] end)
local incremental_start
@@ -175,14 +174,13 @@ local incremental_start
local function find_incremental(text, next, anchor)
local orig_pos = buffer.current_pos
if anchor then
- incremental_start = buffer:position_relative(buffer.current_pos,
- next and 1 or -1)
+ incremental_start = buffer:position_relative(orig_pos, next and 1 or -1)
end
buffer:goto_pos(incremental_start or 0)
-- 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)
+ 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
@@ -198,6 +196,7 @@ end
-- @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
@@ -227,7 +226,7 @@ M.find_incremental_keys = setmetatable({
-- Add the character for any key pressed without modifiers to incremental
-- find.
if #k > 1 and k:find('^[cams]*.+$') then return end
- M.find_incremental(ui.command_entry:get_text()..k, true)
+ M.find_incremental(ui.command_entry:get_text() .. k, true)
end})
---
@@ -257,16 +256,16 @@ function M.find_in_files(dir, filter)
dir = ui.dialogs.fileselect{
title = _L['Select Directory'], select_only_directories = true,
with_directory = io.get_project_root() or
- (buffer.filename or ''):match('^.+[/\\]') or
- lfs.currentdir()
+ (buffer.filename or ''):match('^.+[/\\]') or lfs.currentdir()
}
if not dir then return end
end
if buffer._type ~= _L['[Files Found Buffer]'] then preferred_view = view end
ui.silent_print = false
- ui._print(_L['[Files Found Buffer]'],
- _L['Find:']:gsub('_', '')..' '..M.find_entry_text)
+ ui._print(
+ _L['[Files Found Buffer]'],
+ string.format('%s %s', _L['Find:']:gsub('_', ''), M.find_entry_text))
buffer.indicator_current = M.INDIC_FIND
local ff_buffer = buffer
@@ -278,8 +277,7 @@ function M.find_in_files(dir, filter)
buffer:clear_all()
buffer:empty_undo_buffer()
local f = io.open(filename, 'rb')
- while f:read(0) do buffer:append_text(f:read(1048576)) end -- TODO: why?
- --buffer:set_text(f:read('a')) -- TODO: why not?
+ buffer:set_text(f:read('a'))
f:close()
local binary = nil -- determine lazily for performance reasons
buffer:target_whole_document()
@@ -290,28 +288,28 @@ function M.find_in_files(dir, filter)
if not binary then
local line_num = buffer:line_from_position(buffer.target_start)
local line = buffer:get_line(line_num)
- ff_buffer:append_text(string.format('%s:%d:%s', utf8_filename,
- line_num + 1, line))
+ ff_buffer:append_text(
+ string.format('%s:%d:%s', utf8_filename, line_num + 1, line))
local pos = ff_buffer.length - #line +
- buffer.target_start - buffer:position_from_line(line_num)
- ff_buffer:indicator_fill_range(pos,
- buffer.target_end - buffer.target_start)
+ buffer.target_start - buffer:position_from_line(line_num)
+ ff_buffer:indicator_fill_range(
+ pos, buffer.target_end - buffer.target_start)
if not line:find('\n$') then ff_buffer:append_text('\n') end
else
- ff_buffer:append_text(string.format('%s:1:%s\n', utf8_filename,
- _L['Binary file matches.']))
+ ff_buffer:append_text(
+ string.format('%s:1:%s\n', utf8_filename, _L['Binary file matches.']))
break
end
buffer:set_target_range(buffer.target_end, buffer.length)
end
if os.difftime(os.time(), ref_time) >= M.find_in_files_timeout then
- local continue = ui.dialogs.yesno_msgbox{
+ local button = ui.dialogs.yesno_msgbox{
title = _L['Continue?'],
text = _L['Still searching in files... Continue waiting?'],
icon = 'gtk-dialog-question', no_cancel = true
- } == 1
- if not continue then
- ff_buffer:append_text(_L['Find in Files aborted']..'\n')
+ }
+ if button ~= 1 then
+ ff_buffer:append_text(_L['Find in Files aborted'] .. '\n')
return false
end
ref_time = os.time()
@@ -329,16 +327,16 @@ end
-- @return unescaped text
local function unescape(text)
return M.regex and text:gsub('%f[\\]\\u(%x%x%x%x)', function(code)
- return utf8.char(tonumber(code, 16))
- end) or text
+ return utf8.char(tonumber(code, 16))
+ end) or text
end
-- Replaces found (selected) text.
events.connect(events.REPLACE, function(rtext)
if buffer.selection_empty then return end
- rtext = unescape(rtext)
buffer:target_from_selection()
- buffer[not M.regex and 'replace_target' or 'replace_target_re'](buffer, rtext)
+ local f = not M.regex and buffer.replace_target or buffer.replace_target_re
+ f(buffer, unescape(rtext))
buffer:set_sel(buffer.target_start, buffer.target_end)
end)
@@ -349,17 +347,15 @@ local INDIC_REPLACE = _SCINTILLA.next_indic_number()
events.connect(events.REPLACE_ALL, function(ftext, rtext)
if ftext == '' then return end
local count = 0
- local buffer = buffer
local s, e = buffer.selection_start, buffer.selection_end
- local replace_in_sel = s ~= e and (ftext ~= find_text or
- buffer:get_sel_text() ~= found_text)
+ local replace_in_sel =
+ s ~= e and (ftext ~= find_text or buffer:get_sel_text() ~= found_text)
if replace_in_sel then
buffer.indicator_current = INDIC_REPLACE
buffer:indicator_fill_range(e, 1)
end
local EOF = replace_in_sel and e == buffer.length -- no indicator at EOF
- local buffer_replace_target = buffer[not M.regex and 'replace_target' or
- 'replace_target_re']
+ local f = not M.regex and buffer.replace_target or buffer.replace_target_re
rtext = unescape(rtext)
-- Perform the search and replace.
@@ -369,7 +365,7 @@ events.connect(events.REPLACE_ALL, function(ftext, rtext)
while buffer:search_in_target(ftext) ~= -1 and (not replace_in_sel or
buffer.target_end <= buffer:indicator_end(INDIC_REPLACE, s) or EOF) do
if buffer.target_start == buffer.target_end then break end -- prevent loops
- buffer_replace_target(buffer, rtext)
+ f(buffer, rtext)
count = count + 1
buffer:set_target_range(buffer.target_end, buffer.length)
end
@@ -379,7 +375,7 @@ events.connect(events.REPLACE_ALL, function(ftext, rtext)
if replace_in_sel then
e = buffer:indicator_end(INDIC_REPLACE, s)
buffer:set_sel(s, e > 0 and e or buffer.length)
- buffer:indicator_clear_range(e, 1)
+ if e > 0 then buffer:indicator_clear_range(e, 1) end
end
ui.statusbar_text = string.format('%d %s', count, _L['replacement(s) made'])
end)
@@ -406,11 +402,11 @@ function M.goto_file_found(line_num, next)
if not ff_view and not ff_buf then return end
if ff_view then ui.goto_view(ff_view) else view:goto_buffer(ff_buf) end
- -- If no line was given, find the next search result.
+ -- If no line was given, find the next search result, wrapping as necessary.
if not assert_type(line_num, 'number/nil', 1) and next ~= nil then
if next then buffer:line_end() else buffer:home() end
buffer:search_anchor()
- local f = buffer['search_'..(next and 'next' or 'prev')]
+ local f = next and buffer.search_next or buffer.search_prev
local pos = f(buffer, buffer.FIND_REGEXP, '^.+:\\d+:.+$')
if pos == -1 then
buffer:goto_line(next and 0 or buffer.line_count)
@@ -425,10 +421,10 @@ function M.goto_file_found(line_num, next)
-- Goto the source of the search result.
local line = buffer:get_cur_line()
local utf8_filename, pos
- utf8_filename, line_num, pos = line:match('^(.+):(%d+):().+$')
+ utf8_filename, line_num, pos = line:match('^(.+):(%d+):()')
if not utf8_filename then return end
textadept.editing.select_line()
- pos = buffer.anchor + pos - 1 -- absolute position of result text on line
+ pos = buffer.selection_start + pos - 1 -- absolute pos of result text on line
local s = buffer:indicator_end(M.INDIC_FIND, pos - 1)
local e = buffer:indicator_end(M.INDIC_FIND, s + 1)
if buffer:line_from_position(s) == buffer:line_from_position(pos) then
@@ -443,10 +439,9 @@ function M.goto_file_found(line_num, next)
end
end
events.connect(events.KEYPRESS, function(code)
- if keys.KEYSYMS[code] == '\n' and is_ff_buf(buffer) then
- M.goto_file_found(buffer:line_from_position(buffer.current_pos))
- return true
- end
+ if keys.KEYSYMS[code] ~= '\n' or not is_ff_buf(buffer) then return end
+ M.goto_file_found(buffer:line_from_position(buffer.current_pos))
+ return true
end)
events.connect(events.DOUBLE_CLICK, function(_, line)
if is_ff_buf(buffer) then M.goto_file_found(line) end