Rash - A Raku Shell

Exercise 1: PWD

by Arne Sommer

Rash - Exercise 1: PWD

[67.3.1] Published 13. April 2020.

You have read the Exercise text first?

Note that $*CWD holds an IO-object, and applying say doesn't change that. We have to stringify it manually with .Str:

> $*CWD.say
"/home/raku/code".IO

> $*CWD.Str.say
/home/raku/code

Update the list of commands:

my @commands = <cd exit help pwd run version>;

Remove these lines:

do-allow "pwd";
do-allow "more";

Add this line in the given block:

when "pwd"           { say $*CWD.Str; }

The complete program (based on «rash-allow2»):

File: rash-pwd
use Linenoise;

constant HIST_FILE = ( $*HOME.add: '.rash-hist' ).Str;
constant HIST_LEN  = 25;

linenoiseHistoryLoad(HIST_FILE);
linenoiseHistorySetMaxLen(HIST_LEN);

my @commands = <allow cd exit help pwd run version>;
my %allow;

do-allow "pwd";
do-allow "more";

linenoiseSetCompletionCallback(-> $line, $c
{
  for @commands.grep(/^ $line /).sort -> $cmd
  {
    linenoiseAddCompletion($c, $cmd);
  }
});

say 'rash: Enter «exit» to exit';

while (my $line = linenoise '> ').defined
{
  linenoiseHistoryAdd($line);

  given $line
  {
    when /^allow\s+(.*)/ { do-allow $0; }
    when /^cd\s+(\S+)/   { do-chdir $0; }
    when "exit"          { last; }
    when "help"          { say "Legal commands: { @commands }" }
    when "pwd"           { say $*CWD.Str; }
    when /^run\s+(.*)/   { do-run $0; }
    when "version"       { say "Version 0.10"; }
    default
    {
      my ($cmd, $arg) = $line.split(/\s/, 2);
      %allow{$cmd}
        ?? do-run $line
        !! say "Unknown command: \"$_\" (use \"help\" for a list of commands)";
    }
  }
}

linenoiseHistorySave(HIST_FILE);

sub do-run ($line)
{
  my ($cmd, @args) = $line.words;

  my $res = @args
    ?? run $cmd, @args
    !! run $cmd;

  if ! $res.pid
  {
    say "$cmd: command not found";
  }
  elsif $res.exitcode 
  {
    say "$cmd: exit with code { $res.exitcode }";
  }
}

sub do-chdir ($dir)
{
  say "cd: $dir: No such file or directory" unless chdir $dir;
}

sub do-allow ($cmd)
{
  @commands.push($cmd);
  %allow{$cmd} = True;
}