#!/usr/bin/perl

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

# Many of the scripts and supporting external configurations used via this
# file are available at https://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.0523 1.0509);
&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
# 1.0501  31 Jan 2020	Add "go tkt:" and remove "go topic:" options in G cmd
# 1.0502  22 Apr 2020	Add "go cve:" to G command
# 1.0503  25 Oct 2020	Use `mcomix` vs `comix`
# 1.0504   5 Nov 2020	Add "go story:" to G command
# 1.0505  20 Dec 2020	Add &rc::sites and use for G command site completions
# 1.0506  29 Jul 2021	Add `gthumb` as a viewer for .webp files
# 1.0507   5 Apr 2022	Add /l/plex/tmp to faves
# 1.0508   2 May 2022	Change "go movie:" destination
# 1.0509  29 Jan 2023	Add "go redir:" option to G command; comment out proxy
# 1.0510   6 Feb 2023	Add `zebra` into binary image options
# 1.0511  19 Apr 2023	Add "go gif:" option to G command
# 1.0512  10 Nov 2023	Add /bak/*kinzler/home/kinzler/work to faves
# 1.0513   5 Apr 2024	Rename "go" to "gowww"
# 1.0514  22 Apr 2024	Add git fallback to K command
# 1.0515  24 May 2024	Remove "gowww app:" option to G command
# 1.0516  27 May 2024	Remove "gowww {news,cover,soft}:" options to G command
# 1.0517  28 May 2024	Add "gowww vol:" option to G command
# 1.0518   5 Nov 2024	Remove proctree options from J command
# 1.0519  30 Dec 2024	Recognize u0_a402 user (termux)
# 1.0520  28 Feb 2025	Add `tesseract` into binary image options for OCR
# 1.0521  27 Mar 2025	Add "go ai:" option to G command
# 1.0522   2 Sep 2025	Add typemap for .heic files
# 1.0523   3 Oct 2025	Add "gowww group:" option to G command

###############################################################################
## 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/^vkinzler\b.*/$ENV{VH}/is; $_ }

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

if ($color && (getpwnam('kinzler') || getpwnam('u0_a402'))) {
	$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 -r "zebra --quit $_q"',
	  'view this image file',		    'vV', 'view'],
	 ['run -g "(img2txt -W " . ($scr->{COLS} - 1) . " -- $_q;"
		. " identify -verbose -- $_q)"',
	  'view information about this image file', 'iI', 'info'],
	 ['run -p "tesseract $_q -"',
	  'view text within this image file',	    'oO', 'ocr']]);
&mapadd('typemap_', 'ext heic',
	[['run -x= "eog"',
	  'view this heic image file',		 'vV', 'view'],
	 ['run -R "heif-convert -- $_q $_rq.jpg"',
	  'convert this heic image file to jpg', 'cC', 'convert']]);
&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,	# use pandoc?
	 ['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"';
&mapadd('typemap_do', 'ext webp',
	['run -x= "gthumb"', 'display this webp file'],
	(grep(/ csv /, @typemap_do))[0]);
&mapset('typemap_do', (grep(/ csv /, @typemap_do))[0],
	 ['run -x_ "office"', 'load this file into Office']);
&mapadd('typemap_do', 'ext cbr cbz',
	 ['run -x= "mcomix"', '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{'TH', 'MH'})) ? () :
#		('cd "/l/picons/ftp/incoming"; win',
		('cd("~/l/haiku")    ? longls("-win", 1) : win',
		 'cd("~oracle/post") ? longls("-win", 1) : win'),
	     'cd "~/work"; win');

$rc::prefaves = 'cd /media && make -s';
@rc::faves    = ('/etc/systemd/system', '/l/plex/tmp',
		 '/bak/tkinzler/home/kinzler/work',
		 '/bak/ukinzler/home/kinzler/work',
		 '/bak/vkinzler/home/kinzler/work',
		 </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 "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 "gowww"',
	  'browse the URL guessed from the given piece(s)',
	  'gG',   'url pieces'],
	 ['run -s "gowww", "url:" . gets "Go URL:"',
	  'browse the given URL',
	  'uUkK', 'url'],
	 ['run -s "gowww", "redir:" . gets "Go Redir URL:"',
	  'browse the given URL via a redirect',
	  'rR',   'url redirect (Facebook redirect)'],
#	 ['run -s "gowww", "proxy:" . gets "Go Proxy URL:"',
#	  'browse the given URL via a proxy',
#	  'x',    'url proxy (Google proxy)'],
	 ['run -s "gowww", "info:" . gets "Go Info URL:"',
	  'browse the information about the given URL',
	  'iI',   'url info (Google Info)'],
	 ['run -s "gowww", "cache:" . gets "Go Cache URL:"',
	  'browse the cached version of the given URL',
	  'c',    'url cache (Google cache)'],
	 ['run -s "gowww", "arc:" . gets "Go Archive URL:"',
	  'browse historical versions of the given URL',
	  'vV',   'url versions (Wayback)'],
	 ['setcomplete \&rc::sites;'
	  . ' 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 "gowww", "yub:" . gets "Go YubNub:"',
#	  'browse the results for the given yubnub command',
#	  'yY',   'yubnub'],
	 ['run -s "gowww", "search:" . gets "Go Search:"',
	  'browse the results for the given web search query',
	  's',    'search (Google)'],
	 ['run -s "gowww", "priv:" . gets "Go Private:"',
	  'browse the results for the given private web search query',
	  'S',    'private (DuckDuckGo)'],
	 ['run -s "gowww", "ai:" . gets "Go AI:"',
	  'browse the results for the given AI prompt',
	  '+',    'ai (Google)'],
	 ['run -s "gowww", "image:" . gets "Go Image:"',
	  'browse the results for the given web image search query',
	  '@',    'image (Google Images)'],
	 ['run -s "gowww", "-a", "gif:" . gets "Go Gif:"',
	  'browse the results for the given web gif search query',
	  '~',    'gif (Giphy)'],
	 ['run -s "gowww", "video:" . gets "Go Video:"',
	  'browse the results for the given web video search query',
	  '%',    'video (Google Video)'],
	 ['run -s "gowww", "map:" . gets "Go Map:"',
	  'browse the results for the given map location query',
	  '^',    'map (Google Maps)'],
	 ['run -s "gowww", "dir:" . gets "Go Directions:"',
	  'browse the results for the given map directions query',
	  '_',    'directions (Google Maps)'],
#	 ['run -s "gowww", "news:" . gets "Go News:"',
#	  'browse the results for the given usenet search query',
#	  'nN',   'news (Google Groups)'],
	 ['run -s "gowww", "ask:" . gets "Go Ask:"',
	  'browse the matches for the given question',
	  '?',    'ask (Ask)'],
	 ['run -s "gowww", "encyc:" . gets "Go Encyclopedia:"',
	  'browse the results for the given encyclopedia query',
	  'eE',   'encyclopedia (Wikipedia)'],
	 ['run -s "gowww", "word:" . gets "Go Word:"',
	  'browse the results for the given dictionary query',
	  'wW',   'word (Dictionary)'],
	 ['run -s "gowww", "en:" . gets "Go English:"',
	  'browse the results for the given English translation',
	  '<',    'english (Google Translate)'],
	 ['run -s "gowww", "es:" . gets "Go Spanish:"',
	  'browse the results for the given Spanish translation',
	  '>',    'spanish (Google Translate)'],
	 ['run -s "gowww", "perl:" . gets "Go Perl:"',
	  'browse the results for the given perl documentation query',
	  'p',    'perl (Perldoc)'],
	 ['run -s "gowww", "cpan:" . gets "Go CPAN:"',
	  'browse the results for the given CPAN module query',
	  'P',    'cpan'],
	 ['run -s "gowww", "-a", "user:" . gets "Go User:"',
	  'browse the results for the given user directory query',
	  'h',    'user (U-M Directory)'],
	 ['run -s "gowww", "-a", "group:" . gets "Go Group:"',
	  'browse the results for the given group directory query',
	  'H',    'group (U-M Directory)'],
	 ['run -s "gowww", "phone:" . gets "Go Phonebook:"',
	  'browse the results for the given phonebook query',
	  '#',    'phone (Google PhoneBook)'],
	 ['run -s "gowww", "-a", "tkt:" . gets "Go Ticket:"',
	  'browse the results for the given ticket query',
	  'tT',    'ticket (TeamDynamix)'],
	 ['run -s "gowww", "-a", "story:" . gets "Go Story:"',
	  'browse the results for the given story query',
	  'jJ',    'story (Targetrocess)'],
	 ['run -s "gowww", "-a", "vol:" . gets "Go Volume:"',
	  'browse the results for the given volume query',
	  'a',     'volume (SRS)'],
	 ['run -s "gowww", "-a", "cve:" . gets "Go CVE:"',
	  'browse the results for the given CVE query',
	  '!',    'cve (NIST)'],
	 ['run -s "gowww", "city:" . gets "Go City:"',
	  'browse the results for the given city map query',
	  'C',    'city (City-Data)'],
	 ['run -s "gowww", "book:" . gets "Go Book:"',
	  'browse the results for the given bookstore query',
	  'zZ',   'book (Amazon)'],
	 ['run -s "gowww", "movie:" . gets "Go Movie:"',
	  'browse the results for the given movie database query',
	  'mM',   'movie (JustWatch)'],
	 ['run -s "gowww", "and:" . gets "Go App:"',
	  'browse the results for the given Android app query',
	  'A',    'app (Android Market)'],
	 ['run -s "gowww", "prod:" . gets "Go Product:"',
	  'browse the results for the given product search query',
	  '$',   'product (Google Products)'],
	 ['run -s "gowww", "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 "gowww", "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 -r "dodot";'
	  . ' $cwd eq untilde("~oracle/post") && longls("-win", 1)',
	  'run `make` else `git status`'], ">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 ne "u0_a402"'
	  . ' ? "~$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;
}

sub rc::sites {
	@_ = `sort "$ENV{HOME}/etc/sites" 2> /dev/null`;
	chomp @_; @_;
}

1;
