App-Prima-REPL
view release on metacpan or search on metacpan
lib/PrimaX/InputHistory.pm view on Meta::CPAN
sub currentLine {
return $_[0]->{currentLine} unless $#_;
my ($self, $line_number) = @_;
# Save changes to the current line in the revision list:
$self->currentRevisions->[$self->{currentLine}] = $self->text;
# Get the current character offset:
my $curr_offset = $self->charOffset;
# Note the end-of-line position by zero:
$curr_offset = 0 if $curr_offset == length($self->text);
# make sure the requested line makes sense; cycle if it doesn't, and just
# set to zero if there is no history:
my $last_line = scalar @{$self->history};
if ($last_line) {
$line_number += $last_line while $line_number < 0;
$line_number -= $last_line while $line_number > $last_line;
}
else {
$line_number = 0;
}
# Set self's current line:
$self->{currentLine} = $line_number;
# Load the text using the Orcish Maneuver:
my $new_text = $self->currentRevisions->[$line_number]
//= $self->history->[-$line_number]; #/
$self->text($new_text);
# Put the cursor at the previous offset. However, if the previous offset
# was zero, put the cursor at the end of the line:
$self->charOffset($curr_offset || length($new_text));
return $line_number;
}
# Add a new notification_type for each of on_PressEnter and on_Evaluate. The
# first should be set with hooks that remove or modify any text that needs to be
# cleaned before the eval stage. In other words, if you want to define commands
# that do not parse as a function in Perl, add it as a hook under on_PressEnter.
# The best examples I can think of, which also serve to differentiate between
# the two needs, are NiceSlice processing, and processing the help command. To
# make help work as a bona-fide function, you would have to surround your topic
# with quotes:
# help 'PDL::IO::FastRaw'
# That's ugly. It would be much nicer to avoid the quotes, if possible, with
# something like this:
# help PDL::IO::FastRaw
# That's the kinda thing you would handle with an on_PressEnter hook. After the
# help hook handles that sort of thing, it then calls the clear_event() method
# on the InputHistory object. On the other hand, NiceSlice parsing will modify
# the contents of the evaluation, but not call clear_event because it wants the
# contents of the text to be passed to the evaluation.
#
# If the event is properly handled by one of the hooks, the hook should call the
# clear_event() method on this object.
{
# Keep the notifications hash in its own lexically scoped block so that
# other's can't mess with it (at least, not without using PadWalker or some
# such).
my %notifications = (
%{Prima::InputLine-> notification_types()},
PressEnter => nt::Request,
Evaluate => nt::Action,
PostEval => nt::Request,
);
sub notification_types { return \%notifications }
}
# Issues the on_Evaluate notification. The default evaluation is pretty lame -
# it just prints the result of evaling the text using the print command.
sub Evaluate {
my ($self, $text) = @_;
$_[0]->notify('Evaluate', $text);
}
sub on_evaluate {
my ($self, $text) = @_;
my $results = eval ($text);
$self->outputWidget->newline_printout($results) if defined $results;
$self->outputWidget->newline_printout('undef') if not defined $results;
}
# Issues the on_PostEval notification.
sub PostEval {
$_[0]->notify('PostEval');
}
# The default notification is to do nothing:
sub on_posteval {}
# Issues the on_Enter notification, which starts with the class's method. The
# return value here is important and determines whether or not to evaluate the
# result. Evaluation can be prevented by a handler by calling the clear_event
# method on the InputHistory object from within the handler.
sub PressEnter {
my $self = shift;
# Get a copy of the text from the widget.
my $text = $self->text;
# Call the hooks, allowing them to modify the text as they go:
my $needs_to_eval = $self->notify('PressEnter', $text);
$self->Evaluate($text) if $needs_to_eval;
$self->PostEval($text);
}
# This is the object's method for handling PressEnter events. Its job is to
# handle all of the history-related munging. It does not change the contents of
# the text, so it is safe to unpack the text. (Hooks that intend to modify the
# text must work directly with $_[1].)
#
# Additional PressEnter handlers are called after this one and can be added with
# $input_widget->add_notification(PressEnter => sub {});
sub on_pressenter {
my ($self, $text) = @_;
# Remove the endlines, if present, replacing them with safe whitespace:
$text =~ s/\n/ /g;
( run in 4.460 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )