[CursorBase] split out sys_find_module from sys_load_module
[pugs.git] / examples / shell.pl
blobf09f4d4a29aafaf0729ed5810696b28eee9e0ad5
1 use v6;
3 # A simple shell written in Perl6
5 # TODO
6 # BACKPSACE, history, editing ?
9 my $prompt = '<p6shell>$ ';
10 my $VERSION = '0.01';
12 # we should have this list from some internal command
13 # probably along with the signature of these functions
14 my @available_commands = <exit print say>;
15 @available_commands.push( <mkdir rmdir chdir unlink chmod chown> );
16 @available_commands.push( <pop push> );
19 # Enable reading character as they ar typed, see Perl5: perldoc -f getc
20 # It would be better to use Term::ReadKey but it has to be implemented for Perl6
21 my $BSD_STYLE = 1;
23 if ($BSD_STYLE) {
24 run "stty cbreak </dev/tty >/dev/tty 2>&1";
26 else {
27 run "stty", '-icanon', 'eol', "\x01";
30 my $_loop_ = get_loop();
31 eval $_loop_;
33 if ($BSD_STYLE) {
34 run "stty -cbreak </dev/tty >/dev/tty 2>&1";
36 else {
37 run "stty", 'icanon', 'eol', '^@'; # ASCII null
39 exit;
41 #################################################333
43 sub get_loop {
44 return '
45 loop {
46 my $command = "";
47 print "\n", $prompt;
48 loop {
49 my $char = $*IN.getc;
50 if ($char eq "\n") {
51 # TODO: maybe check if _loop_ shows up in the input and disallow that code ?
52 if (eval "$command;" ~ $_loop_ ) {
53 exit;
55 else {
56 print $!;
57 last;
60 if ($char eq "\t") {
61 # clean the TAB but keep what we had so far
62 refresh_commandline($command);
64 my $tail = tab_completition($command);
66 if (defined $tail) {
67 $command ~= $tail;
68 refresh_commandline($command);
70 next;
72 $command ~= $char;
78 # TODO: this should understand the command line typed in so far....
79 sub tab_completition {
80 my ($command) = @_;
82 my @possible_commands = grep { not index($_, $command)}, @available_commands;
83 # TODO: might really get more than one... and we should let the user step through them using TAB
84 # or display all possible values, or the user should be able to configure the behivaior
85 return if not @possible_commands;
86 return substr(@possible_commands[0], $command.bytes) if 1 == @possible_commands;
88 # TODO: if there are too many (> $LIMIT) ask if the user really wants to display all
89 my $WIDTH = 80;
90 my $out = '';
91 my $line = '';
92 for @possible_commands -> $com {
93 if ($line.bytes + 1 + $com.bytes <= $WIDTH) {
94 $line ~= " $com";
95 } else {
96 $out ~= "$line\n";
97 $line = $com;
100 $out ~= "$line\n";
101 print "\n$out";
102 return "";
105 sub refresh_commandline {
106 my ($command) = @_;
107 print "\r", $prompt;
108 print " " x $command.bytes + 1;
109 print "\r", $prompt;
110 print $command;