- ...
- select mode (optional, URL mode is used on startup):
- f: file paths
+ - i: IPs
- u: URLs
- ...
- /: search mode
$fh = undef; # a failed open still writes a value to $fh
return;
}
+ $fh->autoflush(1);
}
foreach (@args) {
$_ = $self->encode($_);
}
- say $fh "$module: @args";
+ say $fh "$module: @args" or CORE::die $!;
return;
}
$number = int($number / 10);
} elsif ($char eq "\n"
or $char eq $config->{setting}{alternative_return}) {
- if ($number == 0) { # number without selection matches last entry
- $number = 1;
- }
last;
# Selecting a new mode requires falling through into the main input
return { key => $char };
# All other mappings stay in the current mode.
} elsif (defined (my $m = $config->{mapping}{simple}{$char})) {
- $m->($char, $screen, $config, $input);
+ my $result = $m->($char, $screen, $config, $input);
+ last if defined $result->{select_match};
next;
} else {
$screen->draw_matches($config, $matches, \@remaining);
$screen->refresh;
}
+ # Number without selection matches last entry.
+ if ($number == 0) {
+ $number = 1;
+ }
$screen->draw_matches($config, $matches, []); # remove matches
return {};
}
+sub mapping_paste_now {
+ my ($key, $screen, $config, $input) = @_;
+
+ $screen->debug('mapping_paste_now', 'started');
+
+ $config->{state}{handler} = $config->{handler}{paste};
+
+ return {
+ select_match => 1,
+ };
+}
+
sub mapping_yank {
my ($key, $screen, $config, $input) = @_;
return {};
}
+sub mapping_yank_now {
+ my ($key, $screen, $config, $input) = @_;
+
+ $screen->debug('mapping_yank_now', 'started');
+
+ $config->{state}{handler} = $config->{handler}{yank};
+
+ return {
+ select_match => 1,
+ };
+}
=head2 NORMAL MODES
# Use a temporary file to prevent leaking the yanked data to other users
# with the command line, e.g. ps aux or top.
my ($fh, $tmp) = File::Temp::tempfile(); # dies on its own
- print $fh $screen->encode($match->{value});
+ print $fh $screen->encode($match->{value}) or die $!;
close $fh or die $!;
if ($config->{setting}{multiplexer} eq 'screen') {
# Draw matches in blue.
$config{attribute}{match_string} = color_pair(COLOR_BLUE, -1);
- # Enable Vim-like 'smartcase', ignore case until an upper character is
+ # Draw numbers in bold yellow.
+ $config{attribute}{match_id} = color_pair(COLOR_YELLOW, -1)
+ | A_BOLD;
+ # Disable Vim-like 'smartcase', ignore case until an upper character is
# searched.
- $config{setting}{smartcase} = 1;
+ $config{setting}{smartcase} = 0;
# Use chromium to open URLs if running under X, elinks otherwise.
if (defined $ENV{DISPLAY}) {
$config{setting}{browser} = ['chromium'];
} else {
- $config{setting}{browser} = ['elinks'];
+ $config{setting}{browser} = ['elinks', '-remote'];
}
# Let fcscs know the file was loaded successfully.
I<NOTE>: Mappings are split in two categories: Mode mappings which change the
selection and may receive additional input (e.g. a search string) and simple
-mappings which only change some value. Mode mappings are configured via
+mappings which only change some config value. Mode mappings are configured via
C<$config{mapping}{mode}>, simple mappings via C<$config{mapping}{simple}>.
The following mode mappings are available by default (the function to remap
=item B<p> enable pasting (C<\&mapping_paste>)
+=item B<P> paste current selection (like C<\n> but paste) (C<\&mapping_paste_now>)
+
=item B<y> enable yanking (copying) (C<\&mapping_yank>)
+=item B<Y> yank current selection (like C<\n> but yank) (C<\&mapping_yank_now>)
+
=back
Note that yanking only uses the GNU screen or Tmux paste buffer by default. To
);
my %mapping_simple = (
p => \&mapping_paste,
+ P => \&mapping_paste_now,
y => \&mapping_yank,
+ Y => \&mapping_yank_now,
);
=head2 ATTRIBUTES
mapping_mode_search()
mapping_paste()
+ mapping_paste_now()
mapping_yank()
+ mapping_yank_now()
mapping_quit()
Used as mappings, see L</MAPPINGS> above.
Used as handler to yank, paste selection or open URL in browser.
- debug()
get_regex_matches()
select_match()
run_command()
Example:
- TODO
+ # Enhance URL mode by updating the mapping.
+ $config{mapping}{mode}{u} = sub {
+ my ($key, $screen, $config, $input) = @_;
+
+ # First get matches of normal URL mode.
+ my $result = mapping_mode_url(@_);
+
+ # Add all strings matching "CVE-1234-1234" with URLs pointing to the
+ # Debian security tracker. "->{value}" is the string which is used as
+ # result of the match (e.g. the URL in this case).
+ my @matches = get_regex_matches($input, qr/\b(CVE-\d+-\d+)\b/);
+ foreach (@matches) {
+ $_->{value} = "https://security-tracker.debian.org/$_->{string}";
+ }
+ push @{$result->{matches}}, @matches;
+
+ # Change all YouTube links to use the custom "youtube" handler (see
+ # below). This will allow us to automatically open YouTube URLs with a
+ # custom program, like `youtube-dl` or `mpv`.
+ foreach (@{$result->{matches}}) {
+ if ($_->{string} =~ m{^https://www.youtube.com/}) {
+ $_->{handler} = $config{handler}{youtube};
+ }
+ }
+
+ return $result;
+ }
+ # Also update initial mode to use our new "URL mode".
+ $config{setting}{initial_mode} = $config{mapping}{mode}{u};
+
+ # Special handler to download YouTube URLs with `youtube-dl`. You could
+ # also use `mpv` here to immediately play them.
+ $config{handler}{youtube} = sub {
+ my ($screen, $config, $match) = @_;
+
+ return run_in_background($screen, sub {
+ run_command($screen, ['youtube-dl', $match->{value}]);
+ });
+ };
+
+
=cut
sub mapping_mode_search { return main::mapping_mode_search(@_); }
sub mapping_paste { return main::mapping_paste(@_); }
+ sub mapping_paste_now { return main::mapping_paste_now(@_); }
sub mapping_yank { return main::mapping_yank(@_); }
+ sub mapping_yank_now { return main::mapping_yank_now(@_); }
sub mapping_quit { return main::mapping_quit(@_); }
sub handler_yank { return main::handler_yank(@_); }