Day 10 – jmp-starting your work flow

Here’s yet another version of jmp for you to unwrap before Christmas.

jmp is a command-line tool for searching through piles of code and then quickly jumping into an $EDITOR. This helps to keep things flowing.

Computer programming, however, has plenty of potential flow stoppers. To maintain a state of flow while coding you often need to quickly jmp to a line of code in other situations: fixing bugs, running tests, inspecting log files, checking git status etc. Can jmp help speed up these tasks too?

Fortunately it was relatively easy to refactor jmp to accommodate these extra use cases. The latest version of jmp now works like this:

Prefixing a command with jmp will cause the command to be executed again and its output slurped in and paginated.

#| find matching lines
method find-files-in-command-output ($command) {

    # execute the command
    my $shell-cmd = shell $command, :out, :err;

    # join STDOUT and STDERR
    my $result = join("\n", $shell-cmd.out.slurp, 
                            $shell-cmd.err.slurp);

    # don't actually look for filenames just yet
    # do that lazily on demand by the user
    return $result.lines.map({ 
               JMP::File::HitLater.new(context => $_) 
           });
}

jmp creates result hits for each line, and paginates the result. You can then quickly browse the output and jmp into your text editor if needed (see jmp config to change it to your favourite EDITOR).

Speed is important for command-line tools. Rather than scan each line for filenames in advance, jmp only looks for filenames when the user chooses to edit a specific line. Here is the code that lazily parses a line looking for files:

submethod find-file-path {

    given self.context {

        # matches Perl 5 error output (e.g., at SomePerl.pl line 12)
        when /at \s (\S+) \s line \s (\d+)/ {
            proceed unless self.found-file-path($/[0], $/[1]);
        }

        # matches Perl 6 error output (e.g., at SomePerl6.p6:12)
        when /at \s (<-[\s:]>+) ':' (\d+)/ {
            proceed unless self.found-file-path($/[0], $/[1]);
        }

        # matches Perl 6 error output (e.g., SomePerl6.p6 (Some::Perl6):12)
        when /at \s (<-[\s:]>+) '(' \S+ ')' ':' (\d+)/ {
            proceed unless self.found-file-path($/[0], $/[1]);
        }

        # more file finding patterns HERE - PR's welcome?

        # go through each token
        default {
            for self.context.words -> $token {
                # keep trying to set the file path
                proceed if self.found-file-path($token);
            }
        }
    }
}

The when blocks match different types of error formats (e.g., Perl 5 and Perl 6)  to extract the filename and line number. The proceed statement is useful for moving on to the next when block.

This means you can jmp on an error wherever it appears in your workflow: in command output, test output, log files etc.

To upgrade to version 3 of jmp:

shell> zef upgrade jmp

To install jmp for the first time, install Perl 6, then use zef the Perl 6 module manager to install it:

shell> zef install jmp   # install the jmp command line tool
shell> jmp config # set up jmp to use your tools
shell> jmp to sub MAIN # find files containing "sub MAIN"

Hopefully jmp helps you find flow while coding. Happy Christmas!

One thought on “Day 10 – jmp-starting your work flow

Leave a comment

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