1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
-- Copyright 2007 Mitchell mitchell<att>caladbolg.net. See LICENSE.
local find = textadept.find
---
-- [Local table] Text escape sequences with their associated characters.
-- @class table
-- @name escapes
local escapes = {
['\\a'] = '\a', ['\\b'] = '\b', ['\\f'] = '\f', ['\\n'] = '\n',
['\\r'] = '\r', ['\\t'] = '\t', ['\\v'] = '\v', ['\\\\'] = '\\'
}
---
-- Finds and selects text in the current buffer.
-- This is used by the find dialog. It is recommended to use the buffer:find()
-- function for scripting.
-- @param text The text to find.
-- @param flags Search flags. This is a number mask of 3 flags: match case (2),
-- whole word (4), and Lua pattern (8) joined with binary AND.
-- @param next Flag indicating whether or not the search direction is forward.
-- @param nowrap Flag indicating whether or not the search won't wrap.
-- @param wrapped Utility flag indicating whether or not the search has wrapped
-- for displaying useful statusbar information. This flag is used and set
-- internally, and should not be set otherwise.
function find.find(text, flags, next, nowrap, wrapped)
local buffer = buffer
local increment, result
text = text:gsub('\\[abfnrtv\\]', escapes)
find.captures = nil
if buffer.current_pos == buffer.anchor then
increment = 0
elseif not wrapped then
increment = next and 1 or -1
end
if flags < 8 then
if next then
buffer:goto_pos(buffer.current_pos + increment)
buffer:search_anchor()
result = buffer:search_next(flags, text)
else
buffer:goto_pos(buffer.anchor - increment)
buffer:search_anchor()
result = buffer:search_prev(flags, text)
end
if result then buffer:scroll_caret() end
else -- lua pattern search
local buffer_text = buffer:get_text(buffer.length)
local results = { buffer_text:find(text, buffer.anchor + increment) }
if #results > 0 then
result = results[1]
find.captures = { unpack(results, 3) }
buffer:set_sel(results[2], result - 1)
else
result = -1
end
end
if result == -1 and not nowrap and not wrapped then -- wrap the search
local anchor, pos = buffer.anchor, buffer.current_pos
if next or flags >= 8 then
buffer:goto_pos(0)
else
buffer:goto_pos(buffer.length)
end
textadept.statusbar_text = 'Search wrapped'
result = find.find(text, flags, next, true, true)
if not result then
textadept.statusbar_text = 'No results found'
buffer:goto_pos(anchor)
end
return result
elseif result ~= -1 and not wrapped then
textadept.statusbar_text = ''
end
return result ~= -1
end
---
-- Replaces found text.
-- This function is used by the find dialog. It is not recommended to call it
-- via scripts.
-- textadept.find.find is called first, to select any found text. The selected
-- text is then replaced by the specified replacement text.
-- @param rtext The text to replace found text with. It can contain Lua escape
-- sequences to use text captured by a Lua pattern. (%n where 1 <= n <= 9.)
function find.replace(rtext)
if #buffer:get_sel_text() == 0 then return end
local buffer = buffer
buffer:target_from_selection()
if find.captures then
for i, v in ipairs(find.captures) do
rtext = rtext:gsub('[^%%]?[^%%]?%%'..i, v) -- not entirely correct
end
end
buffer:replace_target( rtext:gsub('\\[abfnrtv\\]', escapes) )
end
---
-- Replaces all found text.
-- This function is used by the find dialog. It is not recommended to call it
-- via scripts.
-- @param ftext The text to find.
-- @param rtext The text to replace found text with.
-- @param flags The number mask identical to the one in 'find'.
-- @see find.find
function find.replace_all(ftext, rtext, flags)
buffer:goto_pos(0)
local count = 0
while( find.find(ftext, flags, true, true) ) do
find.replace(rtext)
count = count + 1
end
textadept.statusbar_text = tostring(count)..' replacement(s) made'
end
|