Skip to content

Commit 78d5429

Browse files
authored
ed: basic repeated search (#764)
* If I search for a pattern with "/hi" or "?bye" I want to repeat the search without re-entering the pattern (it might be much longer than "hi") * Allow typing a single "/" or "?" to repeat search down or up respectively (this will fail if a previous search was not performed) * GNU ed also supports repeating search with empty pattern typed as "//" or "??" but that is not supported here for now
1 parent fcaf065 commit 78d5429

File tree

1 file changed

+26
-1
lines changed

1 file changed

+26
-1
lines changed

bin/ed

+26-1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ use constant E_UNSAVED => 'buffer modified';
7979
use constant E_CMDBAD => 'unknown command';
8080
use constant E_PATTERN => 'invalid pattern delimiter';
8181
use constant E_NOMATCH => 'no match';
82+
use constant E_NOPAT => 'no previous pattern';
8283

8384
# important globals
8485

@@ -88,6 +89,7 @@ my $NeedToSave = 0; # buffer modified
8889
my $UserHasBeenWarned = 0; # warning given regarding modified buffer
8990
my $Error = undef; # saved error string for h command
9091
my $Prompt = undef; # saved prompt string for -p option
92+
my $SearchPat; # saved pattern for repeat search
9193
my $SupressCounts = 0; # byte counts are printed by default
9294
my @lines; # buffer for file being edited.
9395
my $command; # single letter command entered by user
@@ -108,7 +110,7 @@ my $NO_QUESTIONS_MODE = 0;
108110
my $PRINT_NUM = 1;
109111
my $PRINT_BIN = 2;
110112

111-
our $VERSION = '0.5';
113+
our $VERSION = '0.6';
112114

113115
my @ESC = (
114116
'\\000', '\\001', '\\002', '\\003', '\\004', '\\005', '\\006', '\\a',
@@ -887,6 +889,27 @@ sub edSetCurrentLine {
887889

888890
sub edParse {
889891
s/\A\s+//;
892+
if (m/\A(\/|\?)\z/) {
893+
unless (defined $SearchPat) {
894+
edWarn(E_NOPAT);
895+
$command = 'nop';
896+
return 1;
897+
}
898+
my $found;
899+
if ($1 eq '/') {
900+
$found = edSearchForward($SearchPat);
901+
} else {
902+
$found = edSearchBackward($SearchPat);
903+
}
904+
if ($found == 0) {
905+
edWarn(E_NOMATCH);
906+
$command = 'nop';
907+
return 1;
908+
}
909+
$_ = $found . 'p';
910+
return edParse();
911+
}
912+
890913
my @fields =
891914
(/^(
892915
(
@@ -1036,6 +1059,7 @@ sub CalculateLine {
10361059
sub edSearchForward {
10371060
my($pattern) = @_;
10381061

1062+
$SearchPat = $pattern;
10391063
for my $line (($CurrentLineNum + 1) .. maxline(), 1 .. $CurrentLineNum) {
10401064
if ($lines[$line] =~ /$pattern/) {
10411065
return $line;
@@ -1060,6 +1084,7 @@ sub edSearchForward {
10601084
sub edSearchBackward {
10611085
my($pattern) = @_;
10621086

1087+
$SearchPat = $pattern;
10631088
my @idx = ($CurrentLineNum .. maxline(), 1 .. ($CurrentLineNum - 1));
10641089
foreach my $line (reverse @idx) {
10651090
if ($lines[$line] =~ /$pattern/) {

0 commit comments

Comments
 (0)