Mercurial Hosting > editor
comparison editor.luan @ 33:e19ac0784287
find regex
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 14 Apr 2025 12:48:05 -0600 |
parents | 15dacd8f5bfc |
children | 8535209b61ff |
comparison
equal
deleted
inserted
replaced
32:15dacd8f5bfc | 33:e19ac0784287 |
---|---|
7 local sub_string = String.sub or error() | 7 local sub_string = String.sub or error() |
8 local replace = String.replace or error() | 8 local replace = String.replace or error() |
9 local starts_with = String.starts_with or error() | 9 local starts_with = String.starts_with or error() |
10 local to_number = String.to_number or error() | 10 local to_number = String.to_number or error() |
11 local find = String.find or error() | 11 local find = String.find or error() |
12 local regex = String.regex or error() | |
13 local regex_quote = String.regex_quote or error() | |
12 local Io = require "luan:Io.luan" | 14 local Io = require "luan:Io.luan" |
13 local print = Io.print or error() | 15 local print = Io.print or error() |
14 local new_file = Io.schemes.file or error() | 16 local new_file = Io.schemes.file or error() |
15 local Math = require "luan:Math.luan" | 17 local Math = require "luan:Math.luan" |
16 local min = Math.min or error() | 18 local min = Math.min or error() |
76 end | 78 end |
77 window.update_undo_redo = update_undo_redo -- dont gc | 79 window.update_undo_redo = update_undo_redo -- dont gc |
78 update_undo_redo() | 80 update_undo_redo() |
79 document.add_undo_listener(update_undo_redo) | 81 document.add_undo_listener(update_undo_redo) |
80 | 82 |
83 local find_menu_item = new_check_box_menu_item{ | |
84 text = "Find and Replace" | |
85 accelerator = "meta F" | |
86 action_listener = function(event) | |
87 window.show_find_panel(event.source.state) | |
88 end | |
89 } | |
90 window.find_menu_item = find_menu_item | |
91 | |
81 local menu_bar = new_menu_bar{ | 92 local menu_bar = new_menu_bar{ |
82 menus = { | 93 menus = { |
83 new_menu{ | 94 new_menu{ |
84 text = "File" | 95 text = "File" |
85 menu_items = { | 96 menu_items = { |
148 } | 159 } |
149 } | 160 } |
150 new_menu{ | 161 new_menu{ |
151 text = "Find" | 162 text = "Find" |
152 menu_items = { | 163 menu_items = { |
153 new_check_box_menu_item{ | 164 find_menu_item |
154 text = "Find and Replace" | |
155 accelerator = "meta F" | |
156 action_listener = function(event) | |
157 window.show_find_panel(event.source.state) | |
158 end | |
159 } | |
160 new_menu_item{ | 165 new_menu_item{ |
161 text = "Find Case Insensitive" | 166 text = "Find Case Insensitive" |
167 action_listener = window.find_case_insensitive | |
162 } | 168 } |
163 new_menu_item{ | 169 new_menu_item{ |
164 text = "Convert Leading Tabs to Spaces" | 170 text = "Convert Leading Tabs to Spaces" |
165 } | 171 } |
166 new_menu_item{ | 172 new_menu_item{ |
207 } | 213 } |
208 window.frame.set_menu_bar(menu_bar) | 214 window.frame.set_menu_bar(menu_bar) |
209 end | 215 end |
210 | 216 |
211 local function get_matches(text,s) | 217 local function get_matches(text,s) |
212 local n = #s | 218 local r = regex(s) |
213 if n == 0 then | |
214 return nil | |
215 end | |
216 local matches = {} | 219 local matches = {} |
217 local i = 0 | 220 local i = 0 |
218 while(true) do | 221 while(true) do |
219 local j = find(text,s,i) | 222 local j1, j2 = r.find(text,i) |
220 if j == nil then | 223 if j1 == nil then |
221 break | 224 break |
222 end | 225 end |
223 matches[#matches+1] = { start=j, end_=j+n } | 226 matches[#matches+1] = { start=j1, end_=j2 } |
224 i = j + n | 227 i = j2 |
225 end | 228 end |
226 return matches | 229 return matches |
227 end | 230 end |
228 | 231 |
229 local function make_find_panel(window) | 232 local function make_find_panel(window) |
230 local text_area = window.text_area | 233 local text_area = window.text_area |
231 local find_field, output | 234 local find_field, regex_check_box, output |
232 local function find_match(event) | 235 local function find_match(event) |
233 --logger.info("action "..event.action) | 236 --logger.info("action "..event.action) |
234 local s = find_field.text | 237 local s = find_field.text |
235 local matches = get_matches( text_area.text, s ) | 238 if #s == 0 then |
236 if matches == nil then | |
237 output.text = "" | 239 output.text = "" |
240 return | |
241 end | |
242 if not regex_check_box.is_selected then | |
243 s = regex_quote(s) | |
244 end | |
245 local matches | |
246 try | |
247 matches = get_matches( text_area.text, s ) | |
248 catch e | |
249 output.text = "Regex error: "..e.get_message() | |
238 return | 250 return |
239 end | 251 end |
240 local n_matches = #matches | 252 local n_matches = #matches |
241 if n_matches == 0 then | 253 if n_matches == 0 then |
242 output.text = "0 matches" | 254 output.text = "0 matches" |
276 constraints = "growx" | 288 constraints = "growx" |
277 show_whitespace = true | 289 show_whitespace = true |
278 action = "next" | 290 action = "next" |
279 action_listener = find_match | 291 action_listener = find_match |
280 } | 292 } |
293 regex_check_box = new_check_box{ | |
294 text = "Use Regex" | |
295 } | |
281 output = new_label{ | 296 output = new_label{ |
282 constraints = "span" | 297 constraints = "span" |
283 } | 298 } |
284 local find_panel = new_panel{ | 299 local find_panel = new_panel{ |
285 constraints = "growy 0,growx" | 300 constraints = "growy 0,growx" |
321 } | 336 } |
322 new_panel{ | 337 new_panel{ |
323 constraints = "span,wrap" | 338 constraints = "span,wrap" |
324 layout = new_mig_layout("insets 0,gap 16px") | 339 layout = new_mig_layout("insets 0,gap 16px") |
325 children = { | 340 children = { |
326 new_check_box{ | 341 regex_check_box |
327 text = "Use Regex" | |
328 } | |
329 new_button{ | 342 new_button{ |
330 text = "Learn About Regular Expressions" | 343 text = "Learn About Regular Expressions" |
331 } | 344 } |
332 } | 345 } |
333 } | 346 } |
337 function window.show_find_panel(visible) | 350 function window.show_find_panel(visible) |
338 find_panel.visible = visible | 351 find_panel.visible = visible |
339 if visible then | 352 if visible then |
340 find_field.request_focus_in_window() | 353 find_field.request_focus_in_window() |
341 end | 354 end |
355 end | |
356 function window.find_case_insensitive(_) | |
357 find_panel.visible = true | |
358 window.find_menu_item.is_selected = true | |
359 regex_check_box.is_selected = true | |
360 find_field.text = "(?i)\Q\E" | |
361 find_field.set_selection(7) | |
362 find_field.request_focus_in_window() | |
342 end | 363 end |
343 return find_panel | 364 return find_panel |
344 end | 365 end |
345 | 366 |
346 local n_windows = 0 | 367 local n_windows = 0 |