diff options
author | John Ankarström <john@ankarstrom.se> | 2021-05-26 01:36:03 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2021-05-26 01:36:03 +0200 |
commit | b9ed52e3684e49b9b00ef08b29111758cc4777ee (patch) | |
tree | 1554f0465c0de4f5a01ec2b938e7cb9547938e76 | |
parent | e0b52520b57cbcf6454ea35e97c99003d5596508 (diff) | |
download | mum-b9ed52e3684e49b9b00ef08b29111758cc4777ee.tar.gz |
Add main 'mum' script
-rwxr-xr-x | src/mum | 121 |
1 files changed, 121 insertions, 0 deletions
@@ -0,0 +1,121 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use feature qw/switch/; +no warnings qw/experimental::smartmatch/; + +use Data::Dumper; + +# Open TTY for reading and writing + +open my $tty, '+<:unix', '/dev/tty' or die "Could not open /dev/tty: $!"; + +# Define range syntax + +my @range; # range (one/two references) +our %ref; # current reference in range +my $d = qr{ + (?(DEFINE) + (?<range> (?{ @range = () }) + ( (?&ref) + | (?&ref),(?&ref) + | (?&pattern) + ) + (?{ push @range, \%ref }) + ) + (?<ref> ( (\d+) (?{ local %ref = (line => $^N) }) + | (\.|\$) (?{ local %ref = (spec => $^N) }) + | ' ([a-z]) (?{ local %ref = (mark => $^N) }) + | /((\\/|[^/])*)/ (?{ local %ref = (next => $^N) }) + | \?((\\\?|[^?])*)\? (?{ local %ref = (prev => $^N) }) + ) + ( ([+-] \d+) (?{ local %ref = (%ref, plus => $^N) }) + )? + ) + (?<pattern> g/((\\/|[^/])*)/ (?{ local %ref = (patt => $^N) }) + ) + ) +}x; + +# Define program state + +my $message = 1; # selected message + +# Run program + +while () { + print $tty "$message& "; + + # Read next command from user + + my $cmd = <$tty>; + $cmd = '' if not $cmd; + chomp $cmd; + $cmd =~ s/^\s+|\s+$//g; + + # Parse user-given command + + for ($cmd) { + # q + if (/^q$/) { + exit; + } + + # range without command + elsif (/^(?&range) \Z $d/x) { + print Dumper(@range), "\n"; + # select last message in range + print "range without command\n"; + } + + # +/- (++/--) + elsif (/^(?<num> \d*) (?<dir> (\+\+?|--?)) \Z/x) { + for ($+{dir}) { + $message += $+{num} || 1 if /\+/; + $message -= $+{num} || 1 if /-/; + goto h if length($_) > 1; + } + } + + # c + elsif (/^c\s+(.*)/) { + chdir $1; + } + + # h + elsif (/^ (?&range)? h \Z $d/x) { +h: + print "h\n"; + } + + # p + elsif (/^ (?&range)? p \Z $d/x) { + print Dumper(@range), "\n"; + print "p\n"; + } + + # | + elsif (/^ (?&range)? \| (?<rest>.+) $d/x) { + print "|\n"; + } + + # ! + elsif (/^!/) { + $cmd =~ s/!//; + system $cmd; + print "!\n"; + } + + # empty command + elsif (/^$/) { + $message++; + } + + # unrecognized command + else { + warn "unrecognized command syntax\n"; + next; + } + } +} |