X-Git-Url: https://ruderich.org/simon/gitweb/?p=fcscs%2Ffcscs.git;a=blobdiff_plain;f=bin%2Ffcscs;h=42b63db010c192edd6baa14187f14fc94a485742;hp=80c89bfde6f082ecca6ff674f7ee32d87388377c;hb=HEAD;hpb=f256721d6e8a23c7502bba1cec687bdfa16e1355 diff --git a/bin/fcscs b/bin/fcscs index 80c89bf..42b63db 100755 --- a/bin/fcscs +++ b/bin/fcscs @@ -2,7 +2,7 @@ # fcscs - fast curses screen content select -# Copyright (C) 2013-2016 Simon Ruderich +# Copyright (C) 2013-2017 Simon Ruderich # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -44,9 +44,9 @@ B [I] I B is a small tool which allows quick selection of terminal screen contents (like URLs, paths, regex matches, etc.) and passes the selection to -GNU Screen's or Tmux's buffer or any other program. The selection can then -quickly be pasted, e.g. in the shell. Requires GNU Screen or Tmux. It's -licensed under the GPL 3 or later. +GNU Screen's or Tmux's paste buffer or any other program. The selection can +then quickly be pasted, e.g. in the shell. Requires GNU Screen or Tmux to +capture the terminal content. It's licensed under the GPL 3 or later. =head1 OPTIONS @@ -111,7 +111,9 @@ explained below. Per default URLs are selected, see options for a way to change this. I: Opening URLs in the browser passes the URL via the command line which -leaks URLs to other users on the current system via C or C. +might leak URLs to other users on the current system via C or C +(mount C with C on Linux to prevent this information +leakage). I: When yanking (copying) a temporary file is used to pass the data to GNU screen/Tmux without exposing it to C or C. However this may @@ -323,6 +325,39 @@ package Screen { return; } + + sub prompt { + my ($self, %settings) = @_; + + foreach (keys %settings) { + die if not exists $self->{prompt}{$_}; + $self->{prompt}{$_} = $settings{$_}; + } + return; + } + + + sub debug { + my ($self, $module, @args) = @_; + + return if not $self->{debug}; + + state $fh; # only open the file once per run + if (not defined $fh) { + # Ignore errors if the directory doesn't exist. + if (not open $fh, '>', "$ENV{HOME}/.config/fcscs/log") { + $fh = undef; # a failed open still writes a value to $fh + return; + } + $fh->autoflush(1); + } + + foreach (@args) { + $_ = $self->encode($_); + } + say $fh "$module: @args" or die $!; + return; + } sub die { my ($self, @args) = @_; @@ -355,38 +390,6 @@ package Screen { $self->deinit; exit 1; } - sub debug { - my ($self, $module, @args) = @_; - - return if not $self->{debug}; - - state $fh; # only open the file once per run - if (not defined $fh) { - # Ignore errors if the directory doesn't exist. - if (not open $fh, '>', "$ENV{HOME}/.config/fcscs/log") { - $fh = undef; # a failed open still writes a value to $fh - return; - } - $fh->autoflush(1); - } - - foreach (@args) { - $_ = $self->encode($_); - } - say $fh "$module: @args" or CORE::die $!; - return; - } - - - sub prompt { - my ($self, %settings) = @_; - - foreach (keys %settings) { - CORE::die if not exists $self->{prompt}{$_}; - $self->{prompt}{$_} = $settings{$_}; - } - return; - } # Wrapper for Curses. sub width { return $Curses::COLS; } @@ -505,7 +508,7 @@ sub run_in_background { # Necessary for GNU screen or it'll keep the window open until an # external command has run. - require File::Spec; + require File::Spec; # load here to speedup startup my $devnull = File::Spec->devnull(); open STDIN, '<', $devnull or die $!; open STDOUT, '>', $devnull or die $!; @@ -589,7 +592,7 @@ sub select_match { $number = 1; } - $screen->draw_matches($config, $matches, []); # remove matches + $screen->draw_matches($config, $matches, []); # clear matches foreach (@{$matches}) { return { match => $_ } if $_->{id} == $number; @@ -663,7 +666,7 @@ sub extend_match { } elsif ($char eq '$') { # select to end of line extend_match_regex_right($line, $match, qr/.+/); - # Allow mode changes if not overwritten by local mappings. + # Allow mode changes if not overwritten by above mappings. } elsif (defined $config->{mapping}{mode}{$char}) { $screen->draw_matches($config, [$match_old], []); # clear match return { key => $char }; @@ -682,54 +685,43 @@ sub extend_match { } -sub mapping_paste { - my ($key, $screen, $config, $input) = @_; +sub mapping_state_helper { + my ($name, $flags, $key, $screen, $config, $input) = @_; - $screen->debug('mapping_paste', 'started'); + $screen->debug("mapping_$name", 'started'); - $config->{state}{handler} = $config->{handler}{paste}; + $config->{state}{handler} = $config->{handler}{$name}; - $screen->prompt(flags => 'P'); # paste + $screen->prompt(flags => $flags); $screen->draw_prompt($config); $screen->refresh; return {}; } -sub mapping_paste_now { - my ($key, $screen, $config, $input) = @_; +sub mapping_state_now_helper { + my ($name, $key, $screen, $config, $input) = @_; - $screen->debug('mapping_paste_now', 'started'); + $screen->debug("mapping_${name}_now", 'started'); - $config->{state}{handler} = $config->{handler}{paste}; + $config->{state}{handler} = $config->{handler}{$name}; return { select_match => 1, }; } -sub mapping_yank { - my ($key, $screen, $config, $input) = @_; - - $screen->debug('mapping_yank', 'started'); - - $config->{state}{handler} = $config->{handler}{yank}; - - $screen->prompt(flags => 'Y'); # yank - $screen->draw_prompt($config); - $screen->refresh; +sub mapping_paste { + return mapping_state_helper('paste', 'P', @_); +} +sub mapping_paste_now { + return mapping_state_now_helper('paste', @_); +} - return {}; +sub mapping_yank { + return mapping_state_helper('yank', 'Y', @_); } 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, - }; + return mapping_state_now_helper('yank', @_); } @@ -753,29 +745,23 @@ The following normal modes are available: =back =cut -sub mapping_mode_path { - my ($key, $screen, $config, $input) = @_; +sub mapping_mode_helper { + my ($name, $select, $key, $screen, $config, $input) = @_; - $screen->debug('mapping_mode_path', 'started'); + $screen->debug("mapping_mode_$name", 'started'); - my @matches = get_regex_matches($input, $config->{regex}{path}); + my @matches = get_regex_matches($input, $config->{regex}{$name}); return { - select => 'path select', + select => $select, matches => \@matches, - handler => $config->{handler}{path}, + handler => $config->{handler}{$name}, }; } +sub mapping_mode_path { + return mapping_mode_helper('path', 'path select', @_); +} sub mapping_mode_url { - my ($key, $screen, $config, $input) = @_; - - $screen->debug('mapping_mode_url', 'started'); - - my @matches = get_regex_matches($input, $config->{regex}{url}); - return { - select => 'url select', - matches => \@matches, - handler => $config->{handler}{url}, - }; + return mapping_mode_helper('url', 'url select', @_); } sub mapping_mode_ip { my ($key, $screen, $config, $input) = @_; @@ -791,16 +777,7 @@ sub mapping_mode_ip { }; } sub mapping_mode_checksum { - my ($key, $screen, $config, $input) = @_; - - $screen->debug('mapping_mode_checksum', 'started'); - - my @matches = get_regex_matches($input, $config->{regex}{checksum}); - return { - select => 'checksum select', - matches => \@matches, - handler => $config->{handler}{checksum}, - }; + return mapping_mode_helper('checksum', 'checksum select', @_); } =head2 SEARCH MODE (AND EXTEND MODE) @@ -915,7 +892,7 @@ sub handler_yank { $screen->debug('handler_yank', 'started'); - require File::Temp; + require File::Temp; # load here to speedup startup # Use a temporary file to prevent leaking the yanked data to other users # with the command line, e.g. ps aux or top. @@ -970,7 +947,7 @@ sub handler_paste { $screen->debug('handler_paste', 'started'); - require Time::HiRes; + require Time::HiRes; # load here to speedup startup my @cmd; if ($config->{setting}{multiplexer} eq 'screen') { @@ -1013,8 +990,9 @@ sub handler_url { =head1 CONFIGURATION -fcscs is configured through F<~/.fcscsrc> or F<~/.config/fcscs/fcscsrc> which -is a normal Perl script with all of Perl's usual features. +fcscs is configured through F<~/.fcscsrc> (preferred) or +F<~/.config/fcscs/fcscsrc> which is a normal Perl script with all of Perl's +usual features (only loaded if not writable by others). All configuration values are stored in the hash C<%config>. All manually defined keys overwrite the default settings. @@ -1034,8 +1012,8 @@ settings see below): # 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. + # Disable Vim-like 'smartcase' (ignore case until an upper character is + # searched) which is enabled by default. $config{setting}{smartcase} = 0; # Use chromium to open URLs if running under X, elinks otherwise. @@ -1206,7 +1184,7 @@ Defaults in parentheses. =item B start in this mode, must be a valid mode mapping (C<\&mapping_mode_url>) -=item B set multiplexer ("screen" or "tmux") if not autodetected (C) +=item B set multiplexer ("screen" or "tmux"), defaults to autodetection (C) =item B ignore case when searching (C<0>) @@ -1216,7 +1194,7 @@ Defaults in parentheses. =item B sleep x us before running paste command (C<100_000>) -=item B GNU Screen's msgwait variable, used when yanking (C<5>) +=item B GNU Screen's msgwait variable, overwritten with this value when yanking (C<5>) =item B additional accept key like return, set to C<\n> to disable (C) @@ -1367,7 +1345,8 @@ Used as handler to yank, paste selection or open URL in browser. run_command() run_in_background() -Helper functions when writing custom mappings, see the source for details. +Helper functions when writing custom mappings, see the source and example for +details. Example: @@ -1411,8 +1390,6 @@ Example: }); }; - - =cut # All variables and functions which are usable by ~/.fcscsrc. @@ -1642,7 +1619,7 @@ Simon Ruderich Esimon@ruderich.orgE =head1 LICENSE AND COPYRIGHT -Copyright (C) 2013-2016 by Simon Ruderich +Copyright (C) 2013-2017 by Simon Ruderich This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by