X-Git-Url: https://ruderich.org/simon/gitweb/?p=fcscs%2Ffcscs.git;a=blobdiff_plain;f=bin%2Ffcscs;h=e0c8cb1a05d42eb6e38a678311972626c6b1c086;hp=6e3d9cb0ca5800986ed8289fab9162c0f6400029;hb=86557c9811d800c38d24ad1f5c944e75260a57ad;hpb=1ef91de49d5a0337ebdd0254d9da659d7774657f diff --git a/bin/fcscs b/bin/fcscs index 6e3d9cb..e0c8cb1 100755 --- a/bin/fcscs +++ b/bin/fcscs @@ -64,6 +64,7 @@ Short overview of the general usage, details below: - f: file paths - i: IPs - u: URLs + - c: checksums (e.g. MD5, SHA1, ..) - ... - /: search mode - for `normal' modes: @@ -558,9 +559,6 @@ sub select_match { $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 @@ -570,7 +568,8 @@ sub select_match { 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 { @@ -585,6 +584,10 @@ sub select_match { $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 @@ -679,31 +682,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_yank { - my ($key, $screen, $config, $input) = @_; +sub mapping_state_now_helper { + my ($name, $key, $screen, $config, $input) = @_; - $screen->debug('mapping_yank', 'started'); + $screen->debug("mapping_${name}_now", 'started'); - $config->{state}{handler} = $config->{handler}{yank}; + $config->{state}{handler} = $config->{handler}{$name}; - $screen->prompt(flags => 'Y'); # yank - $screen->draw_prompt($config); - $screen->refresh; + return { + select_match => 1, + }; +} - return {}; +sub mapping_paste { + return mapping_state_helper('paste', 'P', @_); +} +sub mapping_paste_now { + return mapping_state_now_helper('paste', @_); +} + +sub mapping_yank { + return mapping_state_helper('yank', 'Y', @_); +} +sub mapping_yank_now { + return mapping_state_now_helper('yank', @_); } @@ -716,38 +731,34 @@ The following normal modes are available: =over 4 -=item B select relative/absolute paths +=item B select relative/absolute paths + +=item B select URLs -=item B select URLs +=item B select IPv4 and IPv6 addresses -=item B select IPv4 and IPv6 addresses +=item B select checksums (MD5, SHA1, SHA256, SHA512) =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}{yank}, + 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) = @_; @@ -762,6 +773,9 @@ sub mapping_mode_ip { handler => $config->{handler}{ip}, }; } +sub mapping_mode_checksum { + return mapping_mode_helper('checksum', 'checksum select', @_); +} =head2 SEARCH MODE (AND EXTEND MODE) @@ -1053,6 +1067,8 @@ them in parentheses): =item B select IPv4 and IPv6 addresses (C<\&mapping_mode_ip>) +=item B select checksums (e.g. MD5, SHA) (C<\&mapping_mode_checksum>) + =item B search for regex to get selection (C<\&mapping_mode_search>) =item B quit fcscs (C<\&mapping_quit>) @@ -1065,8 +1081,12 @@ The following simple mappings are available by default: =item B

enable pasting (C<\&mapping_paste>) +=item B

paste current selection (like C<\n> but paste) (C<\&mapping_paste_now>) + =item B enable yanking (copying) (C<\&mapping_yank>) +=item B 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 @@ -1102,12 +1122,15 @@ my %mapping_mode = ( f => \&mapping_mode_path, u => \&mapping_mode_url, i => \&mapping_mode_ip, + c => \&mapping_mode_checksum, '/' => \&mapping_mode_search, q => \&mapping_quit, ); my %mapping_simple = ( p => \&mapping_paste, + P => \&mapping_paste_now, y => \&mapping_yank, + Y => \&mapping_yank_now, ); =head2 ATTRIBUTES @@ -1157,7 +1180,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>) @@ -1225,6 +1248,8 @@ my %regex = ( # enough. ipv4 => qr!\b(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?:/\d{1,2})?)\b!, ipv6 => qr!\b((?:[0-9a-fA-F]{1,4})?(?::+[0-9a-fA-F]{1,4})+(?:/\d{1,3})?)\b!, + # MD5, SHA1, SHA256, SHA512 + checksum => qr!\b([0-9a-fA-F]{32}|[0-9a-fA-F]{40}|[0-9a-fA-F]{64}|[0-9a-fA-F]{128})\b!, ); =head2 HANDLERS @@ -1235,13 +1260,17 @@ The following handlers are available, defaults in parentheses. =over -=item B used to yank (copy) selection to paste buffer (C<\&handler_yank>) +=item B used to yank (copy) selection to paste buffer (C<\&handler_yank>) + +=item B used to paste selection into window (C<\&handler_paste>) + +=item B used to handle paths (C<\&handler_yank>) -=item B used to paste selection into window (C<\&handler_paste>) +=item B used to open URLs (e.g. in a browser) (C<\&handler_url>) -=item B used to open URLs (e.g. in a browser) (C<\&handler_url>) +=item B used to handle IPs (C<\&handler_yank>) -=item B used to handle IPs (C<\&handler_yank>) +=item B used to handle checksums (C<\&handler_yank>) =back @@ -1262,10 +1291,12 @@ Example: =cut my %handler = ( - yank => \&handler_yank, - paste => \&handler_paste, - url => \&handler_url, - ip => \&handler_yank, + yank => \&handler_yank, + paste => \&handler_paste, + path => \&handler_yank, + url => \&handler_url, + ip => \&handler_yank, + checksum => \&handler_yank, ); my %state = ( @@ -1288,10 +1319,13 @@ Create a new Curses attribute with the given fore- and background color. mapping_mode_path() mapping_mode_url() mapping_mode_ip() + mapping_mode_checksum() mapping_mode_search() mapping_paste() + mapping_paste_now() mapping_yank() + mapping_yank_now() mapping_quit() Used as mappings, see L above. @@ -1307,7 +1341,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: @@ -1337,7 +1372,7 @@ Example: } return $result; - } + }; # Also update initial mode to use our new "URL mode". $config{setting}{initial_mode} = $config{mapping}{mode}{u}; @@ -1351,8 +1386,6 @@ Example: }); }; - - =cut # All variables and functions which are usable by ~/.fcscsrc. @@ -1365,18 +1398,19 @@ package Fcscs { sub mapping_mode_path { return main::mapping_mode_path(@_); } sub mapping_mode_url { return main::mapping_mode_url(@_); } sub mapping_mode_ip { return main::mapping_mode_ip(@_); } + sub mapping_mode_checksum { return main::mapping_mode_checksum(@_); } 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(@_); } sub handler_paste { return main::handler_paste(@_); } sub handler_url { return main::handler_url(@_); } - sub debug { return main::debug(@_); } - sub get_regex_matches { return main::get_regex_matches(@_); } sub select_match { return main::select_match(@_); } @@ -1416,10 +1450,10 @@ package Fcscs { } # Make sure the file is not writable by other users. Doesn't handle # ACLs and see comment above about race conditions. - my @stat = stat $path or die $!; + my @stat = stat $path or $screen->die("Config '$decoded': $!"); my $mode = $stat[2]; if (($mode & Fcntl::S_IWGRP) or ($mode & Fcntl::S_IWOTH)) { - die "Config '$decoded' must not be writable by other users."; + $screen->die("Config '$decoded' must not be writable by other users."); } my $result = do $path;