#!/usr/bin/perl

# .vshnurc - personal extra vshnu reconfiguration file
# Steve Kinzler, steve@kinzler.com, Oct 00
# see website http://kinzler.com/me/vshnu/
# http://kinzler.com/me/home.html#unixcfg

# Many of the scripts and supporting external configurations used via this
# file are available at http://kinzler.com/me/home.html

# Names used only within this vshnurc are placed in the rc:: package.
# This file should be reloadable.

###############################################################################
## Change Log #################################################################

($rc::VNAME, $rc::VERSION, $rc::REQUIRE) = qw(vshnurc 1.0500 1.0500);
&addversions($rc::VNAME, $rc::VERSION);

&err("loaded $rc::VNAME $rc::VERSION requires $cfg::VNAME $rc::REQUIRE",
     "($cfg::VERSION)") if $rc::REQUIRE != $cfg::VERSION;

# 1.0000   7 Nov 2000   Initial public release
# 1.0002   4 Dec 2000   Add 'sleep 1' to /Z command
# 1.0003  13 Dec 2000   Version format x.y.z -> x.0y0z
# 1.0004  25 Jan 2001   Add ReadLine package to ^V command output
# 1.0005  26 Jan 2001   Append "=yes" to "--color"s
# 1.0006  27 Apr 2001   Improve Slashdot interface
# 1.0007  29 May 2001   Add "go perl:" option to G command
# 1.0008  05 Jul 2001   Add "go user:", "webdaily", etc options to G command
# 1.0009   1 Aug 2001   Add "go news:" option to G command
# 1.0010  20 Aug 2001   Update Slashdot interface; Add "hmrccal"; B -> GB
# 1.0011  29 Oct 2001   Add "go movie:" option to G command
# 1.0012  14 Feb 2002   Add "go book:" option to G command
# 1.0100  29 Mar 2002   Add mail, download and print menu to default do entry
# 1.0101   1 Apr 2002   Inherit directory action commands, use ifopt
# 1.0102  26 May 2002   Use "pushmime" instead of "mimeexplode"
# 1.0103  14 Jun 2002   Define $stty_cooked to fix 8-bit characters
# 1.0104   8 Aug 2002   Add P choose command for Palm downloads
# 1.0105  20 Aug 2002   Add "go soft:" option to G command
# 1.0106  18 Nov 2002   Add K command for simple "make"
# 1.0107  17 Dec 2002   Add "go image:" option to G command
# 1.0108   1 Jan 2003   Add "go prod:" option to G command
# 1.0109   3 Mar 2003   Add "go arc:" option to G command
# 1.0110   5 Mar 2003   Add _ choose command for filename whitespace -> _
# 1.0111   1 May 2003   Add browse+remove as edit for _comics_*.html files
# 1.0112  20 May 2003   Add H command for simple "dailyh"
# 1.0113  31 May 2003   Add ReadLine package version to ^V command output
# 1.0114  11 Jun 2003   Full versions support
# 1.0115  19 Jun 2003   Correct $optons reloadability
# 1.0116  27 Jun 2003   Update pilot-file and install-memo usage
# 1.0117   3 Sep 2003   Add "print tumble" option to .ps action menu
# 1.0118  18 May 2004   Revise mailp flags for newer versions
# 1.0119   3 Jun 2004   Add secure remove option to /D command
# 1.0120   4 Jun 2004   Remove special file action and /A (to vshnucfg)
# 1.0121   6 Jun 2004   Add "go city:" option to G command
# 1.0122  15 Sep 2004   Replace AskJeeves with A9 for "go ask:"
# 1.0123  22 Nov 2004   Add `txt2pdbdoc -d` action option for pdb files
# 1.0124  28 Nov 2004   Run ^Y on Y command run in ~/work
# 1.0125  18 Mar 2005   Add &rc::edtags and use for ^K command completions
# 1.0126  18 Mar 2005   Add text view as edit for .doc and .xls files
# 1.0127  11 Apr 2005   Make external reconfig dependent on tcsh/less presence
# 1.0128  14 Apr 2005   Delete pager[ar] config; No color reconfig if ! kinzler
# 1.0129  17 Apr 2005   Add &rccolorlong for getfacls and listacls
# 1.0200  29 Apr 2005   Version normalization
# 1.0201   6 May 2005   Add &hostr
# 1.0202  18 May 2005   Use &mapadd for typemap and keymap additions
# 1.0203   2 Jun 2005   Add "go info:" option to G command
# 1.0204   8 Jul 2005   Add "go yub:" option to G command
# 1.0205  24 Oct 2005   Undef $mailbox
# 1.0206   4 Dec 2005   Use &opton vs $optons to fix description bug
# 1.0207  28 Dec 2005   Add ^S command for copying chosen set
# 1.0208  28 Dec 2005   Use &mapget and &mapset for typemap changes
# 1.0209  28 Jan 2006   Use &ext and &Ext
# 1.0210   9 Feb 2006   Add "go video:" option to G command
# 1.0211  24 Mar 2006   Add @ command for atls; Use pager with z file actions
# 1.0212  30 Mar 2006   Add "go map:" and "go phone:" options to G command
# 1.0213   6 Apr 2006   Rename $cfg::pager* to $pager*
# 1.0214   8 Apr 2006   Use &run and special ext syntax
# 1.0215  23 Apr 2006   Move ^ command to W
# 1.0216  14 Feb 2007   Use/Add "$cfg::mailer -f" for mailbox actions
# 1.0217   6 Mar 2007   Add "go cpan:" option to G command
# 1.0218  15 Apr 2007   Use new screen zones in mousemaps
# 1.0219  12 Jun 2007   Enhance ^S command for rcp and X cut buffer usage
# 1.0220  13 Jun 2007   Use $cfg::xcb and &cfg::xpaste
# 1.0300   8 Jul 2007   Version normalization
# 1.0301  15 Jul 2007   Use enhanced &mapadd $before argument syntax
# 1.0302  21 Feb 2008   Add @rc::faves and 7 command
# 1.0303  30 May 2008   Add > option to ^S command; Revise @rc::ring
# 1.0304  26 Jun 2008   Add ` command for today
# 1.0305   9 Jul 2008   Use duplex $PRINTERs vs psduplex; Add tumble everywhere
# 1.0306   2 Sep 2008   Add "webdaily Mon" option to G command
# 1.0307  26 May 2008   Replace getfacls and listacls with lsacl
# 1.0308  27 May 2008   Add C command for `chmod +r *`
# 1.0309  21 Jul 2009   Add `korganizer` action for ics files
# 1.0310  14 Sep 2009   Add "go auct:" option to G command
# 1.0311  22 Sep 2009   Add information listing as edit for binary image files
# 1.0312   9 Nov 2009   Add text view as edit for .doc.gz and .xls.gz files
# 1.0313  20 Dec 2009   Change P command to `whichpkg` listing with coloring
# 1.0314   9 Mar 2010   Use `pdbdump` instead of `pilot-file -d`
# 1.0315  23 Mar 2010   Use `evince` as PostScript viewer vs `ghostview`
# 1.0316   8 Jan 2011   Use $dotdotdot and &cfg::onecmd
# 1.0317  11 Jan 2011   Add ~/tmp to @rc::ring on $MAILHOST*
# 1.0318  14 Feb 2011   Add "go en:" and "go es:" options to G command
# 1.0319  22 Jul 2011   Use `office` instead of `libreoffice`
# 1.0320  25 Jul 2011   Display images with `xv` and ics files with `evolution`
# 1.0321  21 Sep 2011   Change P choose command to mount-related menu
# 1.0322  24 Oct 2011   Add text view as edit for .docx and .docx.gz files
# 1.0323  21 Nov 2011   Add text view as edit for .xlsx and .xlsx.gz files
# 1.0324  22 Nov 2011   Use `zzcat` to generalize text views as edits
# 1.0325  29 Nov 2011   Add "go and:" option to G command
# 1.0326   4 May 2012   Add "go cover:" option to G command
# 1.0327   7 May 2012   Add play/info/edit/to_ogg action set for mp3 files
# 1.0328  11 Jun 2012   Add backburner action for problems mailboxes
# 1.0329   6 Aug 2012   Add `comix` action for .cbr and .cbz files
# 1.0330   7 Aug 2012   Add `fbreader` action for .epub and .fb2 files
# 1.0331   3 Dec 2012   Add "go priv:" option to G command
# 1.0332  30 Dec 2012   Add "go dir:" option to G command
# 1.0333   5 Jan 2012   Add "go cache:" option to G command; Remove "hmrccal"
# 1.0334   5 Jan 2012   Add play/extract action set for mp4 files
# 1.0336  17 Jul 2013   Add "go proxy:" option to G command; comment out yubnub
# 1.0337  20 Oct 2013   Add google drive mounting options to P choose command
# 1.0338  14 Dec 2013   Add D command for fdupes
# 1.0339  21 Dec 2013   Use `webdaily ALL -v` in G command
# 1.0340   1 Jan 2014   Add `iotop` to T command (though may need root)
# 1.0341   1 Jan 2014   Add M choose command for metadata listing
# 1.0342   1 Feb 2014   Add ~/tmp to @rc::ring on all hosts
# 1.0343  29 Mar 2014   Add ^X command for an empty display and use in $getch
# 1.0344   5 Apr 2014   Add %nobag to map unassigned bag keys to uppercase acts
# 1.0345  20 Apr 2014   Add `htop` option with `top`
# 1.0346  31 May 2014   Use $ENSCRARGS and $rc::enscript in enscript commands
# 1.0347  11 Feb 2015   Add 'edit audio' action for mp3 files
# 1.0348  19 Feb 2015   Add install deb and extract options for rpm files
# 1.0349  20 Mar 2015   Add "auth" option to G command
# 1.0350   2 Apr 2015   Use `mp42mp3` not `soundconverter` for mp4 extracts
# 1.0351  21 Apr 2015   Add `dailyh -P` action to H command
# 1.0352   7 May 2015   Add text view as edit for .odt, .ott and .ods files
# 1.0353  14 Sep 2015   Use $SU_CLASS to determine $co_decor
# 1.0354   4 Nov 2015   Add metadata erasing options to M choose command
# 1.0355  28 Nov 2015   Set $co_decor to on_blue explicitly for kinzler
# 1.0356  10 Dec 2015   Enable $disksgvfs for user gvfs mounts in disks list
# 1.0357  11 Jan 2016   Add `crontab -l` to @ command output
# 1.0400  12 Feb 2016   Version normalization
# 1.0401  12 Feb 2016   Uppercase $rc::vname, version and require variables
# 1.0402  22 Apr 2016   Add color printing option to print menus
# 1.0403  10 May 2016   Change Slashdot interface to dailypages
# 1.0404  18 May 2016   Add proctree options to J command
# 1.0404  29 May 2016   Add fewer-pass options for srm removes
# 1.0405   7 Sep 2016   Use &run 2 flag in various commands
# 1.0406  28 Sep 2016   Add security context long listing into A command
# 1.0407  28 Sep 2016   Add `certinfo -K` option to Q command
# 1.0408   7 Dec 2016   Add `certinfo -s` option to Q command
# 1.0409  26 Dec 2016   Add `img2txt` into binary image information listing
# 1.0410  30 Jan 2017   Use `certinfo -t` for all certificate files
# 1.0411  20 Feb 2017   Add $rc::prefaves
# 1.0412  16 Jun 2017   Add "go app:" option to G command and tweak some others
# 1.0413  17 Nov 2017   Change $co_color for usual to black on_green
# 1.0414  25 Feb 2019   Add /etc/systemd/system to faves
# 1.0415  21 May 2019   Add text view as edit for .msg files
# 1.0500  25 Aug 2019   Version normalization

###############################################################################
## External reconfiguration ###################################################

$mailbox = undef;

`tcsh -f /dev/null`;
$shell = 'tcsh' unless $?;              # for use by &shell

$stty_cooked = '-istrip';               # corrections to `stty -raw echo`

sub hostr { local $_ = shift; s/^ukinzler\b.*/$ENV{UH}/is; $_ }

###############################################################################
## Color reconfiguration ######################################################

if ($color && getpwnam('kinzler')) {
        $co_decor = ($user eq 'kinzler')          ? 'on_blue'    :
                    ($ENV{'SU_CLASS'} eq 'other') ? 'on_magenta' :
                                                    'black on_green' if $>;
        delete $co_user{$user}, @co_user{'kinzler', 'oracle',  'uoracle'} =
                                        ('blue',    'magenta', 'magenta');
}

###############################################################################
## General reconfiguration ####################################################

$disksgvfs = 1;                         # add user gvfs mounts to disks list
$dotdotdot = "\267";                    # ISO 8859-1 Middle dot

$getch = "\cX" if $scr->{ROWS} <= 5;    # personal pref for console windows

%nobag = ('' => 'keymapcmd($_, "\u$key")');

###############################################################################
## Typemap reconfiguration ####################################################

&mapset('typemap_', '', 'run -s= $cfg::editor', 0);

$rc::Ext_mbox  = (grep(/mbox/, @typemap_do))[0];
$rc::Ext__mbox = '/(^|\/)#?_(|[^_].*\.)mbox$/';
$rc::probmbox  = '/(^|\/)_problems.mbox$/';

&mapset('typemap_do', $rc::Ext_mbox,
         ['run -s_ "$cfg::mailer -f"', 'run the mailer on this mbox file']);
&mapadd('typemap_',   $rc::Ext__mbox, &mapget('typemap_do', $rc::Ext_mbox));
&mapadd('typemap_do', $rc::Ext__mbox, &mapget('typemap_', ''), $rc::Ext_mbox);
&mapadd('typemap_',   $rc::probmbox,
         ['run -s_ "$cfg::mailer -f"; point("-\$"), run("-X", "qq") if ! -s',
          'run the mailer on this problems mailbox'], $rc::Ext__mbox);
&mapadd('typemap_do', $rc::probmbox,
         ['run "catrm $_q >> ~/l/mail/_problems2.mbox"; typemap "*do"',
          'backburner this problems mailbox'],        $rc::Ext__mbox);

$rc::zzext = '(\.([gl]?z|bz2))?';

&mapadd('typemap_', '/(^|\/)_comics_[^\/]*\.html?$/',
         ['sh "$ENV{HTMLVIEW} < $_q"; remove $_; win',
          'browse and remove this HTML file']);
&mapadd('typemap_', 'ext bmp gif ico jpe?g p[bgnp]m pcx png svg tiff?',
         ['run -g "(img2txt -W " . ($scr->{COLS} - 1) . " -- $_q;"
                . " identify -verbose -- $_q)"',
          'view information about this image file']);
&mapadd('typemap_', 'ext do[ct]' . $rc::zzext,
         ['run -p "zzcat $_q | doc2txt -"',
          'view a text version of this Word file']);
&mapadd('typemap_', 'ext docx' . $rc::zzext,
         ['run -p "zzcat $_q | docx2txt - -"',
          'view a text version of this Word-X file']);
&mapadd('typemap_', 'ext msg',
         ['run -p "msgconvert --outfile - $_q | tr -d \\r"',
          'view a text version of this Outlook email file']);
&mapadd('typemap_', 'ext o[dt]t ods',
         ['run -_p "odt2txt"',
          'view a text version of this OpenDocument file']);
&mapadd('typemap_', 'ext xls' . $rc::zzext,
         ['run -p "zzcat $_q | xls2tsv"',
          'view a text version of this Excel file']);
&mapadd('typemap_', 'ext xls[xm]' . $rc::zzext,
         ['run -pr "zzcat $_q | ' .
                   'ssconvert -T Gnumeric_stf:stf_csv fd://0 fd://1"',
          'view a text version of this Excel-X file']);

${&mapget('typemap_do', '-d _', 0)}[0] .= ', ifopt("C", "--color")';
&mapadd('typemap_do', 'ext mp3',
        [[${$typemap_do{(grep(/ asf /, @typemap_do))[0]}}[0],
          'play this MP3 file',                 'pP',   'play'],
         ['run -s=r "eyeD3", "-v"',
          'show the ID3 tags of this MP3 file', 'iI',   'info'],
         ['run -x_ "easytag"',
          'edit the ID3 tags of this MP3 file', 'tT',   'edit tags'],
         ['run -x_ "audacity"',
          'edit the audio of this MP3 file',    'aAeE', 'edit audio'],
         ['run -_r "mp32ogg"',
          'convert this MP3 file to Ogg',       'oOcC', 'to ogg']],
        (grep(/ asf /, @typemap_do))[0]);
&mapadd('typemap_do', 'ext mp4',
        [[${$typemap_do{(grep(/ asf /, @typemap_do))[0]}}[0],
          'play this MP4 file',                   'pP',  'play'],
         ['run -_R "mp42mp3"',
          'extract MP3 audio from this MP4 file', 'xX3', 'to mp3']],
        (grep(/ asf /, @typemap_do))[0]);
${&mapget('typemap_do', (grep(/ bmp /, @typemap_do))[0])}[0] = 'run -x_ "xv"';
&mapset('typemap_do', (grep(/ csv /, @typemap_do))[0],
         ['run -x_ "office"', 'load this file into Office']);
&mapadd('typemap_do', 'ext cbr cbz',
         ['run -x= "comix"', 'display this comics file'], 'Ext crl');
&mapset('typemap_do', 'ext e?ps', sub { my $c =
         ['run -x= "evince"',
          'display this PostScript file',           'vVgG',  'view'];
        &cfg::onecmd() ? $c : [$c,
         ['run -s_r "lpr", "-h", "-P$ENV{PRINTER1}"',
          'print this PostScript file',             'pPlL',  'print'],
         ['run -s_r "lpr", "-h", "-P$ENV{PRINTER2}"',
          'print this PostScript file duplex',      'd',     'print duplex'],
         ['run -s_r "lpr", "-h", "-P$ENV{PRINTERT}"',
          'print this PostScript file tumble',      't',     'print tumble'],
         ['run -s_r "lpr", "-h", "-P$ENV{PRINTERC}"',
          'print this PostScript file color',       'c',     'print color'],
         ['run -sr "psnup -n 2 $_q | lpr -h -P$ENV{PRINTER1}"',
          'print this PostScript file 2-up',        '2rRnN', 'print 2-up'],
         ['run -sr "psnup -n 2 $_q | lpr -h -P$ENV{PRINTER2}"',
          'print this PostScript file duplex 2-up', 'D',  'print duplex 2-up'],
         ['run -sr "psnup -n 2 $_q | lpr -h -P$ENV{PRINTERT}"',
          'print this PostScript file tumble 2-up', 'T',  'print tumble 2-up'],
         ['run -sr "psnup -n 2 $_q | lpr -h -P$ENV{PRINTERC}"',
          'print this PostScript file color 2-up',  'C',  'print color']]
        });
&mapadd('typemap_do', 'ext epub fb2',
         ['run -x_ "fbreader"', 'display this ebook file'], 'Ext fig');
&mapadd('typemap_do', 'Ext err',
         ['run -s_ $cfg::editor, "-q"',
          'quickfix edit based on this error file'], 'Ext fig');
&mapadd('typemap_do', 'ext html?',
         ['run -s_w "$ENV{HTMLVIEW} <"',
          'browse this HTML file'], 'ext iso');
&mapadd('typemap_do', 'Ext ics',
         ['run -x= "evolution"', 'display this calendar file'], 'ext iso');
&mapadd('typemap_do', 'ext pdb',
        [['run -=p "+palm; txt2pdbdoc -d"',
          'read this Palm Doc file',       'rRtT', 'read'],
#        ['run -=p "+palm; pilot-file -d"',
         ['run -_p "+palm; pdbdump"',
          'view a dump of this Palm file', 'vVfF', 'view'],
         ['run -_R "+palm; exec pilot-xfer -i"',
          'download this file to a Palm',  'dDxX', 'download']], '>Ext o');
&mapadd('typemap_do', 'ext prc pqa',
        [@{&mapget('typemap_do', 'ext pdb')}[0, 1]], '>Ext o');
&mapset('typemap_do', 'Ext rpm', [@{&mapget('typemap_do', 'Ext rpm')},
         ['run -s=r "alien", "-i"',
          'install this RPM package as a Debian package',
                                      'dD',   'install deb'],
         ['run -sR "rpm2cpio $_q | cpio -idmv"',
          'extract this RPM package', 'xXeE', 'extract']]);
&mapadd('typemap_do', 'Ext url?',
         ['run -s_w "xrshio - webrowse -mw <"',
          'browse this URL file marked up'], 'Ext uu');
&mapadd('typemap_do', '/(^|\/)known_hosts$/',
         ['run -s_2p "ssh-keygen -lvf"',
          'view the fingerprints of these keys'], '/(^|\/)Imakefile$/');
${&mapget('typemap_do', '/[Mm]akefile/')}[0] =~ s/"make /"mak /;
${&mapget('typemap_do', 'Ext Z'        )}[0] =~ s/P/p/;
${&mapget('typemap_do', 'Ext bz2'      )}[0] =~ s/P/p/;
${&mapget('typemap_do', 'Ext g?z'      )}[0] =~ s/P/p/;
&mapset('typemap_do', '',
        [['run -s= $pager',
          'view this file',                   'vV',   'view'],
         ['run -s_ "$cfg::mailer -f"',
          'run the mailer on this mailbox',   'mM',   'view mailbox'],
         ['run -s_R "sendfile"',
          'mail this message file',           'sS',   'send mail'],
         ['run -sR "$rc::enscript -p- -- $_q | lpr -h -P$ENV{PRINTER1}"',
          'print this text file',             'pl',   'print'],
         ['run -sR "$rc::enscript -p- -- $_q | lpr -h -P$ENV{PRINTER2}"',
          'print this text file duplex',      'd',    'print duplex'],
         ['run -sR "$rc::enscript -p- -- $_q | lpr -h -P$ENV{PRINTERT}"',
          'print this text file tumble',      't',    'print tumble'],
         ['run -sR "$rc::enscript -p- -- $_q | lpr -h -P$ENV{PRINTERC}"',
          'print this text file color',       't',    'print color'],
         ['run -sR "$rc::enscript -2r -p- -- $_q | lpr -h -P$ENV{PRINTER1}"',
          'print this text file 2-up',        '2rn',  'print 2-up'],
         ['run -sR "$rc::enscript -2r -p- -- $_q | lpr -h -P$ENV{PRINTER2}"',
          'print this text file duplex 2-up', 'D',    'print duplex 2-up'],
         ['run -sR "$rc::enscript -2r -p- -- $_q | lpr -h -P$ENV{PRINTERT}"',
          'print this text file tumble 2-up', 'T',    'print tumble 2-up'],
         ['run -sR "$rc::enscript -2r -p- -- $_q | lpr -h -P$ENV{PRINTERC}"',
          'print this text file color 2-up',  'T',    'print color 2-up'],
         ['run -s=R "mailp", "-from", "-noburstpage"',
          'print this mail file',             'PL',   'print mail'],
         ['run -s=R "mailp", "-from", "-landscape", "-noburstpage"',
          'print this mail file 2-up',        'RN',   'print mail 2-up']]);

&mapadd('typemap_do', join(' ', 'Ext', map { "$_(|[-._].*)" }
                                           qw/crl cer crt pem csr key prm/),
         ['run -s_2p "certinfo -t"', 'view this certificate file'], 'Ext crl');
&mapdel('typemap_do', 'Ext crl');
&mapdel('typemap_do', 'Ext cer crt pem');
&mapdel('typemap_do', 'Ext csr');
&mapdel('typemap_do', 'Ext key');
&mapdel('typemap_do', 'Ext prm');

$rc::enscript = 'enscript' . ($ENV{'ENSCRARGS'} ? " $ENV{'ENSCRARGS'}" : '');

###############################################################################
## Main keymap reconfiguration ################################################

$cfg::quemarkmsg = '';

@rc::ring = ('cd "~/tmp"; win',
             (! grep($ENV{'HOST'} eq $_, @ENV{'SH', 'MH'})) ? () :
                ('cd "/l/picons/ftp/incoming"; win',
                 'cd("~oracle/post") ? longls("-win", 1) : win'),
             'cd "~/work"; win');

$rc::prefaves = 'cd /media && make -s';
@rc::faves    = ('/etc/systemd/system',
                 </media/*>, </mnt/*>, </run/user/*/*/*:*>);
                 # Warning: the <>'s above can hang if there's system problems

&mapadd('keymap_', "\cK",
         ['setcomplete \&rc::edtags;'
          . ' run "-s/", $cfg::editor, "-t", get "Tag:"',
          'edit in the file for the given tag'], "\cL");
$keymap_{"\cL"}[0] = 'point "-\$"; winch';
unshift(@{$keymap_{"\cQ"}},
         ['do $vshnurc; err $@; win', 'reload just the personal rc file '
          . '($vshnurc)', "rR\cR", 'load $vshnurc'])
                unless $keymap_{"\cQ"}[0][2] =~ /r/i;
&mapadd('keymap_', "\cS",       # Warning: scp not robust wrt quoting & no -i
        [['run -ru "gnu cp -axi --", quote(@choose), "."',
          'copy the chosen set to the current directory',
          '.', 'cp chosen .'],
         ['run -r "$ENV{RCPCMD} -r --", quote(split(/\n/, cfg::xpaste)), "."',
          'remote copy X cut buffer $cfg::xcb lines to the current directory',
          'x', 'rcp Xcutbuf$cfg::xcb .'],
         ['run -ru "$ENV{RCPCMD} -r --", quote(@choose, cfg::xpaste)',
          'remote copy the chosen set to X cut buffer $cfg::xcb',
          'X', 'rcp chosen Xcutbuf$cfg::xcb'],
         ['run -ru "$ENV{RCPCMD} -r --", quote($point, cfg::xpaste)',
          'remote copy the point file to X cut buffer $cfg::xcb',
          '>', 'rcp point Xcutbuf$cfg::xcb']], "\cT");
&mapadd('keymap_', "\cX",
         ['altls \@rc::empty, ""; win',
          'switch to/from an empty display'], "\cW");
&mapadd('keymap_', ",",
         ['evalnext \@rc::ring', 'cycle to monitored directories'], "-");
&mapadd('keymap_', "7",
         ['system $rc::prefaves; altls \@rc::faves, "Favorites"; win',
          'switch to/from the favorites display'], "8");
&mapadd('keymap_', "@",
         ['run -p "(atls -#; crontab -l)"',
          'view the scheduled at and cron jobs'], "B");
&mapadd('keymap_', "A",
         ['cfg::longls2 ["lsacl"], ["ls", ifopt("L"), "-d --scontext --"]',
          'long list files with their ACL info or security context'], "B");
&mapadd('keymap_', "C",
         ['run -sL "chmod +r *"', 'run `chmod +r *`'], ">B");
&mapadd('keymap_', "D",
        [['run -s2P "fdupes", "-S", "-n", ifopt("L", "-s"), "."',
          'find duplicate files in the current directory',
          '.*', 'non-recursive'],
         ['run -s2P "fdupes", "-S", "-n", ifopt("L", "-s"), "-r", "."',
          'find duplicate files in the current directory recursively',
          'rR', 'recursive']], ">C");
&mapadd('keymap_', "G",
        [['run getcmd "go"',
          'browse the URL guessed from the given piece(s)',
          'gG',   'url pieces'],
         ['run -s "go", "url:" . gets "Go URL:"',
          'browse the given URL',
          'uUkK', 'url'],
         ['run -s "go", "proxy:" . gets "Go Proxy URL:"',
          'browse the given URL via a proxy',
          'x',    'url proxy (Google proxy)'],
         ['run -s "go", "info:" . gets "Go Info URL:"',
          'browse the information about the given URL',
          'iI',   'url info (Google Info)'],
         ['run -s "go", "cache:" . gets "Go Cache URL:"',
          'browse the cached version of the given URL',
          'c',    'url cache (Google cache)'],
         ['run -s "go", "arc:" . gets "Go Archive URL:"',
          'browse historical versions of the given URL',
          'vV',   'url versions (Wayback)'],
         ['run -s "auth", "-b", gets "Go Site:"',
          'browse the results for the given login site query',
          'lL',   'login'],
         ['run -s "grepbm", "-b", "-i", "--", gets "Go Regexp:"',
          'browse the matched browser bookmarks',
          'bB',   'bookmarks'],
#        ['run -s "go", "yub:" . gets "Go YubNub:"',
#         'browse the results for the given yubnub command',
#         'yY',   'yubnub'],
         ['run -s "go", "search:" . gets "Go Search:"',
          'browse the results for the given web search query',
          's',    'search (Google)'],
         ['run -s "go", "priv:" . gets "Go Private:"',
          'browse the results for the given private web search query',
          'S',    'private (DuckDuckGo)'],
         ['run -s "go", "image:" . gets "Go Image:"',
          'browse the results for the given web image search query',
          '@',    'image (Google Images)'],
         ['run -s "go", "video:" . gets "Go Video:"',
          'browse the results for the given web video search query',
          '%',    'video (Google Video)'],
         ['run -s "go", "map:" . gets "Go Map:"',
          'browse the results for the given map location query',
          '^',    'map (Google Maps)'],
         ['run -s "go", "dir:" . gets "Go Directions:"',
          'browse the results for the given map directions query',
          '_',    'directions (Google Maps)'],
         ['run -s "go", "news:" . gets "Go News:"',
          'browse the results for the given usenet search query',
          'nN',   'news (Google Groups)'],
         ['run -s "go", "ask:" . gets "Go Ask:"',
          'browse the matches for the given question',
          '?',    'ask (Ask)'],
         ['run -s "go", "topic:" . gets "Go Topic:"',
          'browse the matches for the given topic',
          'tT',   'topic (Yahoo)'],
         ['run -s "go", "encyc:" . gets "Go Encyclopedia:"',
          'browse the results for the given encyclopedia query',
          'eE',   'encyclopedia (Wikipedia)'],
         ['run -s "go", "word:" . gets "Go Word:"',
          'browse the results for the given dictionary query',
          'wW',   'word (Dictionary)'],
         ['run -s "go", "en:" . gets "Go English:"',
          'browse the results for the given English translation',
          '<',    'english (Google Translate)'],
         ['run -s "go", "es:" . gets "Go Spanish:"',
          'browse the results for the given Spanish translation',
          '>',    'spanish (Google Translate)'],
         ['run -s "go", "perl:" . gets "Go Perl:"',
          'browse the results for the given perl documentation query',
          'p',    'perl (Perldoc)'],
         ['run -s "go", "cpan:" . gets "Go CPAN:"',
          'browse the results for the given CPAN module query',
          'P',    'cpan'],
         ['run -s "go", "user:" . gets "Go User:"',
          'browse the results for the given user directory query',
          'hH',   'user (U-M Directory)'],
         ['run -s "go", "phone:" . gets "Go Phonebook:"',
          'browse the results for the given phonebook query',
          '#',    'phone (Google PhoneBook)'],
         ['run -s "go", "city:" . gets "Go City:"',
          'browse the results for the given city map query',
          'C',    'city (City-Data)'],
         ['run -s "go", "book:" . gets "Go Book:"',
          'browse the results for the given bookstore query',
          'zZ',   'book (Amazon)'],
         ['run -s "go", "movie:" . gets "Go Movie:"',
          'browse the results for the given movie database query',
          'mM',   'movie (Netflix)'],
         ['run -s "go", do{ $cwd =~ /.*\/([^\/]+)\/([^\/]*)/; "cover:$1 $2" }',
          'browse the results for the cover art database query'
          . ' for this directory',
          '[]',   'cover (Albumart)'],
         ['run -s "go", "soft:" . gets "Go Software:"',
          'browse the results for the given software archive query',
          'X',    'software (Freecode)'],
         ['run -s "go", "-a", "app:" . gets "Go Application:"',
          'browse the results for the given application query',
          'a',    'application (UM-HITS PlatServ)'],
         ['run -s "go", "and:" . gets "Go App:"',
          'browse the results for the given Android app query',
          'A',    'app (Android Market)'],
         ['run -s "go", "prod:" . gets "Go Product:"',
          'browse the results for the given product search query',
          '$',   'product (Google Products)'],
         ['run -s "go", "auct:" . gets "Go Auction:"',
          'browse the results for the given auction search query',
          '4',   'auction (eBay)'],
         ['run -s "webrowse", "-w", getfile("Go File (.):") || $cwd',
          'browse the given file or directory (default current directory)',
          'fF',   'file (default current directory)'],
#        ['run -s "slashdot"',              'browse the Slashdot website',
#         '/.'],
         ['run -s "go", "kinzler", "me/daily.html"',
                                            'browse my dailypage',
          '/.'],
         ['run -s "webdaily", "-v"',        'browse my daily web pages',
          'D'],
         ['run -s "webdaily", "ALL", "-v"', 'browse all my daily web pages',
          '*8'],
         ['run -s "webdaily", "Mon", "-v"', 'browse my weekly web pages',
          'd']], ">F");
&mapadd('keymap_', "H",
        [['run -sr "dailyh"',    'update my home directory', 'hHdD', 'dailyh'],
         ['run -sr "dailyh -P"', 'push back mboxes', 'pPmM#', 'dailyh -P']],
        ">G");
&mapadd('keymap_', "J",
        [['run -s2p "snaps -u"',
          "list the user's current processes",         'ujJ','user'],
         ['run -s2p "snaps -s -l"',
          'list all system processes',                 's',  'system'],
         ['run -s2p "pstree -alp $user"',
          "pstree list the user's current processes",  'U','user pstree'],
         ['run -s2p "pstree -alp"',
          'pstree list all system processes',          'S','system pstree'],
         ['run -s2p "proctree -aTu $user"',
          "proctree list the user's current processes",'V','user proctree'],
         ['run -s2p "proctree -aT"',
          'proctree list all system processes',        'T','system proctree']],
        ">H");
&mapadd('keymap_', "K",
         ['run -sr "make";'
          . ' $cwd eq untilde("~oracle/post") && longls("-win", 1)',
          'run `make`'], ">J");
$keymap_{"M"}[0] =~ s/"make"/"mak"/;
#&mapadd('keymap_', "N",
#        ['run -s "nn"', 'run `nn`'], ">M");
&mapadd('keymap_', "N", $keymap_{"\cI"}, ">M"); # for Tab-less kbds eg Kindle
$keymap_{"P"} =
         ['longls "-win", "whichpkg"',
          'long list files with their owning package'];
$keymap_{"Q"} =
        [['longls "-win", q(CERTINFO_OPENSSL_ARGS="-passin pass:dunno" )
                        .  "certinfo -s \@_ 2>&1"',
          'long list files with a summary of their certificate information',
                            'cCsS', 'certinfo'],
         ['longls "-win", q(CERTINFO_OPENSSL_ARGS="-passin pass:dunno" )
                        .  "certinfo -K 2>&1"',
          'long list files with the beginning of their certificate key',
                            'kK',   'certinfo key'],
         [@{$keymap_{"Q"}}, '? ',   'prompt']];
$keymap_{"T"} =
        [['run "top"',   'monitor system processes',       'tTpP', 'top'],
         ['run "htop"',  'interact with system processes', 'hH',   'htop'],
         ['run "iotop"', 'monitor system I/O',             'iIoO', 'i/o']];
&mapadd('keymap_', "W",
         ['cd($> && $user ne "kinzler" ? "~$user" : "~/work");'
          . ' point "-\$"; win',
          "cd to the user's working directory"], "X");
$keymap_{"Y"}[0] .= '; $cwd eq untilde("~/work") && msg filecount';
$keymap_{"`"}[0] =~ s/r "cal -3/g "today/;

###############################################################################
## "Choose" keymap reconfiguration ############################################

&mapadd('keymap_choose', "<",
         ['run -s+ruk "pushmime"',
          'explode the chosen mail messages/folders into directories'], ">;");
$keymap_choose{"D"}    =
        [['run -#buk "rm -r"',
          'recursively remove the chosen files/directories (background)',
          'dDrR', 'recursive remove'],
         ['run -#buk "srm -rs"', '1-pass'
          . ' recursively remove the chosen files/directories (background)',
          '1',    '1-pass recursive remove'],
         ['run -#buk "srm -rE"', '3-pass'
          . ' recursively remove the chosen files/directories (background)',
          '3',    '3-pass recursive remove'],
         ['run -#buk "srm -rD"', '7-pass'
          . ' recursively remove the chosen files/directories (background)',
          '7',    '7-pass recursive remove'],
         ['run -#buk "srm -r"',  '35-pass'
          . ' recursively remove the chosen files/directories (background)',
          'sS',   '35-pass recursive remove']];
$keymap_choose{"E"}[0] = 'run -s#uk $cfg::editor';
$keymap_choose{"I"}[0] = 'run -x+uk "xv"';
&mapadd('keymap_choose', "J",
         ['run -sruk "push", "--", @choose, getfile "Directory:"',
          'push the chosen files into the given directory'], ">I");
&mapadd('keymap_choose', "K",
         ['run -s#ruk "pop"', 'pop files out of the chosen directories'],">J");
&mapadd('keymap_choose', "M",
        [['run -puk "exiftool -a -u -g1", quote(@choose),'
          . ' q(| sed "s/^==*/########/")',
          'list the metadata of the chosen files',
          'lLmM', 'list metadata'],
         ['run -+ruk qw(exiftool -geotag= -P -overwrite_original)',
          'erase the geotag metadata of the chosen files',
          'gG',   'erase geotags'],
         ['run -+ruk qw(exiftool -all= -P -overwrite_original)',
          'erase all the metadata of the chosen files',
          'eE',   'erase metadata']], ">K");
#&mapadd('keymap_choose', "P",
#        ['run -+Cuk "+palm; exec pilot-xfer -i"',
#         'download the chosen files to a Palm'], "R");
&mapadd('keymap_choose', "P",
        [[&cfg::mapchoose('run "-sn", "mount", absfile $_'),
          'mount the chosen directories',        'mM', 'mount'],
         [&cfg::mapchoose('run "-sn", "sshfs", "-o", "idmap=user",'
          . ' gets("Ssh Directory:"), absfile $_'),
          'ssh mount the chosen directories',    'sS', 'ssh mount'],
         ['run "-s", "google-drive-ocamlfuse"', # www.ubuntugeek.com/?p=14521
          'initialize google mounting',          'iI', 'google init'],
         [&cfg::mapchoose('run "-sn", "google-drive-ocamlfuse", absfile $_'),
          'google mount the chosen directories', 'gG', 'google mount'],
         [&cfg::mapchoose('run "-sn", "unmount", absfile $_'),
          'unmount the chosen directories',      'uU', 'unmount'],
         [&cfg::mapchoose('run "-sn", "fusermount", "-u", absfile $_'),
          'fuse unmount the chosen directories', 'fF', 'fuse unmount'],
         [&cfg::mapchoose('run "-sn", "eject", absfile $_'),
          'eject the chosen directories',        'eE', 'eject']], "R");
&mapadd('keymap_choose', "Z",
         ['run -#buk "z"', '(un)tar and (de)feather the chosen files'
                           . ' and directories (background)'], ">R");
&mapadd('keymap_choose', "_",
         ['run -+uk "_"', 'rename the chosen files without whitespace'], "`");

###############################################################################
## "Options" keymap reconfiguration ###########################################

#&opton('s');

###############################################################################
## Main mousemap reconfiguration ##############################################

&mapset('mousemap_', 'user',
        [[@{$keymap_{"~"}}, &mev2c('1u')],
         [@{$keymap_{"W"}}, &mev2c('3u')],
         [@{$keymap_{","}}, &mev2c('Wd')],
         [@{$keymap_{","}}, &mev2c('Wu')]]);

###############################################################################
## Subroutines ################################################################

sub cfg::onecmd { $ch eq 'mous' }

sub rccolorlong {
        local $_ = join('', @_);
        return &colorlongline($_, $co_msg)
                if $long =~ /\b(whichpkg|certinfo)\b/
                && /n[o'](t| path) (owned|found)/i;
        return &colorlongline($_, $co_error)
                if $long =~ /\bcertinfo\b/ && /^\S*certinfo:/;
        my $rwx = '[-r][-w][-x]';
        s/\b(?:(d)(:))?([ugmo]):(?:(\w*)(:))?($rwx)(?:(#)($rwx))?/
                &color($1, $co_sbits)                    . $2  .
                &color($3, $co_ftype)                    . ':' .
                &color($4, $co_user{$4} || $co_user{''}) . $5  .
                &color($6, $co_perms)                    . $7  .
                &color($8, $co_myper)/ge ||
        s/([^\\\s]+) (r?l?i?d?w?k?a?)(, |\\|$)/
                &color($1, $co_user{$1} || $co_user{''}) . ' ' .
                &color($2, $co_perms)                    . $3
                                     /ge if $long =~ /^\s*lsacl\b/;
        $_;
}

sub rc::edtags {
        my %tags = ();
        foreach my $tags ('tags', 'etc/tags', "$ENV{HOME}/etc/tags") {
                next unless open(TAGS, $tags);
                while (<TAGS>) {
                        next if /^!_TAG_/;
                        chomp; s/\t.*//; $tags{$_}++;
                }
                close TAGS;
        }
        sort keys %tags;
}

1;