Skip to content

Commit

Permalink
de: basic support for mark (k) command (#812)
Browse files Browse the repository at this point in the history
* Mark is a standard feature in ed and it's not very much code to support it
* Resolving a mark that doesn't exist results in Invalid Address error
* 1,2kx ---> mark x as 2
* 1kx ---> mark x as 1
* kx ---> mark x as CurrentLine (default)
* 'x,$n ---> run n command from marked line x to end of buffer
  • Loading branch information
mknos authored Nov 15, 2024
1 parent b24bf24 commit 2855e11
Showing 1 changed file with 25 additions and 3 deletions.
28 changes: 25 additions & 3 deletions bin/ed
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ License: gpl
#
# Todo:
# - Implement the following commands from the v7 docs:
# k - mark
# u - undo
#
# - add a "-e" flag to allow it to be used in sed(1) like fashion.
Expand All @@ -63,6 +62,7 @@ use Getopt::Std qw(getopts);
use constant A_NOMATCH => -1;
use constant A_NOPAT => -2;
use constant A_PATTERN => -3;
use constant A_NOMARK => -4;

use constant E_ADDREXT => 'unexpected address';
use constant E_ADDRBAD => 'invalid address';
Expand Down Expand Up @@ -97,6 +97,7 @@ my $command; # single letter command entered by user
my $commandsuf; # single letter modifier of command
my @adrs; # 1 or 2 line numbers for commands to operate on
my @args; # command arguments (filenames, search patterns...)
my %marks;
my $isGlobal;

my $EXTENDED_MESSAGES = 0;
Expand All @@ -112,7 +113,7 @@ my $NO_QUESTIONS_MODE = 0;
my $PRINT_NUM = 1;
my $PRINT_BIN = 2;

our $VERSION = '0.16';
our $VERSION = '0.17';

my @ESC = (
'\\000', '\\001', '\\002', '\\003', '\\004', '\\005', '\\006', '\\a',
Expand Down Expand Up @@ -170,6 +171,7 @@ my %cmdtab = (
't' => \&edMove,
'H' => \&edSetHelp,
'h' => \&edHelp,
'k' => \&edMark,
'm' => \&edMoveDel,
'n' => \&edPrintNum,
'l' => \&edPrintBin,
Expand Down Expand Up @@ -313,6 +315,19 @@ sub edHelp {
}
}

sub edMark {
my $c = $args[0];
if (!defined($c) || $c !~ m/\A[a-z]\z/) {
edWarn(E_SUFFBAD);
return;
}
my $ad = $adrs[1];
$ad = $adrs[0] unless defined $ad;
$ad = $CurrentLineNum unless defined $ad;
$marks{$c} = $ad;
return;
}

#
# Print contents of requested lines
#
Expand Down Expand Up @@ -936,7 +951,7 @@ sub edParse {
$isGlobal = 1;
@adrs = @found;
}
if (s/\A([acdEefHhijlmnPpQqrstWw=\!])//) { # optional argument
if (s/\A([acdEefHhijklmnPpQqrstWw=\!])//) { # optional argument
$command = $1;
if ($command eq 'W' || $command eq 'w') {
if (s/\A[Qq]//) {
Expand Down Expand Up @@ -964,6 +979,8 @@ sub getAddr {
foreach my $c (split //, $1) {
$n += $c eq '+' ? 1 : -1;
}
} elsif (s/\A\'([a-z])//) {
$n = exists $marks{$1} ? $marks{$1} : A_NOMARK;
} elsif (s/\A([0-9]+)//) { # '10' == 10
$n = $1;
} elsif (s/\A\.//) { # '.' == current line
Expand Down Expand Up @@ -1181,6 +1198,11 @@ Insert text
Join a range of lines into a single line.
The current address is set to the destination address.
=item kCH
Mark an address with the lowercase letter CH.
The mark can then be used as 'CH in place of an address.
=item l
Print lines with escape sequences for non-printable characters
Expand Down

0 comments on commit 2855e11

Please sign in to comment.