comparison editor.luan @ 36:0a8865de3d53

replace all
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 14 Apr 2025 21:17:04 -0600
parents c5b57654147b
children
comparison
equal deleted inserted replaced
35:c5b57654147b 36:0a8865de3d53
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() 12 local regex = String.regex or error()
13 local regex_quote = String.regex_quote or error() 13 local regex_quote = String.regex_quote or error()
14 local regex_quote_replacement = String.regex_quote_replacement or error() 14 local regex_quote_replacement = String.regex_quote_replacement or error()
15 local repeated = String.repeated or error()
15 local Io = require "luan:Io.luan" 16 local Io = require "luan:Io.luan"
16 local print = Io.print or error() 17 local print = Io.print or error()
17 local new_file = Io.schemes.file or error() 18 local new_file = Io.schemes.file or error()
18 local Math = require "luan:Math.luan" 19 local Math = require "luan:Math.luan"
19 local min = Math.min or error() 20 local min = Math.min or error()
167 text = "Find Case Insensitive" 168 text = "Find Case Insensitive"
168 action_listener = window.find_case_insensitive 169 action_listener = window.find_case_insensitive
169 } 170 }
170 new_menu_item{ 171 new_menu_item{
171 text = "Convert Leading Tabs to Spaces" 172 text = "Convert Leading Tabs to Spaces"
173 action_listener = window.tabs_to_spaces
172 } 174 }
173 new_menu_item{ 175 new_menu_item{
174 text = "Convert Leading Spaces to Tabs" 176 text = "Convert Leading Spaces to Tabs"
177 action_listener = window.spaces_to_tabs
175 } 178 }
176 } 179 }
177 } 180 }
178 new_menu{ 181 new_menu{
179 text = "View" 182 text = "View"
216 end 219 end
217 220
218 local function get_matches(text,s) 221 local function get_matches(text,s)
219 local r = regex(s) 222 local r = regex(s)
220 local matches = {} 223 local matches = {}
221 local i = 0 224 local i = 1
222 while(true) do 225 local n = #text
226 while i <= n do
223 local j1, j2 = r.find(text,i) 227 local j1, j2 = r.find(text,i)
224 if j1 == nil then 228 if j1 == nil then
225 break 229 break
226 end 230 end
227 j2 = j2 + 1 231 j2 = j2 + 1
228 matches[#matches+1] = { start=j1, end_=j2 } 232 if j1 == j2 then
229 i = j2 233 i = j2 + 1
234 else
235 matches[#matches+1] = { start=j1, end_=j2 }
236 i = j2
237 end
230 end 238 end
231 return matches 239 return matches
232 end 240 end
233 241
234 local function make_find_panel(window) 242 local function make_find_panel(window)
284 output.text = n_matches.." of "..n_matches.." matches; wrapped past end" 292 output.text = n_matches.." of "..n_matches.." matches; wrapped past end"
285 else 293 else
286 error(action) 294 error(action)
287 end 295 end
288 end 296 end
289 local function replace_match(_) 297 local function replace_match(event)
290 local find = find_field.text 298 local find = find_field.text
291 if #find == 0 then 299 if #find == 0 then
292 output.text = "" 300 output.text = ""
293 return 301 return
294 end 302 end
302 r = regex(find) 310 r = regex(find)
303 catch e 311 catch e
304 output.text = "Regex error: "..e.get_message() 312 output.text = "Regex error: "..e.get_message()
305 return 313 return
306 end 314 end
307 local selection = text_area.selected_text 315 local new, n
308 local new, n = r.gsub(selection,replace) 316 local action = event.action
309 if n > 0 then 317 if action == "replace" then
310 text_area.selected_text = new 318 local selection = text_area.selected_text
319 new, n = r.gsub(selection,replace)
320 if n > 0 then
321 text_area.selected_text = new
322 end
323 elseif action == "replace_all" then
324 local text = text_area.text
325 new, n = r.gsub(text,replace)
326 if n > 0 then
327 text_area.text = new
328 end
329 else
330 error(action)
311 end 331 end
312 output.text = n.." replacements" 332 output.text = n.." replacements"
313 end 333 end
314 find_field = new_text_field{ 334 find_field = new_text_field{
315 constraints = "growx" 335 constraints = "growx"
318 action_listener = find_match 338 action_listener = find_match
319 } 339 }
320 replace_field = new_text_field{ 340 replace_field = new_text_field{
321 constraints = "growx" 341 constraints = "growx"
322 show_whitespace = true 342 show_whitespace = true
343 action = "replace"
323 action_listener = replace_match 344 action_listener = replace_match
324 } 345 }
325 regex_check_box = new_check_box{ 346 regex_check_box = new_check_box{
326 text = "Use Regex" 347 text = "Use Regex"
327 } 348 }
357 replace_field 378 replace_field
358 new_button{ 379 new_button{
359 constraints = "grow" 380 constraints = "grow"
360 text = "Replace" 381 text = "Replace"
361 tool_tip_text = "Replace matches in selected text" 382 tool_tip_text = "Replace matches in selected text"
383 action = "replace"
362 action_listener = replace_match 384 action_listener = replace_match
363 } 385 }
364 new_button{ 386 new_button{
365 constraints = "grow,wrap" 387 constraints = "grow,wrap"
366 text = "Replace All" 388 text = "Replace All"
389 action = "replace_all"
390 action_listener = replace_match
367 } 391 }
368 new_panel{ 392 new_panel{
369 constraints = "span,wrap" 393 constraints = "span,wrap"
370 layout = new_mig_layout("insets 0,gap 16px") 394 layout = new_mig_layout("insets 0,gap 16px")
371 children = { 395 children = {
389 window.find_menu_item.is_selected = true 413 window.find_menu_item.is_selected = true
390 regex_check_box.is_selected = true 414 regex_check_box.is_selected = true
391 find_field.text = "(?i)\Q\E" 415 find_field.text = "(?i)\Q\E"
392 find_field.set_selection(7) 416 find_field.set_selection(7)
393 find_field.request_focus_in_window() 417 find_field.request_focus_in_window()
394 output.text = "" 418 output.text = [[Put search text between "\Q" and "\E"]]
419 end
420 function window.tabs_to_spaces(_)
421 find_panel.visible = true
422 window.find_menu_item.is_selected = true
423 regex_check_box.is_selected = true
424 find_field.text = [[(?m)^(\t*)\t]]
425 local spaces = repeated( " ", text_area.tab_size )
426 replace_field.text = "$1"..spaces
427 output.text = [[Do "Replace All" until 0 replacements]]
428 end
429 function window.spaces_to_tabs(_)
430 find_panel.visible = true
431 window.find_menu_item.is_selected = true
432 regex_check_box.is_selected = true
433 local tab_size = text_area.tab_size
434 find_field.text = `%>(?m)^(( {<%=tab_size%>})*) {<%=tab_size%>}<%`
435 replace_field.text = "$1\t"
436 output.text = [[Do "Replace All" until 0 replacements]]
395 end 437 end
396 return find_panel 438 return find_panel
397 end 439 end
398 440
399 local n_windows = 0 441 local n_windows = 0