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;
}
$screen->refresh;
}
+ $screen->draw_matches($config, $matches, []); # remove matches
+
foreach (@{$matches}) {
return { match => $_ } if $_->{id} == $number;
}
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) = @_;
return {
select => 'search',
matches => \@last_matches,
+ extend => 1,
handler => $config->{handler}{yank},
};
}
$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}) {