From 76042851b82d9471991440856182da4bff03be7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Thu, 27 May 2021 19:03:02 +0200 Subject: mum: Fix range parsing, implement 'h' command --- src/mum | 88 ++++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/src/mum b/src/mum index 22dd6bf..4ce9d05 100755 --- a/src/mum +++ b/src/mum @@ -5,6 +5,7 @@ use strict; use warnings; use Data::Dumper; +use Email::MIME::RFC2047::Decoder; use Getopt::Std; use POSIX qw/sigaction SIGINT/; use Term::ReadLine; @@ -15,16 +16,18 @@ our $VERSION = '0.01'; # Define range syntax my @RANGE; # range (one/two references) -our %REF; # current reference +our %REF; # currently matched reference +our %A; # first reference in currently matched range my $d = qr{ (?(DEFINE) (? (?{ @RANGE = () }) - ( (?&ref) - | (?&ref),(?&ref) + ( (?&ref) (?{ local %A = %REF }) + , (?&ref) + | (?&ref) | (?&grep) ) - (?{ push @RANGE, \%REF }) + (?{ push @RANGE, \%A if %A; push @RANGE, \%REF }) ) (? ( (\d+) (?{ local %REF = (line => $^N) }) | (\.|\$) (?{ local %REF = (spec => $^N) }) @@ -52,10 +55,11 @@ my $MBOX = ''; # associated mbox my @MESSAGES; # loaded messages my %MARKS; # saved marks my $SEARCH; # last search regex +my $DECODER = Email::MIME::RFC2047::Decoder->new; # Open TTY for reading and writing -open my $tty, '+<:unix', '/dev/tty' or die "Could not open /dev/tty: $!"; +open my $tty, '+<:unix:encoding(utf8)', '/dev/tty' or die "Could not open /dev/tty: $!"; # Parse arguments @@ -112,7 +116,6 @@ while () { for ($+{dir}) { $MESSAGE += $num if /\+/; $MESSAGE -= $num if /-/; - goto h if length($_) > 1; } } @@ -123,40 +126,47 @@ while () { # h -- print summary of headers elsif (/^ (?&range)? h \Z $d/x) { -h: - print "h\n"; + my ($a, $b) = range() or next; + if ($a == $b) { + $a -= 4; + $a = 1 if $a < 1; + } + + my $i = $a-1; + for (@MESSAGES[$a-1..$b-1]) { + $i++; + + /^(From .*)$/m; + print $tty "($i) "; + print $tty $DECODER->decode_text($1), "\n"; + + /^(Date: .*)$/m; + print $tty "$1\n"; + + /^(Subject: .*)$/m; + my $s = $1; + $s =~ s/Re:=\?/Re: =?/; + print $tty $DECODER->decode_text($s), "\n"; + + print "\n"; + } } # i -- print headers verbatim - elsif (/^ (&range)? i \Z $d/x) { - my ($a, $b); - $a = toloc(0, shift @RANGE) or next if @RANGE > 1; - $b = toloc($a, shift @RANGE) or next if @RANGE; - $b = $MESSAGE if not $b; - $a = $b if not $a; - + elsif (/^ (?&range)? i \Z $d/x) { + my ($a, $b) = range() or next; print "$_" for @MESSAGES[$a-1..$b-1]; } # p -- print message(s) elsif (/^ (?&range)? p \Z $d/x) { - my ($a, $b); - $a = toloc(0, shift @RANGE) or next if @RANGE > 1; - $b = toloc($a, shift @RANGE) or next if @RANGE; - $b = $MESSAGE if not $b; - $a = $b if not $a; - + my ($a, $b) = range() or next; print "$_\n" for mbox($a, $b); } # l -- view message(s) in pager elsif (/^ (?&range)? l \Z $d/x) { - my ($a, $b); - $a = toloc(0, shift @RANGE) or next if @RANGE > 1; - $b = toloc($a, shift @RANGE) or next if @RANGE; - $b = $MESSAGE if not $b; - $a = $b if not $a; - + my ($a, $b) = range() or next; open my $pager, '|-', $ENV{PAGER} || 'less' or do { warn "failed to open pager: $!\n"; next; @@ -191,10 +201,7 @@ h: # range without command elsif (/^(?&range) \Z $d/x) { - # select last message in range - my ($a, $b); - $a = toloc(0, shift @RANGE) or next if @RANGE > 1; - $b = toloc($a, shift @RANGE) or next; + my ($a, $b) = range() or next; $MESSAGE = $b; } @@ -295,11 +302,16 @@ found: sub load { my $idx = shift; # index file to read + if (not $idx) { + warn "no mbox given\n"; + return; + } + $idx =~ s/\.i$//; $idx .= '.i'; # be sure to open index and not mbox open my $h, '<', $idx or do { warn "failed to open $idx: $!\n"; - next; + return; }; $INDEX = $idx; @@ -324,7 +336,7 @@ sub mbox { open my $mbox, '<', $MBOX or do { warn "failed to open $MBOX: $!\n"; - next; + return; }; for my $i ($a .. $b) { @@ -352,4 +364,12 @@ sub mbox { return @messages; } -print $tty "\n"; +# Parse range and extract corresponding locations +sub range { + my ($a, $b); + $a = toloc(0, shift @RANGE) or return if @RANGE > 1; + $b = toloc($a, shift @RANGE) or return if @RANGE; + $b = $MESSAGE if not $b; + $a = $b if not $a; + return ($a, $b); +} -- cgit v1.2.3