Mercurial Hosting > editor
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 |
