App-sdview-Output-Tickit
view release on metacpan or search on metacpan
lib/App/sdview/Output/Tickit.pm view on Meta::CPAN
entry will jump directly to it, dismissing the view.
Typing text with the outline view open will filter it to just those headings
matching the typed text. Pressing the C<< <Enter> >> key will jump directly to
the first highlighted heading, again dismissing the view.
=head2 Regexp Searching
Typing into the main search box enters text that forms a (perl) regexp pattern
to be tested against the body text of the document. Each paragraph is tested
individually and all matches are highlighted. Pressing C<< <Enter> >> will
select the first match. Use the C<< <n> >> and C<< <p> >> keys to jump between
them. Press C<< <Escape> >> to clear the highlights. Press C<< <Alt-i> >> to
toggle case-insensitivity. Press C<< <Alt-w> >> to toggle whole-word matching.
=cut
# Override default output format
require App::sdview;
$App::sdview::DEFAULT_OUTPUT = "tickit"
if $App::sdview::DEFAULT_OUTPUT eq "terminal" and -t STDOUT;
my @HIGHLIGHT_PEN = (
fg => 16, # avoid bold-black
bg => "magenta",
b => 1,
);
my @SELECT_PEN = (
bg => "green",
);
field $t;
field $scroller;
field $outlinetree;
field @items;
# Related to searching
field $matchposstatic;
field $matchidx;
field @matches;
ADJUST
{
# Lazy load all the Tickit modules in here
require Tickit;
require Tickit::Utils;
$t = Tickit->new;
$t->term->await_started( 0.050 );
$t->bind_key( q => sub { $t->stop; } );
require Tickit::Widget::Scroller;
Tickit::Widget::Scroller->VERSION( '0.33' );
$scroller = Tickit::Widget::Scroller->new;
$scroller->set_gen_bottom_indicator(
sub ( $scroller ) {
# It feels better for progress if we claim the percentage of ofscreen
# lines that are above the screen.
my $lines_above = $scroller->lines_above;
my $lines_total = $lines_above + $scroller->lines_below;
return "" if $lines_total < 1;
return sprintf( "%d of %d (%d%%)",
$lines_above, $lines_total, 100 * $lines_above / $lines_total );
}
);
# Ugh
$scroller->set_style(
'<Home>' => "scroll_to_top",
'<Space>' => "scroll_down_page",
'<Backspace>' => "scroll_up_page",
'<End>' => "scroll_to_bottom",
'<<>' => "scroll_to_top",
'<>>' => "scroll_to_bottom",
);
$outlinetree = App::sdview::Output::Tickit::_OutlineTree->new;
}
method output ( @paragraphs )
{
require Tickit::Widget::Scroller::Item::Text;
foreach my $para ( @paragraphs ) {
my $code = $self->can( "output_" . ( $para->type =~ s/-/_/gr ) )
or die "TODO: Unhandled paragraph type " . $para->type;
$self->$code( $para );
}
require Tickit::Widget::FloatBox;
$t->set_root_widget( my $fb = Tickit::Widget::FloatBox->new
->set_base_child( $scroller )
);
my $outlinefloat = $fb->add_float(
child => $outlinetree,
hidden => 1, # initially hidden
top => 0, bottom => -1,
left => 0, right => 25, # ideally we want to set "30%" or somesuch here
);
$t->bind_key(
'F9' => sub { $outlinefloat->is_visible ? $outlinefloat->hide : $outlinefloat->show },
);
$t->bind_key(
']' => sub {
my $item = $outlinetree->next_item( +1 );
$scroller->scroll_to( 0, $item->itemidx, 0 ) if $item;
}
);
$t->bind_key(
'[' => sub {
my $item = $outlinetree->current_item;
# Scroll back up to that item if it's not visible
my ( undef, $offscreen ) = $scroller->item2line( $item->itemidx, 0 );
( run in 0.715 second using v1.01-cache-2.11-cpan-39bf76dae61 )