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.