Mercurial Hosting > editor
changeset 28:bdb8754f1211
find work
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Fri, 11 Apr 2025 21:41:26 -0600 |
parents | 32232df78246 |
children | 01b8a25b38aa |
files | editor.luan |
diffstat | 1 files changed, 89 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/editor.luan Fri Apr 11 11:43:41 2025 -0600 +++ b/editor.luan Fri Apr 11 21:41:26 2025 -0600 @@ -1,12 +1,14 @@ local Luan = require "luan:Luan.luan" local error = Luan.error local ipairs = Luan.ipairs or error() +local range = Luan.range or error() local stringify = Luan.stringify or error() local String = require "luan:String.luan" local sub_string = String.sub or error() local replace = String.replace or error() local starts_with = String.starts_with or error() local to_number = String.to_number or error() +local find = String.find or error() local Io = require "luan:Io.luan" local print = Io.print or error() local new_file = Io.schemes.file or error() @@ -177,7 +179,6 @@ accelerator = "meta G" action_listener = function(_) local input = show_input_dialog( window.frame, "Goto line" ) - --logger.info("input "..input) local line = input and to_number(input) if line ~= nil then window.goto(line) @@ -190,14 +191,93 @@ } end +local function get_matches(text,s) + local n = #s + if n == 0 then + return nil + end + local matches = {} + local i = 0 + while(true) do + local j = find(text,s,i) + if j == nil then + break + end + matches[#matches+1] = { start=j, end_=j+n } + i = j + n + end + return matches +end + local function make_find_dialog(window) + local text_area = window.text_area + local find_field, output + local function find_match(event) + --logger.info("action "..event.action) + local s = find_field.text + local matches = get_matches( text_area.text, s ) + if matches == nil then + output.text = "" + return + end + local n_matches = #matches + if n_matches == 0 then + output.text = "0 matches" + return + end + local action = event.action + if action == "next" then + local _, pos = text_area.get_selection() + for i, match in ipairs(matches) do + if match.start >= pos then + text_area.set_selection( match.start, match.end_ ) + output.text = i.." of "..n_matches.." matches" + return + end + end + local match = matches[1] + text_area.set_selection( match.start, match.end_ ) + output.text = "1 of "..n_matches.." matches; wrapped past end" + elseif action == "previous" then + local pos = text_area.get_selection() + for i in range(n_matches,1,-1) do + local match = matches[i] + if match.end_ <= pos then + text_area.set_selection( match.start, match.end_ ) + output.text = i.." of "..n_matches.." matches" + return + end + end + local match = matches[n_matches] + text_area.set_selection( match.start, match.end_ ) + output.text = n_matches.." of "..n_matches.." matches; wrapped past end" + else + error(action) + end + end + find_field = new_text_field{ + constraints = "wrap,growx" + columns = 20 + action = "next" + action_listener = find_match + } + output = new_label{ + constraints = "span,grow" + text = "testing" + } local dialog = new_dialog{ owner_frame = window.frame content_pane = new_panel{ - layout = new_mig_layout("debug","[][grow]","[][grow,top]") + layout = new_mig_layout("","[][grow]") children = { new_label{ - text = "Find Next:" + constraints = "right" + text = "Find:" + } + find_field + new_label{ + constraints = "right" + text = "Replace:" } new_text_field{ constraints = "wrap,growx" @@ -205,18 +285,21 @@ } new_panel{ constraints = "span,wrap" - layout = new_mig_layout("debug,insets 0") - --border = create_empty_border(8,8,8,8) - --border = create_line_border(int_to_color(0)) + layout = new_mig_layout("insets 0") children = { new_button{ text = "Find Next" + action = "next" + action_listener = find_match } new_button{ text = "Find Previous" + action = "previous" + action_listener = find_match } } } + output } } }