""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" vim: set com=b\:\" tw=79 fo=croq2:
"
"			File manager macros for Vim 4.5
"
"	 Author:  Ral Segura Acevedo <raul@hplara.iquimica.unam.mx>
" Last modified:  970129  (1997 Jan 29)
"    Suggestion:  Add the command "so filename" in your ~/.vimrc (where
"		  filename is the name of this file;).
"
" To get the last version send a mail to <raul@hplara.iquimica.unam.mx> with
" SUBJECT: "send file manager macros".  Tar viewer coming soon!!
"
"
" User commands from any buffer:
" _ls	loads vim's current directory.
" _LS	loads the current file's directory. (it doesn't work on a [No File]).
"
" or 'edit' the directory ("vim /tmp/", or from vim with ":e .", ":sp ~/bin",
" etc., sometimes a trailing "/" is needed)
"
" Magic Keys:
"
" In normal mode:
"
"   _H		Show keys/functions table.
"   <Return>	On a file entry.  Loads the file/directory.
"   <Return>	On a line starting with ":" executes the line as a :-command.
"   <Return>	On any other line.  Executes the 'listing command' (such as
"		":r!ls -lLa /home/user", displayed on line 1)
"   <C-N>	Moves the cursor to the next file entry.
"   		([count]<C-N> also works:  9<C-N>)
"   <C-P>	Moves the cursor to the previous file entry.
"               ([count]<C-P> also works:  9<C-P>)
"   o		Same as <Return> but it splits the window first.
"   U		Loads the parent directory. (The current buffer is not deleted).
"   R		Refresh (executes the 'listing command').
"   Q		Quit.
"
"   %		(Un)Tag a file entry.  It can be used alone on the current line,
"		or from the visual to toggle the tag of the highlighted lines.
"		The easiest way to untag all the files is pressing "R" (refresh)
"
" The next commands create a new window which prompts the user to execute a
" command on the "selected files".  Where "selected files" means:
"	1) Those tagged with % (a % is showed at the beginning of the lines)
"	2) If there are no tagged files, the file entry in the current line
"	3) If there is no file entry in the current line either, then the
"	macros' working directory.
" To execute the command type "done", if no messages (errors) are returned then
" the window is deleted, otherwise the window displays those messages and "u"
" (undo) can be used to get back the previous contents of the buffer.
" "Q" can be used to quit without executing the command.
"
"   _CP		Copy the file(s) to another place.
"   _MV		Move the file(s) to another place.
"   _LN		Link the file(s) to another place.
"   _SLN	(Symbolic) Link the file(s) to another place.
"   _MK		Make directories (the given files are used as a template)
"   _CHM	Change the file(s) mode (chmod).
"   _CHO	Change the file(s) owner (chown).
"   _CHG	Change the file(s) group (chgrp).
"   _RM		Remove the file(s) (directories have to be empty)
"   _RF		Remove (force) the file(s) (rm -rf is used, directories are
"		removed recursively).  BE CAREFUL with this one.
"   _SH		This macro just list the given files/directories and the
"		macros' working directory, so you can use those names with any
"		command you wish, say tar, gzip, or whatever.
"
" In insert mode:
"   <Return>	Exits insert mode and does the same as <Return> in normal mode.
"   <Tab>	Expands filenames.
"   		(These commands are useful to edit the listing-command.)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" The internal macros start with "__" and end with "-".
"
" __CQ-  quotes all the shell metacharacters in the given lines so each line
"	 can be seen as a single pathname. (normally used just in the current
"	 line: 1__CQ-) cursor: same line, but might end on column 1.
"	 pattern: :-search (& therefore last-search too), replace.
"
" __LS-  the given lines have pathnames, it strips the first occurrence of
"	 the following "words": (anything might be before or after them)
"	 //something//../  ->	/   (// means at least 1 / in a row)
"	 //../		  ->	/   (//../ at the beginning of the pathname)
"     				    (// means at least 1 / in a row)
"	 //./		  ->	/   (// means at least 1 / in a row)
"	 //		  ->	/   (// means at least 2 / in a row)
"	 cursor: same line,  but might end on column 1.  pattern: all.
"
" __L1-  Adds the 'listing command' (:r!ls -lLA <dir>) in line 1, which is
"	 always needed to get the (macro's) working directory. <dir> quoted
"	 with __LQ-.  cursor: line 1, just before the dir. name.
"	 register:-,"
" __L1C- checks if the first line is a :-command, calls __L1- if not.  Calls
"	 __LS- to strip the dir. name.  (an aux. map is used: __LA-)
"	 cursor: line 1, might end in col 1.  register: -," (iff _L1- called).
"	 pattern: search patterns changed.
"
" __LC-  this macro is executed on a line which starts with ":", assuming it
"	 is a :-command to list files, the line is *copied* (to ensure there
"	 are at least 2 lines in the buf.) to the first line, a message is
"	 printed in the second line and all the other lines are removed.  Then
"	 the :-command is executed.  Finally it adds a / to the directories
"	 names, inserts 2 spaces before every file entry, and :set's nomod.
"	 cursor: last file entry (last line).	pattern: all.  pattern: all.
"	 register: .(msg), 0 (listing com.), 1 and " (previous buf. contents)
"
" __LBD- It creates a normal-command to display the file whose name appears in
"	 the current line and deletes the current buffer (to keep the window
"	 dimensions something must be loaded before bdelete the current
"	 buffer, but if the old buf. is :bdeleted after loading the new one
"	 then we'd end with nothing if the old and new buffers have the same
"	 name) so /dev/null is temporarily loaded to avoid that.  register: .
"
" __LK-  It creates a normal-command to undo the changes and display the file
"	 whose name appears in the current line (the old buffer is kept).
"	 register: .
"
" __LF-  called when <CR> is typed in a line which looks like a file entry, it
"	 expects the filename in register 0 (yank), the listing command on line
"	 1 (to get the dir. name), and a macro __LFP- mapped to either __LBD-
"	 or __LK- depending on whether the current buf. is going to be deleted
"	 or kept.  First, it removes everything but the dirname from line 1, It
"	 quotes the filename, adds the dir. if needed, __LS-strips it, loads
"	 that file by executing the command generated by __LFP- and finally
"	 shows the file info (:f), note that it explicitly jumps to line 1 to
"	 avoid "Press return" msgs.  cursor: col 1. (not sure), line 1.
"	 register: ", - (loading command).  patterns: all.
"
" __LN-  looks forward for a filename, if the cursor is at the start of a line
"	 with a file entry, then this macro moves the cursor to the beginning
"	 of the filename, (note that 3E2l must not be replaced with 4W or the
"	 macro will get confused with filenames starting with spaces/tabs)
"	 cursor: beginning of a filename (hopefully).  pattern: last search.
"
" __LWh- sets [Wh]ich action will be done by the macro __LD- depending on
"	 whether the current line looks like a file entry, a :-command, or
"	 none (when "none", the listing command is executed) finally calls
"	 __LD-.  patterns: all.  registers: depend on __LD-
"
" _H	 Open a new window to display the key/function table.
"
" %	 it toggles the tag (leading % char.) of the selected lines (default
"	 just the current, but it can be used from the visual)
"	 cursor: below the end of the selected area.  patterns: all.
"
" __LSC- (shell command) marks the current line (y) so the cursor goes back to
"	 there just before leave the buffer.  puts the current line, and all
"	 the tagged ones in register l, the listing command is yanked, then
"	 :splits another window, (named: /Command(from_%):_<command name from
"	 macro __L_C->, if it already exists then its previous contents are
"	 kept), pastes the register l as the first paragraph and the second
"	 paragraph starts with a white space followed by the macros' working
"	 directory (gotten from the listing command) this line is marked (also
"	 "y", but remember we R in a different buffer now) and yanked (without
"	 the trailing NL) and finally the macro __CI- is called.  After that
"	 the first paragraph has quoted full pathnames with a leading white
"	 space, the second paragraph is not modified by __CI-, instructions are
"	 inserted automatically at the end of the buffer when it is created.
"	 cursor: first line, column 1, of a new window.  pattern: all.  
"	 registers: ", l, 0, -, ., %
"
" __LCM- This macro is called from _CP, _MV, etc. to map __L_C- to the name of
"	 the command to be displayed in the status line.
"
" _CP, _MV, _LN, _SLN
"	 these macros call __LSC to create a new window which prompts the user
"	 to copy/move/link/symbolic-link the given files (tagged files, if
"	 there are none, the file on the current line, if it doesn't list a
"	 file then the working directory:) to the (macro's)working directory.
"	 the cursor is left at the end of working directory name so it can be
"	 easily edited.
"
" _RF	 call __LSC to create a new window which prompts the user to delete
"	 the given files, and directories.  rm -rf is used!! directories are
"	 removed recursively.
" _RM	 same as _RF but it uses rm on files and rmdir on directories, (so
"	 directories must be empty)
"
" _MK	 call __LSC to create a new window which prompts the user to create
"	 directories (the given files are used as a template) 
"
" _CHM, _CHG, _CHO
" 	 these macros call __LSC to create a new window which prompts the user
" 	 to chmod/chgrp/chown the given files. the cursor is left between the
" 	 command and the first filename where an argument must be inserted.
"
" _SH	 call __LSC to create a new window which shows the given files first,
"	 then the given directories (separated with an empty line) and finally
"	 the macros' working directory, so the user can pass those names to any
"	 command. (":.g/./" can be used to check if there are directories, and
"	 ":1g/./" to check if there are files) cursor: on the directories
"	 paragraph (or on the second empty line if there were no directories)
"
" <CR>	 in insert-mode goes to normal mode and then execute the normal-mode's
"	 macro <CR>.
" <Tab>  in insert mode, expands file names.
"
" <CR>	 normal-mode set __LFP- to __LBD-, and then calls __LWh- which means
"	 that a new file/directory is going to be loaded and the current
"	 buffer will be removed.
"    on a line with a file entry, that file (or directory) is loaded.
"    on a line starting with : that line is executed as a :-command.
"    on any other line the 'listing command' (normally on line 1) is executed.
"
" __L:- Shows in the command mode line the contents of the file from the cursor
"	position to the end of the line.  Used by <C-N>, <C-P> and BufEnter to
"	remove the garbage in that line showing the current filename entry.
"
" <C-N>	moves the cursor to the next line, and then calls __LN- from the
"	beginning of the line to jump to the next file name.  calls __L:-.
"	[count]<C-N> works too.
"
" <C-P>	moves the cursor to the previous line, and then calls __LN- from the
"	beginning of the line to jump to the next file name.  calls __L:-.
"	[count]<C-P> works too.
"
" o	set __LFP- to __LK- and then calls __LWh-, so works like <CR> but
"	doesn't destroy the current buffer.  It splits the window too.
"
" U	loads parent directory. (current buffer is not deleted)  it first
"	checks for the listing command and deletes everything after the last /
"	adds a ../ at the end of the line, strips the directory's name, and
"	executes the listing command, finally the buffer's name is set
"	accordingly to the directory's.  and the cursor is left in the first
"	file entry.
"
" Q	quit
" 
" R	refresh.  before the refresh: if the current line has a file entry then
"	just the filename is used, in any case, the search-metacharacters in
"	the line are quoted, the line is yanked in register "l" (lower L) and
"	the changes undone, after the refresh the cursor is in the last line,
"	it is then moved to the last column where a backward search starts
"	looking for the former current line or the "^:" which always exists in
"	line 1, finally, a dummy ":" command is executed to clean the last
"	message.
"
" __+-  refresh.  call R and then sets mark y.  Called by the /Command*'s
"	macro "done" (my__+-`y).  This is the only internal macro without a L/C
"	in it's name.  That's because when "__+-" is interpreted the cursor may
"	or may not be in the listing window, so, it has to be harmless in a
"	"normal" buffer.
"
" The buffer's refresh is automatically done when it is empty.
" The autocommands (for */,.,..) also ":set magic tw=0 wm=0 noai nosi nocin
" nolisp fo="
"
"
" in the buffers /Command*
" __CJ-	 joins the lines in a paragraph without adding or removing any space.
"	 and :set nomod.  cursor: first non-blank
" __CJD- same as __CJ- but also removes the next line.  cursor: last column.
" __CJj- same as __CJ- but also joins   the next line.  cursor: last column.
"
" done	 filters the buffer through $SHELL, if no messages (errors) are
"	 returned then the window is deleted, otherwise the window displays
"	 those messages and "u" (undo) can be used to get back the previous
"	 contents of the buffer.  Finally, "my__+-`y" is executed, it is
"	 harmless in a normal buffer, but in the listing window it refreshes
"	 the listing.  note that in a normal buffer, if the cursor is in the
"	 last line then my__+-`y moves the cursor to the beginning of the line.
"
" Q	 quit.
" <Tab>  insert-mode expand filenames.
" <CR>   insert-mode exits insert-mode.
"
" __CB-  prints a banner at the end of the buffer giving instructions.
"	 the cursor is left at the end of the buffer.
"
" __CI-  (called from __LSC-) it gets what was the listing buffer's current
"	 line in line 1, the tagged lines (if any) from line 2 on, the macros'
"	 working directory in the next paragraph (marked y) and in registers 0
"	 and ", and the cursor in line 1, then checks line 2, if there are
"	 tagged lines then the first line is removed, after that, if line 1
"	 doesn't look like a file entry then it is replaced with a dummy entry
"	 to the "./" file so the first paragraph has always a list of file
"	 entries which is then marked with the visual to execute 4 global
"	 commands on it, 1) remove everything but the filename, 2)quote (__CQ-)
"	 those filenames, 3) add the directory name if needed, or some blanks
"	 otherwise (from the yank buffer) and 4) strips (__LS-) the pathnames.
"	 patterns: all.	registers: -, 1, ".  cursor: in the first paragraph.
"
" The autocomands for /Command* also "set tw=0 wm=0 noai nosi nocin nolisp
" fo=" and insert "instructions" in the last line if the last line is empty.
"
" The /File_manager/keys windows has just 2 maps:
" Q	delete the window.
" R	refresh: clears the window and inserts the key/function table.
" and "set tw=0 wm=0 noai nosi nocin nolisp fo="
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

au!BufEnter */,.,..,/Command* no__CQ- :g/\([];&><()~$*? <C-I>\\\[#\|^]\)/s//\\\1/g<CR>
au BufEnter */,.,..,/Command* no__LS- :g-\(/\+[^/]*\)\=/\+\.\./\<BAR>/\+\.\=/-s--/-<CR>
au BufEnter */,.,.. nm__L1- :0r!echo :r1ls -lLa %:p/<CR>f1r!0dt/1__CQ-0P
au BufEnter */,.,.. nm__L1C- :nm__LA- 1G<BAR>1v-^:-nm__LA- __L1-<CR>__LA-1__LS-
au BufEnter */,.,.. no__LC- yy1GPA<NL>Type _H for a list of commands, see the source file for a detailed explanation.<Esc>jdG@0:g-^d-s-/*$-/<CR>:g/^[^:].*[0-9] [A-Z]/s/^/  <CR>:set nomod<CR>
au BufEnter */,.,.. nn__LBD- I:e!/dev/null<Bar>bd!#<bar>e<End><Bar>bd#<Esc>
au BufEnter */,.,.. nn__LK- Iu:e<Esc>
au BufEnter */,.,.. nm__LF- 0dt/$pT/D0D"0p1__CQ-:.v-^/-norm "-P<CR>1__LS-__LFP-y1G@":f<CR>1G
au BufEnter */,.,.. nn__LN- /[0-9] [A-Z]<CR>3E2l
au BufEnter */,.,.. nm__LWh- :nm__LD- __LC-1G__LN-<Bar>.g/^[ %]/nm__LD- __LF-<BAR>norm __LN-y$<CR>:.g/^:/t0<CR>__L1C-__LD-
au BufEnter */,.,.. nm_H :5new/File_manager/keys<CR>R<C-W>p

au BufEnter */,.,.. nm % v%|vn % :g/^%/s//x<CR>:'<,'>g/^ /s//%<CR>:'<,'>g/^x/s// <CR>:set nomod<CR>:"toggle tag"<CR>`>j
au BufEnter */,.,.. nm __LSC- "lyymy__L1C-yy:g/^%/y L<CR>`y:5sp/Command:__L_C-<BAR>cu <C-V>__L_C-<CR>"0Pt/d0yl3Pmy$pT/DyyP0y$D"lP__CI-1G0

au BufEnter */,.,.. nn__LCM- :cno__L_C- 
au BufEnter */,.,.. nm_CP __LCM-cp<CR>__LSC-icp<Esc>__CJj-
au BufEnter */,.,.. nm_MV __LCM-mv<CR>__LSC-imv<Esc>__CJj-
au BufEnter */,.,.. nm_LN __LCM-ln<CR>__LSC-iln<Esc>__CJj-
au BufEnter */,.,.. nm_SLN __LCM-ln-s<CR>__LSC-iln -s<Esc>__CJj-
au BufEnter */,.,.. nm_RF __LCM-rm-rf<CR>__LSC-irm -rf<Esc>__CJD-
au BufEnter */,.,.. nm_RM __LCM-rm<CR>__LSC-'yD:1,-2g-/$-m'y-<CR>:.g--norm {jirmdir<C-V><ESC>__CJ-<CR>:1g/./norm 0irm<C-V><Esc>__CJ-<CR>$
au BufEnter */,.,.. nm_MK __LCM-mk<CR>__LSC-imkdir<Esc>__CJD-T/
" au BufEnter */,.,.. nm_CHM __LCM-chmod<CR>__LSC-'yD:1,-2g-/$-m'y-<CR>:.g--norm {jichmod <C-V><ESC>__CJ-<CR>:1g/./norm 0ichmod <C-V><Esc>__CJ-<CR>e2l
au BufEnter */,.,.. nm_CHM __LCM-chmod<CR>__LSC-ichmod <Esc>__CJD-0e2l
au BufEnter */,.,.. nm_CHG __LCM-chgrp<CR>__LSC-ichgrp <Esc>__CJD-0e2l
au BufEnter */,.,.. nm_CHO __LCM-chown<CR>__LSC-ichown <Esc>__CJD-0e2l
au BufEnter */,.,.. nm_SH __LCM-sh<CR>__LSC-}yyp:1,-2g-/$-m'y-2<CR>0

au BufEnter */,.,.. im<CR> <Esc><CR>|ino<TAB> <C-X><C-F>
au BufEnter */,.,.. nm<CR> :nm__LFP- __LBD-<CR>__LWh-
au BufEnter */,.,.. nn__L:- y$:"<C-R>""<CR>
au BufEnter */,.,.. nm<C-N> +__LN-__L:-|nm<C-P> -__LN-__L:-
au BufEnter */,.,.. nm o   :sp<Bar>nm__LFP- __LK-<CR>__LWh-
au BufEnter */,.,.. nm U   __L1C-yl$pT/C../<Esc>1__LS-__LC-1G0f/y$__LN-:f <C-R>"<CR>
au BufEnter */,.,.. nn Q   :bd!<CR>
au BufEnter */,.,.. nm R   :.g-^[% ]-norm __LN-d0<CR>__magic0"ly$u__L1C-__LC-$?^:\<Bar> <C-R>l$<CR>:"refresh"<CR>
au BufEnter */,.,.. nm__+- Rmy
au BufEnter */,.,.. set magic tw=0 wm=0 noai nosi nocin nolisp fo=
au BufEnter */,.,.. nn__LA- my|nn__LFP- my
" [R]efresh only iff the buffer is empty
au BufEnter */,.,.. nn__LD- my|.v/./nm__LD- __L1C-__LC-1G__LN-
au BufEnter */,.,.. norm__LD-__L:-

au!BufLeave */,.,.. unm__CQ-|unm__LS-|unm__L1-|unm__L1C-|unm__LC-
au BufLeave */,.,.. unm__LBD-|unm__LK-|unm__LF-|unm__LN-|unm__LWh-
au BufLeave */,.,.. unm__LD-|unm__LA-|unm__LFP-|iun<CR>|iun<Tab>|nun<CR>
au BufLeave */,.,.. nun__L:-|nun<C-N>|nun<C-P>|nun o|nun U|nun Q|nun R|nun__+-
au BufLeave */,.,.. unm %|unm_CP|unm_MV|unm_LN|unm_SLN|unm_RF|unm_RM|unm__LSC-
au BufLeave */,.,.. unm_MK|unm_CHM|unm_CHG|unm_CHO|unm_SH|unm_H|nun__LCM-

map _ls :sp.<CR><C-N>
map _LS :sp%:p:h/<CR><C-N>

au BufEnter /Command* nn__CJ- vp:j!<CR>:set nomod<CR>
au BufEnter /Command* nn__CJD- vp:j!<CR>JD:set nomod<CR>
au BufEnter /Command* nn__CJj- vpj:j!<CR>:set nomod<CR>$
au BufEnter /Command* nm done :%!$SHELL<CR>:g/./err<CR>:bd!<CR>my__+-`y
au BufEnter /Command* nn Q :bd!<CR>
au BufEnter /Command* ino<TAB> <C-X><C-F>|ino<CR> <Esc>
au BufEnter /Command* nn __CB- Gi# Normal-mode: Type "done" to execute the command, "Q" to quit.<NL># Insert-mode: Tab to expand filenames, Return go to Normal mode.<Esc><<<<

" au BufEnter /Command* nm__CI- :2g/^%/1d<CR>:1v-^[% ]-s-.*-69 N u l ./<CR>vpk:g/[0-9] [A-Z]/norm n3E2ld0<CR>gv__CQ-:.g-^/-norm `y0yt/``<CR>gv:g/^/norm "0P<CR>gv__LS-
au BufEnter /Command* nm__CI- :2g/^%/1d<CR>:1v-^[% ]-s-.*-69 N u l ./<CR>vpk:g/[0-9] [A-Z]/norm /<C-V><CR>3E2ld0<CR>gv__CQ-:.g-^/-norm `y0yt/``<CR>gv:g/^/norm "0P<CR>gv__LS-
au BufEnter /Command* set tw=0 wm=0 noai nosi nocin nolisp fo=
au BufEnter /Command* nn__CA- my|$v/./nm__CA- __CB-
au BufEnter /Command* norm__CA-
au!BufLeave /Command* unm__CQ-|unm__LS-|unm__CI-
au BufLeave /Command* unm__CB-|unm__CJ-|unm__CJj-|unm__CJD-|unm__CA-
au BufLeave /Command* iu<Tab>|iu<CR>|unm Q|unm done

au!BufEnter /File_manager/keys set tw=0 wm=0 noai nosi nocin nolisp fo=
au BufEnter /File_manager/keys nn Q :bd!<CR>
au BufEnter /File_manager/keys nn R :%d<CR>iRal Segura Acevedo <raul@hplara.iquimica.unam.mx><CR>#CR> enter      <Bar> #C-N> next     <Bar> _MV move   <Bar> _LN  link      <Bar> _CHO chown<CR>o    split&enter<Bar> #C-P> prev.    <Bar> _CP copy   <Bar> _SLN sym. link <Bar> _CHM chmod<CR>U    up dir.    <Bar> %     tag file <Bar> _RM delete <Bar> _MK  make dir. <Bar> _CHG chgrp<CR>R    refresh    <Bar> Q     *QUIT*   <Bar> _RF rm -rf <Bar> _SH  shell free style<CR>    insert mode: #CR> enter   #Tab> expand <Esc>:%s/#/</g<Bar>set nomod<CR>G
au BufLeave /File_manager/keys nun Q|nun R

" the next macro comes from my set of emacs-like incremental search macros
nmap __magic   :.g/\([[$^.*~\\/?]\)/s//\\\1/g<CR>
