Commit | Line | Data |
9eedd677 |
1 | package DX::ShellFrontend; |
2 | |
3 | use IO::Handle; |
4 | use Caroline; |
5 | use DX::Class; |
6 | |
7 | has session => ( |
8 | is => 'ro', required => 1, |
9 | handles => [ qw(is_complete_command_string eval_command_string) ] |
10 | ); |
11 | |
12 | has session_mode => (is => 'rwp', required => 1); |
13 | |
14 | has readline => (is => 'lazy', builder => sub { Caroline->new }); |
15 | |
16 | sub BUILD { STDOUT->autoflush(1) } |
17 | |
18 | sub repl { |
19 | my ($self) = @_; |
20 | while (1) { |
21 | last unless $self->rep |
22 | } |
23 | } |
24 | |
25 | sub rep { |
26 | my ($self) = @_; |
27 | return unless defined(my $command = $self->read_command); |
28 | my @result = $self->eval_command_string($command); |
29 | $self->process_result(@result); |
30 | return 1; |
31 | } |
32 | |
33 | sub read_command { |
34 | my ($self) = @_; |
35 | my $base_prompt = $self->session_mode eq 'shell' ? '$ ' : '? '; |
36 | my $rl = $self->readline; |
37 | return unless defined(my $command = $rl->readline($base_prompt)); |
38 | while (not $self->is_complete_command_string($command)) { |
39 | $command .= $rl->readline('> '); |
40 | } |
41 | $rl->history_add($command); |
42 | return $command; |
43 | } |
44 | |
45 | sub process_result { |
46 | my ($self, @result) = @_; |
47 | foreach my $res (@result) { |
48 | my ($type, $payload) = @$res; |
49 | $self->${\($self->can("process_${type}_result")||die)}($payload); |
50 | } |
51 | } |
52 | |
53 | sub process_mode_result { |
54 | my ($self, $mode) = @_; |
55 | $self->_set_session_mode($mode); |
56 | } |
57 | |
58 | sub process_output_result { |
59 | my ($self, $output) = @_; |
fa8f5696 |
60 | $output .= "\n" unless $output =~ /\n$/; |
9eedd677 |
61 | print $output; |
62 | } |
63 | |
64 | 1; |