summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2021-05-27 19:03:02 +0200
committerJohn Ankarström <john@ankarstrom.se>2021-05-27 19:03:02 +0200
commit76042851b82d9471991440856182da4bff03be7f (patch)
treebe91d99b4d3e6164deb256dfc0e78914f5d213af
parentb05762b6afcc16894f667d775451c08da34d790b (diff)
downloadmum-76042851b82d9471991440856182da4bff03be7f.tar.gz
mum: Fix range parsing, implement 'h' command
-rwxr-xr-xsrc/mum88
1 files 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> (?{ @RANGE = () })
- ( (?&ref)
- | (?&ref),(?&ref)
+ ( (?&ref) (?{ local %A = %REF })
+ , (?&ref)
+ | (?&ref)
| (?&grep)
)
- (?{ push @RANGE, \%REF })
+ (?{ push @RANGE, \%A if %A; push @RANGE, \%REF })
)
(?<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);
+}