App-orgadb
view release on metacpan or search on metacpan
lib/App/orgadb/Select/Shell.pm view on Meta::CPAN
$self->{_settings}{output_format} //= 'text';
$self->{_in_completion} = 0;
$self->{_state}{main_args} = $args{main_args};
$self;
}
# override, readline workarounds. TODO: extract routine. this is shared with
# App::riap.
sub cmdloop {
require Carp;
require IO::Stty;
require Signal::Safety;
my $o = shift;
my $rl = $o->{term};
local $SIG{INT} = sub {
# save history when we are interrupted
$o->save_history;
print STDERR "Interrupted\n";
if ($rl->ReadLine eq 'Term::ReadLine::Gnu') {
IO::Stty::stty(\*STDIN, 'echo');
}
exit 1;
};
local $SIG{__DIE__} = sub {
IO::Stty::stty(\*STDIN, 'echo');
$o->setting('debug_stack_trace') ? Carp::confess(@_) : die(@_);
};
local $SIG{__WARN__} = sub {
IO::Stty::stty(\*STDIN, 'echo');
$o->setting('debug_stack_trace') ? Carp::cluck(@_) : warn(@_);
};
# some workaround for Term::ReadLine
# say "D0, rl=", $rl->ReadLine;
my $attribs = $rl->Attribs;
if ($rl->ReadLine eq 'Term::ReadLine::Gnu') {
# TR::Gnu traps our INT handler
# ref: http://www.perlmonks.org/?node_id=1003497
$attribs->{catch_signals} = 0;
} elsif ($rl->ReadLine eq 'Term::ReadLine::Perl') {
# TR::Perl messes up colors
# doesn't do anything?
#$rl->ornaments(0);
#$attribs->{term_set} = ["", "", "", ""];
}
$o->{stop} = 0;
$o->preloop;
while (1) {
my $line;
{
no warnings 'once';
local $Signal::Safety = 0; # limit the use of unsafe signals
$line = $o->readline($o->prompt_str);
}
last unless defined($line);
my $time1 = time();
$o->cmd($line);
my $time2 = time();
if ($o->setting('debug_time_command')) {
say sprintf(" %.3fs", ($time2-$time1));
}
last if $o->{stop};
}
$o->postloop;
}
sub mainloop { goto \&cmdloop }
sub settings_filename {
my $self = shift;
"$ENV{HOME}/.".$self->{program_name}."rc";
}
sub history_filename {
my $self = shift;
"$ENV{HOME}/.".$self->{program_name}."_history";
}
sub known_settings {
state $settings;
if (!$settings) {
$settings = {
debug_time_command => {
summary => 'Show how long it takes to complete a command',
schema => ['bool', default=>0],
},
debug_completion => {
summary => 'Whether to display debugging for tab completion',
schema => ['bool', default=>0],
},
debug_stack_trace => {
summary => 'Whether to print stack trace on die/warning',
schema => ['bool', default=>0],
},
};
require Data::Sah::Normalize;
for (keys %$settings) {
for ($settings->{$_}{schema}) {
$_ = Data::Sah::Normalize::normalize_schema($_);
}
}
}
$settings;
}
sub setting {
my $self = shift;
my $name = shift;
die "BUG: Unknown setting '$name'" unless $self->known_settings->{$name};
if (@_) {
my $oldval = $self->{_settings}{$name};
$self->{_settings}{$name} = shift;
return $oldval;
lib/App/orgadb/Select/Shell.pm view on Meta::CPAN
my $res = Config::IOD::Reader->new->read_file($filename);
last unless $res->{GLOBAL};
for (sort keys %{$res->{GLOBAL}}) {
$self->setting($_, $res->{GLOBAL}{$_});
}
}
}
sub save_settings {
die "Unimplemented";
}
sub clear_history {
my $self = shift;
if ($self->{term}->Features->{setHistory}) {
$self->{term}->SetHistory();
}
}
sub load_history {
my $self = shift;
if ($self->{term}->Features->{setHistory}) {
my $filename = $self->history_filename;
return unless $filename;
if (-r $filename) {
log_trace("Loading history from %s ...", $filename);
open(my $fh, '<', $filename)
or die "Can't open history file $filename: $!\n";
chomp(my @history = <$fh>);
$self->{term}->SetHistory(@history);
close $fh or die "Can't close history file $filename: $!\n";
}
}
}
sub save_history {
my $self = shift;
if ($self->{term}->Features->{getHistory}) {
my $filename = $self->history_filename;
unless ($filename) {
log_warn("Skipped saving history since filename not defined");
return;
}
log_trace("Saving history to %s ...", $filename);
open(my $fh, '>', $filename)
or die "Can't open history file $filename for writing: $!\n";
print $fh "$_\n" for grep { length } $self->{term}->GetHistory;
close $fh or die "Can't close history file $filename: $!\n";
}
}
sub postloop {
my $self = shift;
print "\n";
$self->save_history;
}
sub prompt_str {
my $self = shift;
"> ";
}
my $opts = {};
my $common_opts = {
help => {
getopt=>'help|h|?',
usage => '--help (or -v, -?)',
handler=>sub {$opts->{help}=1},
},
verbose => {
getopt=>'verbose',
handler=>sub {$opts->{verbose}=1},
},
};
sub _help_cmd {
require Perinci::CmdLine::Help;
my ($self, %args) = @_;
my $res = Perinci::CmdLine::Help::gen_help(
program_name => $args{name},
meta => $args{meta},
common_opts => $common_opts,
per_arg_json => 1,
);
print $res->[2];
}
sub _run_cmd {
require Perinci::Result::Format::Lite;
require Perinci::Sub::GetArgs::Argv;
require Perinci::Sub::ValidateArgs;
local $Perinci::Result::Format::Enable_Cleansing = 1;
my ($self, %args) = @_;
my $cmd = $args{name};
my $res;
RUN:
{
$opts = {};
$res = Perinci::Sub::GetArgs::Argv::get_args_from_argv(
argv => $args{argv},
meta => $args{meta},
check_required_args => 0,
per_arg_json => 1,
common_opts => $common_opts,
);
if ($res->[0] == 501) {
# try sending argv to the server because we can't seem to parse it
$res = $args{code_argv}->(@{ $args{argv} });
last RUN;
}
last RUN if $res->[0] != 200;
( run in 0.735 second using v1.01-cache-2.11-cpan-0b5f733616e )