Day 3 – Perl 6 – jmp 2 it

jmp is a Perl 6 powered command-line program I use every day to navigate through piles of Perl and quickly jump into my $EDITOR. I try and stay in a state of flow while coding and the ability to quickly search files and then jump straight into an editor helps.

jmp is a simple terminal-based frontend to your favourite code searching tool (e.g., rgrep, ag, ack, git grep etc). It displays a list of search results you can quickly browse through before jumping in to edit your file (e.g., vim, nano, comma etc).

It works like this:

Recently I refactored jmp to improve the user interface with the help of the Terminal::Print module. Terminal::Print provides a handy two dimensional grid for drawing on the terminal screen. There is also a module for processing user input asynchronously.

Here is the jmp code that reacts whenever the user presses a key:

my $in-supply = decoded-input-supply;
my $timer = Supply.interval(1).map: { Tick };
my $supplies = Supply.merge($in-supply, $timer);

react {
whenever $supplies -> $_ {
when Tick {}
when 'CursorUp' { self.pager.cursor-up; }
when 'CursorDown' { self.pager.cursor-down; }
when 'CursorRight' | 'PageDown' { self.pager.next; }
when 'CursorLeft' | 'PageUp' { self.pager.previous; }
when 'x' | 'X' { self.pager.exit-page; }
when 'e' | 'E' {
self.pager.edit-selected($!editor);
}
when $_ ~~ Str and $_.ord == 13 {
# the user pressed ENTER
self.pager.edit-selected($!editor);
}
}
}

This code sets up an asynchronous supply of user input events and it reacts whenever an event fires (e.g., the user presses PageUp). But what happens if the user presses lots of keys at once? How is the terminal screen updated in an orderly way?

The solution is found inside Terminal::Print::Grid thanks to Jonathan Worthington’s OO::Monitors module and the monitor keyword. This ensures that only one thread can be inside the grid object’s methods at a time:

use OO::Monitors;
unit monitor Terminal::Print::Grid;

Making your own Perl 6 powered command-line tools is a great way to learn the language. Check out Terminal::Print if you need a terminal interface. To speed up your command-line tools it’s a good trick to place the code inside a module so Perl 6 can pre-compile it for faster start up times (e.g., CLI.pm) .

To install version 2 of jmp, first install Perl 6, then use zef the Perl 6 module manager to install it:

shell> zef install jmp   # or zef upgrade jmp
shell> jmp config # set up jmp to use your tools
shell> jmp find sub MAIN # find files containing "sub MAIN"

Keep an eye out for more command-line tools to unwrap as we get closer to Christmas.

3 thoughts on “Day 3 – Perl 6 – jmp 2 it

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.