From 37ec012bdcb1ac20deea423cb9b4ff4d8c13cade Mon Sep 17 00:00:00 2001 From: Simon Ruderich Date: Sun, 24 Jan 2016 20:39:25 +0100 Subject: [PATCH] allow extending a match after search mode --- bin/fcscs | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/bin/fcscs b/bin/fcscs index 7543a9d..95a769a 100755 --- a/bin/fcscs +++ b/bin/fcscs @@ -401,7 +401,7 @@ sub get_regex_matches { my ($x, $y) = input_match_offset_to_coordinates($input->{width}, $offset); - push @matches, { x => $x, y => $y, string => $1 }; + push @matches, { x => $x, y => $y, offset => $offset, string => $1 }; } return @matches; } @@ -543,6 +543,8 @@ sub select_match { $screen->refresh; } + $screen->draw_matches($config, $matches, []); # remove matches + foreach (@{$matches}) { return { match => $_ } if $_->{id} == $number; } @@ -550,6 +552,86 @@ sub select_match { return { match => undef }; } +sub extend_match_regex_left { + my ($line, $match, $regex) = @_; + + my $s = reverse substr $line, 0, $match->{x}; + if ($s =~ /^($regex)/) { + $match->{string} = reverse($1) . $match->{string}; + $match->{x} -= length $1; + $match->{offset} -= length $1; + } + return; +} +sub extend_match_regex_right { + my ($line, $match, $regex) = @_; + + my $s = substr $line, $match->{x} + length $match->{string}; + if ($s =~ /^($regex)/) { + $match->{string} .= $1; + } + return; +} +sub extend_match { + my ($screen, $config, $input, $match) = @_; + + debug $config, 'extend_match', 'started'; + + $screen->prompt(name => 'extend', value => undef); + $screen->draw_prompt($config); + + delete $match->{id}; # don't draw any match ids + $screen->draw_matches($config, [], [$match]); + $screen->refresh; + + my $line = $input->{lines}[$match->{y}]; + + while (1) { + my $match_old = \%{$match}; + + my $char = $screen->getch; + if ($char eq "\n") { # accept match + last; + + } elsif ($char eq 'w') { # select current word (both directions) + extend_match_regex_left($line, $match, qr/\w+/); + extend_match_regex_right($line, $match, qr/\w+/); + } elsif ($char eq 'b') { # select current word (only left) + extend_match_regex_left($line, $match, qr/\w+/); + } elsif ($char eq 'e') { # select current word (only right) + extend_match_regex_right($line, $match, qr/\w+/); + + } elsif ($char eq 'W') { # select current WORD (both directions) + extend_match_regex_left($line, $match, qr/\S+/); + extend_match_regex_right($line, $match, qr/\S+/); + } elsif ($char eq 'B') { # select current WORD (only left) + extend_match_regex_left($line, $match, qr/\S+/); + } elsif ($char eq 'E') { # select current WORD (only right) + extend_match_regex_right($line, $match, qr/\S+/); + + } elsif ($char eq '^') { # select to beginning of line + extend_match_regex_left($line, $match, qr/.+/); + } elsif ($char eq '$') { # select to end of line + extend_match_regex_right($line, $match, qr/.+/); + + # Allow mode changes if not overwritten by local mappings. + } elsif (defined $config->{mapping}{mode}{$char}) { + $screen->draw_matches($config, [$match_old], []); # clear match + return { key => $char }; + + } else { + next; # ignore unknown mappings + } + + $screen->draw_matches($config, [$match_old], [$match]); + $screen->refresh; + } + + debug $config, 'extend_match', 'done'; + + return { match => $match }; +} + sub mapping_paste { my ($key, $screen, $config, $input) = @_; @@ -659,6 +741,7 @@ sub mapping_mode_search { return { select => 'search', matches => \@last_matches, + extend => 1, handler => $config->{handler}{yank}, }; } @@ -1214,6 +1297,13 @@ RESULT: $screen, \%config, $input, $result->{matches}); $result->{handler} = $tmp->{handler}; + $result->{extend} = $tmp->{extend}; + goto RESULT; # reprocess special entries in result + } + if (defined $result->{extend}) { + debug \%config, 'input', 'extending match'; + $result = extend_match($screen, \%config, $input, + $result->{match}); goto RESULT; # reprocess special entries in result } if (defined $result->{match}) { -- 2.43.2