xref: /vim-8.2.3635/runtime/autoload/netrw.vim (revision 00a927d6)
1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		May 14, 2010
4" Version:	138
5" Maintainer:	Charles E Campbell, Jr <[email protected]>
6" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
7" Copyright:    Copyright (C) 1999-2009 Charles E. Campbell, Jr. {{{1
8"               Permission is hereby granted to use and distribute this code,
9"               with or without modifications, provided that this copyright
10"               notice is copied with it. Like anything else that's free,
11"               netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
12"               *as is* and come with no warranty of any kind, either
13"               expressed or implied. By using this plugin, you agree that
14"               in no event will the copyright holder be liable for any damages
15"               resulting from the use of this software.
16"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
17"
18"  But be doers of the Word, and not only hearers, deluding your own selves {{{1
19"  (James 1:22 RSV)
20" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
21" Load Once: {{{1
22if &cp || exists("g:loaded_netrw")
23  finish
24endif
25let g:loaded_netrw = "v138"
26if v:version < 702
27 echohl WarningMsg
28 echo "***warning*** this version of netrw needs vim 7.2"
29 echohl Normal
30 finish
31endif
32if !exists("s:NOTE")
33 let s:NOTE    = 0
34 let s:WARNING = 1
35 let s:ERROR   = 2
36endif
37
38" sanity checks
39if v:version < 700
40 call netrw#ErrorMsg(s:WARNING,"you need vim version 7.0 or later for version ".g:loaded_netrw." of netrw",1)
41 finish
42endif
43
44let s:keepcpo= &cpo
45setlocal cpo&vim
46"DechoTabOn
47"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw)
48
49" ======================
50"  Netrw Variables: {{{1
51" ======================
52
53" ---------------------------------------------------------------------
54" NetrwInit: initializes variables if they haven't been defined {{{2
55"            Loosely,  varname = value.
56fun s:NetrwInit(varname,value)
57  if !exists(a:varname)
58   if type(a:value) == 0
59    exe "let ".a:varname."=".a:value
60   elseif type(a:value) == 1
61    exe "let ".a:varname."="."'".a:value."'"
62   else
63    exe "let ".a:varname."=".a:value
64   endif
65  endif
66endfun
67
68" ---------------------------------------------------------------------
69"  Netrw Constants: {{{2
70call s:NetrwInit("g:netrw_dirhist_cnt",0)
71if !exists("s:LONGLIST")
72 call s:NetrwInit("s:THINLIST",0)
73 call s:NetrwInit("s:LONGLIST",1)
74 call s:NetrwInit("s:WIDELIST",2)
75 call s:NetrwInit("s:TREELIST",3)
76 call s:NetrwInit("s:MAXLIST" ,4)
77endif
78
79" ---------------------------------------------------------------------
80" Default values for netrw's global protocol variables {{{2
81if !exists("g:netrw_dav_cmd")
82 if executable("cadaver")
83  let g:netrw_dav_cmd	= "cadaver"
84 elseif executable("curl")
85  let g:netrw_dav_cmd	= "curl"
86 else
87  let g:netrw_dav_cmd   = ""
88 endif
89endif
90if !exists("g:netrw_fetch_cmd")
91 if executable("fetch")
92  let g:netrw_fetch_cmd	= "fetch -o"
93 else
94  let g:netrw_fetch_cmd	= ""
95 endif
96endif
97if !exists("g:netrw_ftp_cmd")
98  let g:netrw_ftp_cmd	= "ftp"
99endif
100if !exists("g:netrw_http_cmd")
101 if executable("elinks")
102  let g:netrw_http_cmd = "elinks"
103  call s:NetrwInit("g:netrw_http_xcmd","-source >")
104 elseif executable("links")
105  let g:netrw_http_cmd = "links"
106  call s:NetrwInit("g:netrw_http_xcmd","-source >")
107 elseif executable("curl")
108  let g:netrw_http_cmd	= "curl"
109  call s:NetrwInit("g:netrw_http_xcmd","-o")
110 elseif executable("wget")
111  let g:netrw_http_cmd	= "wget"
112  call s:NetrwInit("g:netrw_http_xcmd","-q -O")
113 elseif executable("fetch")
114  let g:netrw_http_cmd	= "fetch"
115  call s:NetrwInit("g:netrw_http_xcmd","-o")
116 else
117  let g:netrw_http_cmd	= ""
118 endif
119endif
120call s:NetrwInit("g:netrw_rcp_cmd"  , "rcp")
121call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
122call s:NetrwInit("g:netrw_scp_cmd"  , "scp -q")
123call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
124call s:NetrwInit("g:netrw_ssh_cmd"  , "ssh")
125
126if (has("win32") || has("win95") || has("win64") || has("win16"))
127  \ && exists("g:netrw_use_nt_rcp")
128  \ && g:netrw_use_nt_rcp
129  \ && executable( $SystemRoot .'/system32/rcp.exe')
130 let s:netrw_has_nt_rcp = 1
131 let s:netrw_rcpmode    = '-b'
132else
133 let s:netrw_has_nt_rcp = 0
134 let s:netrw_rcpmode    = ''
135endif
136
137" ---------------------------------------------------------------------
138" Default values for netrw's global variables {{{2
139" Cygwin Detection ------- {{{3
140if !exists("g:netrw_cygwin")
141 if has("win32") || has("win95") || has("win64") || has("win16")
142  if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
143   let g:netrw_cygwin= 1
144  else
145   let g:netrw_cygwin= 0
146  endif
147 else
148  let g:netrw_cygwin= 0
149 endif
150endif
151" Default values - a-c ---------- {{{3
152call s:NetrwInit("g:netrw_alto"        , &sb)
153call s:NetrwInit("g:netrw_altv"        , &spr)
154call s:NetrwInit("g:netrw_banner"      , 1)
155call s:NetrwInit("g:netrw_browse_split", 0)
156call s:NetrwInit("g:netrw_chgwin"      , -1)
157call s:NetrwInit("g:netrw_compress"    , "gzip")
158call s:NetrwInit("g:netrw_ctags"       , "ctags")
159if !exists("g:netrw_cursorline")
160 let g:netrw_cursorline= 1
161 let s:netrw_usercul   = &cursorline
162 let s:netrw_usercuc   = &cursorcolumn
163endif
164" Default values - d-g ---------- {{{3
165call s:NetrwInit("g:netrw_dirhist_cnt"      , 0)
166call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf"}')
167call s:NetrwInit("g:netrw_dirhistmax"       , 10)
168call s:NetrwInit("g:netrw_fastbrowse"       , 1)
169call s:NetrwInit("g:netrw_ftp_browse_reject", '^total\s\+\d\+$\|^Trying\s\+\d\+.*$\|^KERBEROS_V\d rejected\|^Security extensions not\|No such file\|: connect to address [0-9a-fA-F:]*: No route to host$')
170if !exists("g:netrw_ftp_list_cmd")
171 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
172  let g:netrw_ftp_list_cmd     = "ls -lF"
173  let g:netrw_ftp_timelist_cmd = "ls -tlF"
174  let g:netrw_ftp_sizelist_cmd = "ls -slF"
175 else
176  let g:netrw_ftp_list_cmd     = "dir"
177  let g:netrw_ftp_timelist_cmd = "dir"
178  let g:netrw_ftp_sizelist_cmd = "dir"
179 endif
180endif
181call s:NetrwInit("g:netrw_ftpmode",'binary')
182" Default values - h-lh ---------- {{{3
183call s:NetrwInit("g:netrw_hide",1)
184if !exists("g:netrw_ignorenetrc")
185 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
186  let g:netrw_ignorenetrc= 1
187 else
188  let g:netrw_ignorenetrc= 0
189 endif
190endif
191call s:NetrwInit("g:netrw_keepdir",1)
192if !exists("g:netrw_list_cmd")
193 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
194  " provide a 'pscp' listing command
195  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
196   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
197  endif
198  let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
199 elseif executable(g:netrw_ssh_cmd)
200  " provide a default listing command
201  let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
202 else
203"  call Decho(g:netrw_ssh_cmd." is not executable")
204  let g:netrw_list_cmd= ""
205 endif
206endif
207call s:NetrwInit("g:netrw_list_hide","")
208" Default values - lh-lz ---------- {{{3
209if !exists("g:netrw_localcopycmd")
210 if has("win32") || has("win95") || has("win64") || has("win16")
211  if g:netrw_cygwin
212   let g:netrw_localcopycmd= "cp"
213  else
214   let g:netrw_localcopycmd= "copy"
215  endif
216 elseif has("unix") || has("macunix")
217  let g:netrw_localcopycmd= "cp"
218 else
219  let g:netrw_localcopycmd= ""
220 endif
221endif
222call s:NetrwInit("g:netrw_local_mkdir","mkdir")
223if !exists("g:netrw_localmovecmd")
224 if has("win32") || has("win95") || has("win64") || has("win16")
225  if g:netrw_cygwin
226   let g:netrw_localmovecmd= "mv"
227  else
228   let g:netrw_localmovecmd= "move"
229  endif
230 elseif has("unix") || has("macunix")
231  let g:netrw_localmovecmd= "mv"
232 else
233  let g:netrw_localmovecmd= ""
234 endif
235endif
236call s:NetrwInit("g:netrw_local_rmdir", "rmdir")
237call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
238" sanity checks
239if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
240 let g:netrw_liststyle= s:THINLIST
241endif
242if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
243 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
244endif
245" Default values - m-r ---------- {{{3
246call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
247call s:NetrwInit("g:netrw_maxfilenamelen", 32)
248call s:NetrwInit("g:netrw_menu"          , 1)
249call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
250call s:NetrwInit("g:netrw_mousemaps"     , (exists("&mouse") && &mouse =~ '[anh]'))
251call s:NetrwInit("g:netrw_retmap"        , 0)
252if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
253 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
254elseif has("win32") || has("win95") || has("win64") || has("win16")
255 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
256else
257 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
258endif
259call s:NetrwInit("g:netrw_preview"       , 0)
260call s:NetrwInit("g:netrw_scpport"       , "-P")
261call s:NetrwInit("g:netrw_sshport"       , "-p")
262call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
263call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
264call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
265call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f")
266" Default values - s ---------- {{{3
267" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
268call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
269call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "silent keepj " : "keepj ")
270call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
271call s:NetrwInit("g:netrw_sort_options"  , "")
272call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
273if !exists("g:netrw_sort_sequence")
274 if has("unix")
275  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
276 else
277  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
278 endif
279endif
280call s:NetrwInit("g:netrw_special_syntax"   , 0)
281call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
282call s:NetrwInit("g:netrw_use_noswf"        , 0)
283" Default values - t-w ---------- {{{3
284call s:NetrwInit("g:netrw_timefmt","%c")
285call s:NetrwInit("g:netrw_xstrlen",0)
286call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
287call s:NetrwInit("g:netrw_use_errorwindow",1)
288call s:NetrwInit("g:netrw_win95ftp",1)
289call s:NetrwInit("g:netrw_winsize",25)
290" ---------------------------------------------------------------------
291" Default values for netrw's script variables: {{{2
292call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
293if has("win32") || has("win95") || has("win64") || has("win16")
294 call s:NetrwInit("g:netrw_glob_escape",'[]*?`{$')
295else
296 call s:NetrwInit("g:netrw_glob_escape",'[]*?`{~$\')
297endif
298call s:NetrwInit("g:netrw_menu_escape",'./&? \')
299call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
300call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
301
302" BufEnter event ignored by decho when following variable is true
303"  Has a side effect that doau BufReadPost doesn't work, so
304"  files read by network transfer aren't appropriately highlighted.
305"let g:decho_bufenter = 1	"Decho
306
307" ==============================
308"  Netrw Utility Functions: {{{1
309" ==============================
310
311" ------------------------------------------------------------------------
312" s:NetrwOptionSave: save options and set to "standard" form {{{2
313"  06/08/07 : removed call to NetrwSafeOptions(), either placed
314"             immediately after NetrwOptionSave() calls in NetRead
315"             and NetWrite, or after the s:NetrwEnew() call in
316"             NetrwBrowse.
317"             vt: normally its "w:" or "s:" (a variable type)
318fun! s:NetrwOptionSave(vt)
319"  call Dfunc("s:NetrwOptionSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$"))
320
321"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"))
322  if !exists("{a:vt}netrw_optionsave")
323   let {a:vt}netrw_optionsave= 1
324  else
325"   call Dret("s:NetrwOptionSave : options already saved")
326   return
327  endif
328"  call Decho("fo=".&fo.(exists("&acd")? " acd=".&acd : " acd doesn't exist"))
329
330  " Save current settings and current directory
331  let s:yykeep          = @@
332  if exists("&l:acd")
333   let {a:vt}netrw_acdkeep  = &l:acd
334  endif
335  let {a:vt}netrw_aikeep    = &l:ai
336  let {a:vt}netrw_awkeep    = &l:aw
337  let {a:vt}netrw_bombkeep  = &l:bomb
338  let {a:vt}netrw_cikeep    = &l:ci
339  let {a:vt}netrw_cinkeep   = &l:cin
340  let {a:vt}netrw_cinokeep  = &l:cino
341  let {a:vt}netrw_comkeep   = &l:com
342  let {a:vt}netrw_cpokeep   = &l:cpo
343  if g:netrw_keepdir
344   let {a:vt}netrw_dirkeep  = getcwd()
345  endif
346  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
347  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
348  let {a:vt}netrw_hidkeep   = &l:hidden
349  let {a:vt}netrw_imkeep    = &l:im
350  let {a:vt}netrw_magickeep = &l:magic
351  let {a:vt}netrw_repkeep   = &l:report
352  let {a:vt}netrw_spellkeep = &l:spell
353  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
354  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
355  if has("win32") && !has("win95")
356   let {a:vt}netrw_swfkeep  = &l:swf          " swapfile
357  endif
358  if &go =~ 'a' | silent! let {a:vt}netrw_regstar = @* | endif
359  silent! let {a:vt}netrw_regslash= @/
360
361"  call Dret("s:NetrwOptionSave : win#".winnr()." buf#".bufnr("%"))
362endfun
363
364" ------------------------------------------------------------------------
365" s:NetrwOptionRestore: restore options {{{2
366fun! s:NetrwOptionRestore(vt)
367"  call Dfunc("s:NetrwOptionRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")." winnr($)=".winnr("$"))
368  if !exists("{a:vt}netrw_optionsave")
369"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
370"   call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist")
371   return
372  endif
373  unlet {a:vt}netrw_optionsave
374
375  if exists("&acd")
376   if exists("{a:vt}netrw_acdkeep")
377"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd)
378    let curdir = getcwd()
379    let &l:acd = {a:vt}netrw_acdkeep
380    unlet {a:vt}netrw_acdkeep
381    if &l:acd
382"     call Decho("exe keepjumps lcd ".fnameescape(curdir))  " NOTE: was g:netrw_fname_escape for some reason
383     try
384      if !exists("&l:acd") && !&l:acd
385       exe 'keepj lcd '.fnameescape(curdir)
386      endif
387     catch /^Vim\%((\a\+)\)\=:E472/
388      call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".curdir."> (permissions?)",61)
389     endtry
390    endif
391   endif
392  endif
393  if exists("{a:vt}netrw_aikeep")   |let &l:ai     = {a:vt}netrw_aikeep      |unlet {a:vt}netrw_aikeep   |endif
394  if exists("{a:vt}netrw_awkeep")   |let &l:aw     = {a:vt}netrw_awkeep      |unlet {a:vt}netrw_awkeep   |endif
395  if exists("{a:vt}netrw_bombkeep") |let &l:bomb   = {a:vt}netrw_bombkeep    |unlet {a:vt}netrw_bombkeep |endif
396  if exists("{a:vt}netrw_cikeep")   |let &l:ci     = {a:vt}netrw_cikeep      |unlet {a:vt}netrw_cikeep   |endif
397  if exists("{a:vt}netrw_cinkeep")  |let &l:cin    = {a:vt}netrw_cinkeep     |unlet {a:vt}netrw_cinkeep  |endif
398  if exists("{a:vt}netrw_cinokeep") |let &l:cino   = {a:vt}netrw_cinokeep    |unlet {a:vt}netrw_cinokeep |endif
399  if exists("{a:vt}netrw_comkeep")  |let &l:com    = {a:vt}netrw_comkeep     |unlet {a:vt}netrw_comkeep  |endif
400  if exists("{a:vt}netrw_cpokeep")  |let &l:cpo    = {a:vt}netrw_cpokeep     |unlet {a:vt}netrw_cpokeep  |endif
401  if exists("{a:vt}netrw_dirkeep") && isdirectory({a:vt}netrw_dirkeep) && g:netrw_keepdir
402   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
403   if exists("{a:vt}netrw_dirkeep")  |exe "keepjumps lcd ".fnameescape(dirkeep)|unlet {a:vt}netrw_dirkeep  |endif
404  endif
405  if exists("{a:vt}netrw_fokeep")   |let &l:fo     = {a:vt}netrw_fokeep      |unlet {a:vt}netrw_fokeep   |endif
406  if exists("{a:vt}netrw_gdkeep")   |let &l:gd     = {a:vt}netrw_gdkeep      |unlet {a:vt}netrw_gdkeep   |endif
407  if exists("{a:vt}netrw_hidkeep")  |let &l:hidden = {a:vt}netrw_hidkeep     |unlet {a:vt}netrw_hidkeep  |endif
408  if exists("{a:vt}netrw_imkeep")   |let &l:im     = {a:vt}netrw_imkeep      |unlet {a:vt}netrw_imkeep   |endif
409  if exists("{a:vt}netrw_magic")    |let &l:magic  = {a:vt}netrw_magic       |unlet {a:vt}netrw_magic    |endif
410  if exists("{a:vt}netrw_repkeep")  |let &l:report = {a:vt}netrw_repkeep     |unlet {a:vt}netrw_repkeep  |endif
411  if exists("{a:vt}netrw_spellkeep")|let &l:spell  = {a:vt}netrw_spellkeep   |unlet {a:vt}netrw_spellkeep|endif
412  if exists("{a:vt}netrw_twkeep")   |let &l:tw     = {a:vt}netrw_twkeep      |unlet {a:vt}netrw_twkeep   |endif
413  if exists("{a:vt}netrw_wigkeep")  |let &l:wig    = {a:vt}netrw_wigkeep     |unlet {a:vt}netrw_wigkeep  |endif
414  if exists("s:yykeep")             |let  @@       = s:yykeep                |unlet s:yykeep             |endif
415  if exists("{a:vt}netrw_swfkeep")
416   if &directory == ""
417    " user hasn't specified a swapfile directory;
418    " netrw will temporarily set the swapfile directory
419    " to the current directory as returned by getcwd().
420    let &l:directory   = getcwd()
421    silent! let &l:swf = {a:vt}netrw_swfkeep
422    setlocal directory=
423    unlet {a:vt}netrw_swfkeep
424   elseif &l:swf != {a:vt}netrw_swfkeep
425    " following line causes a Press ENTER in windows -- can't seem to work around it!!!
426    silent! let &l:swf= {a:vt}netrw_swfkeep
427    unlet {a:vt}netrw_swfkeep
428   endif
429  endif
430  if exists("{a:vt}netrw_regstar") |silent! let @*= {a:vt}netrw_regstar |unlet {a:vt}netrw_regstar |endif
431  if exists("{a:vt}netrw_regslash")|silent! let @/= {a:vt}netrw_regslash|unlet {a:vt}netrw_regslash|endif
432
433"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd)
434"  call Decho("fo=".&fo.(exists("&acd")? " acd=".&acd : " acd doesn't exist"))
435"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
436"  call Dret("s:NetrwOptionRestore : win#".winnr()." buf#".bufnr("%"))
437endfun
438
439" ---------------------------------------------------------------------
440" s:NetrwSafeOptions: sets options to help netrw do its job {{{2
441fun! s:NetrwSafeOptions()
442"  call Dfunc("s:NetrwSafeOptions() win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
443"  call Decho("win#".winnr()."'s ft=".&ft)
444  setlocal cino=
445  setlocal com=
446  setlocal cpo-=aA
447  if exists("&acd") | setlocal noacd | endif
448  setlocal nocin noai nobomb noci magic nospell nohid wig= noaw noim
449  setlocal fo=nroql2
450  setlocal tw=0
451  setlocal report=10000
452  setlocal isk+=@ isk+=* isk+=/
453  if g:netrw_use_noswf && has("win32") && !has("win95")
454   setlocal noswf
455  endif
456  call s:NetrwCursorline()
457
458  " allow the user to override safe options
459  if &ft == "netrw"
460"   call Decho("do any netrw FileType autocmds")
461   silent keepalt keepjumps doau FileType netrw
462  endif
463
464"  call Decho("fo=".&fo.(exists("&acd")? " acd=".&acd : " acd doesn't exist"))
465"  call Dret("s:NetrwSafeOptions")
466endfun
467
468" ---------------------------------------------------------------------
469" netrw#NetrwClean: remove netrw {{{2
470" supports :NetrwClean  -- remove netrw from first directory on runtimepath
471"          :NetrwClean! -- remove netrw from all directories on runtimepath
472fun! netrw#NetrwClean(sys)
473"  call Dfunc("netrw#NetrwClean(sys=".a:sys.")")
474
475  if a:sys
476   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
477  else
478   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
479  endif
480"  call Decho("choice=".choice)
481  let diddel= 0
482  let diddir= ""
483
484  if choice == 1
485   for dir in split(&rtp,',')
486    if filereadable(dir."/plugin/netrwPlugin.vim")
487"     call Decho("removing netrw-related files from ".dir)
488     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
489     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
490     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
491     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
492     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
493     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
494     let diddir= dir
495     let diddel= diddel + 1
496     if !a:sys|break|endif
497    endif
498   endfor
499  endif
500
501   echohl WarningMsg
502  if diddel == 0
503   echomsg "netrw is either not installed or not removable"
504  elseif diddel == 1
505   echomsg "removed one copy of netrw from <".diddir.">"
506  else
507   echomsg "removed ".diddel." copies of netrw"
508  endif
509   echohl None
510
511"  call Dret("netrw#NetrwClean")
512endfun
513
514" ---------------------------------------------------------------------
515" netrw#Nread: {{{2
516fun! netrw#Nread(mode,fname)
517"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
518  call netrw#NetrwSavePosn()
519  call netrw#NetRead(a:mode,a:fname)
520  call netrw#NetrwRestorePosn()
521"  call Dret("netrw#Nread")
522endfun
523
524" ------------------------------------------------------------------------
525"  Netrw Transfer Functions: {{{1
526" ===============================
527
528" ------------------------------------------------------------------------
529" netrw#NetRead: responsible for reading a file over the net {{{2
530"   mode: =0 read remote file and insert before current line
531"         =1 read remote file and insert after current line
532"         =2 replace with remote file
533"         =3 obtain file, but leave in temporary format
534fun! netrw#NetRead(mode,...)
535"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw)
536
537  " NetRead: save options {{{3
538  call s:NetrwOptionSave("w:")
539  call s:NetrwSafeOptions()
540  call s:RestoreCursorline()
541
542  " NetRead: interpret mode into a readcmd {{{3
543  if     a:mode == 0 " read remote file before current line
544   let readcmd = "0r"
545  elseif a:mode == 1 " read file after current line
546   let readcmd = "r"
547  elseif a:mode == 2 " replace with remote file
548   let readcmd = "%r"
549  elseif a:mode == 3 " skip read of file (leave as temporary)
550   let readcmd = "t"
551  else
552   exe a:mode
553   let readcmd = "r"
554  endif
555  let ichoice = (a:0 == 0)? 0 : 1
556"  call Decho("readcmd<".readcmd."> ichoice=".ichoice)
557
558  " NetRead: get temporary filename {{{3
559  let tmpfile= s:GetTempfile("")
560  if tmpfile == ""
561"   call Dret("netrw#NetRead : unable to get a tempfile!")
562   return
563  endif
564
565  while ichoice <= a:0
566
567   " attempt to repeat with previous host-file-etc
568   if exists("b:netrw_lastfile") && a:0 == 0
569"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">")
570    let choice = b:netrw_lastfile
571    let ichoice= ichoice + 1
572
573   else
574    exe "let choice= a:" . ichoice
575"    call Decho("no lastfile: choice<" . choice . ">")
576
577    if match(choice,"?") == 0
578     " give help
579     echomsg 'NetRead Usage:'
580     echomsg ':Nread machine:path                         uses rcp'
581     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
582     echomsg ':Nread "machine id password path"           uses ftp'
583     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
584     echomsg ':Nread fetch://machine/path                 uses fetch'
585     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
586     echomsg ':Nread http://[user@]machine/path           uses http  wget'
587     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
588     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
589     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
590     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
591     sleep 4
592     break
593
594    elseif match(choice,'^"') != -1
595     " Reconstruct Choice if choice starts with '"'
596"     call Decho("reconstructing choice")
597     if match(choice,'"$') != -1
598      " case "..."
599      let choice=strpart(choice,1,strlen(choice)-2)
600     else
601       "  case "... ... ..."
602      let choice      = strpart(choice,1,strlen(choice)-1)
603      let wholechoice = ""
604
605      while match(choice,'"$') == -1
606       let wholechoice = wholechoice . " " . choice
607       let ichoice     = ichoice + 1
608       if ichoice > a:0
609       	if !exists("g:netrw_quiet")
610	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
611	endif
612"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
613        return
614       endif
615       let choice= a:{ichoice}
616      endwhile
617      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
618     endif
619    endif
620   endif
621
622"   call Decho("choice<" . choice . ">")
623   let ichoice= ichoice + 1
624
625   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
626   call s:NetrwMethod(choice)
627   if !exists("b:netrw_method") || b:netrw_method < 0
628"    call Dfunc("netrw#NetRead : unsupported method")
629    return
630   endif
631   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
632
633   " Check if NetrwBrowse() should be handling this request
634"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">")
635   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^http://'
636"    call Decho("yes, choice matches '^.*[\/]$'")
637    keepj call s:NetrwBrowse(0,choice)
638"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
639    return
640   endif
641
642   " ============
643   " NetRead: Perform Protocol-Based Read {{{3
644   " ===========================
645   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
646    echo "(netrw) Processing your read request..."
647   endif
648
649   ".........................................
650   " NetRead: (rcp)  NetRead Method #1 {{{3
651   if  b:netrw_method == 1 " read with rcp
652"    call Decho("read via rcp (method #1)")
653   " ER: nothing done with g:netrw_uid yet?
654   " ER: on Win2K" rcp machine[.user]:file tmpfile
655   " ER: if machine contains '.' adding .user is required (use $USERNAME)
656   " ER: the tmpfile is full path: rcp sees C:\... as host C
657   if s:netrw_has_nt_rcp == 1
658    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
659     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
660    else
661     " Any way needed it machine contains a '.'
662     let uid_machine = g:netrw_machine .'.'. $USERNAME
663    endif
664   else
665    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
666     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
667    else
668     let uid_machine = g:netrw_machine
669    endif
670   endif
671"   call Decho("executing: !".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".shellescape(uid_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1))
672   exe s:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".shellescape(uid_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1)
673   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
674   let b:netrw_lastfile = choice
675
676   ".........................................
677   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
678   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
679"     call Decho("read via ftp+.netrc (method #2)")
680     let netrw_fname= b:netrw_fname
681     call s:SaveBufVars()|new|call s:RestoreBufVars()
682     let filtbuf= bufnr("%")
683     setlocal ff=unix
684     keepj put =g:netrw_ftpmode
685"     call Decho("filter input: ".getline(line("$")))
686     if exists("g:netrw_ftpextracmd")
687      keepj put =g:netrw_ftpextracmd
688"      call Decho("filter input: ".getline(line("$")))
689     endif
690     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
691"     call Decho("filter input: ".getline(line("$")))
692     if exists("g:netrw_port") && g:netrw_port != ""
693"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine." ".g:netrw_port,1))
694      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine." ".g:netrw_port,1)
695     else
696"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
697      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
698     endif
699     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
700     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
701      let debugkeep = &debug
702      setlocal debug=msg
703      call netrw#ErrorMsg(s:ERROR,getline(1),4)
704      let &debug    = debugkeep
705     endif
706     call s:SaveBufVars()
707     bd!
708     if bufname("%") == "" && getline("$") == "" && line('$') == 1
709      " needed when one sources a file in a nolbl setting window via ftp
710      q!
711     endif
712     call s:RestoreBufVars()
713     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
714     let b:netrw_lastfile = choice
715
716   ".........................................
717   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
718   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
719    " Construct execution string (four lines) which will be passed through filter
720"    call Decho("read via ftp+mipf (method #3)")
721    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
722    call s:SaveBufVars()|new|call s:RestoreBufVars()
723    let filtbuf= bufnr("%")
724    setlocal ff=unix
725    if exists("g:netrw_port") && g:netrw_port != ""
726     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
727"     call Decho("filter input: ".getline('.'))
728    else
729     keepj put ='open '.g:netrw_machine
730"     call Decho("filter input: ".getline('.'))
731    endif
732
733    if exists("g:netrw_ftp") && g:netrw_ftp == 1
734     keepj put =g:netrw_uid
735"     call Decho("filter input: ".getline('.'))
736     keepj put ='\"'.s:netrw_passwd.'\"'
737"     call Decho("filter input: ".getline('.'))
738    else
739     keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
740"     call Decho("filter input: ".getline('.'))
741    endif
742
743    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
744     keepj put =g:netrw_ftpmode
745"     call Decho("filter input: ".getline('.'))
746    endif
747    if exists("g:netrw_ftpextracmd")
748     put =g:netrw_ftpextracmd
749"     call Decho("filter input: ".getline('.'))
750    endif
751    keepj put ='get \"'.netrw_fname.'\" '.tmpfile
752"    call Decho("filter input: ".getline('.'))
753
754    " perform ftp:
755    " -i       : turns off interactive prompting from ftp
756    " -n  unix : DON'T use <.netrc>, even though it exists
757    " -n  win32: quit being obnoxious about password
758    norm! 1Gdd
759"    call Decho("executing: %!".g:netrw_ftp_cmd." -i -n")
760    exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
761    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
762    if getline(1) !~ "^$"
763"     call Decho("error<".getline(1).">")
764     if !exists("g:netrw_quiet")
765      call netrw#ErrorMsg(s:ERROR,getline(1),5)
766     endif
767    endif
768    call s:SaveBufVars()|bd!|call s:RestoreBufVars()
769    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
770    let b:netrw_lastfile = choice
771
772   ".........................................
773   " NetRead: (scp) NetRead Method #4 {{{3
774   elseif     b:netrw_method  == 4	" read with scp
775"    call Decho("read via scp (method #4)")
776    if exists("g:netrw_port") && g:netrw_port != ""
777     let useport= " ".g:netrw_scpport." ".g:netrw_port
778    else
779     let useport= ""
780    endif
781"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1))
782    exe s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1)
783    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
784    let b:netrw_lastfile = choice
785
786   ".........................................
787   " NetRead: (http) NetRead Method #5 (wget) {{{3
788   elseif     b:netrw_method  == 5
789"    call Decho("read via http (method #5)")
790    if g:netrw_http_cmd == ""
791     if !exists("g:netrw_quiet")
792      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
793     endif
794"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
795     return
796    endif
797
798    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
799     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
800"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)")
801     if exists("g:netrw_http_xcmd")
802"      call Decho("exe ".s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape("http://".g:netrw_machine.b:netrw_fname,1)." ".g:netrw_http_xcmd." ".shellescape(tmpfile,1))
803      exe s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape("http://".g:netrw_machine.b:netrw_fname,1)." ".g:netrw_http_xcmd." ".shellescape(tmpfile,1)
804     else
805"      call Decho("exe ".s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape(tmpfile,1)." ".shellescape("http://".g:netrw_machine.b:netrw_fname,1))
806      exe s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape(tmpfile,1)." ".shellescape("http://".g:netrw_machine.b:netrw_fname,1)
807     endif
808     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
809
810    else
811     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
812"     call Decho(("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)")
813     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
814     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
815"     call Decho("netrw_html<".netrw_html.">")
816"     call Decho("netrw_tag <".netrw_tag.">")
817"     call Decho("exe ".s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape(tmpfile,1)." ".shellescape("http://".g:netrw_machine.netrw_html,1))
818     exe s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape(tmpfile,1)." ".shellescape("http://".g:netrw_machine.netrw_html,1)
819     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
820"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/')
821     exe 'norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
822    endif
823    let b:netrw_lastfile = choice
824    setlocal ro
825
826   ".........................................
827   " NetRead: (dav) NetRead Method #6 {{{3
828   elseif     b:netrw_method  == 6
829"    call Decho("read via cadaver (method #6)")
830
831    if !executable(g:netrw_dav_cmd)
832     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
833"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
834     return
835    endif
836    if g:netrw_dav_cmd =~ "curl"
837"     call Decho("exe ".s:netrw_silentxfer."!".g:netrw_dav_cmd." ".shellescape("dav://".g:netrw_machine.b:netrw_fname,1)." ".shellescape(tmpfile,1))
838     exe s:netrw_silentxfer."!".g:netrw_dav_cmd." ".shellescape("dav://".g:netrw_machine.b:netrw_fname,1)." ".shellescape(tmpfile,1)
839    else
840     " Construct execution string (four lines) which will be passed through filter
841     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
842     new
843     setlocal ff=unix
844     if exists("g:netrw_port") && g:netrw_port != ""
845      keepj put ='open '.g:netrw_machine.' '.g:netrw_port
846     else
847      keepj put ='open '.g:netrw_machine
848     endif
849     keepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
850     keepj put ='get '.netrw_fname.' '.tmpfile
851     keepj put ='quit'
852
853     " perform cadaver operation:
854     keepj norm! 1Gdd
855"    call Decho("executing: %!".g:netrw_dav_cmd)
856     exe s:netrw_silentxfer."%!".g:netrw_dav_cmd
857     bd!
858    endif
859    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
860    let b:netrw_lastfile = choice
861
862   ".........................................
863   " NetRead: (rsync) NetRead Method #7 {{{3
864   elseif     b:netrw_method  == 7
865"    call Decho("read via rsync (method #7)")
866"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1))
867    exe s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1)
868    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
869    let b:netrw_lastfile = choice
870
871   ".........................................
872   " NetRead: (fetch) NetRead Method #8 {{{3
873   "    fetch://[user@]host[:http]/path
874   elseif     b:netrw_method  == 8
875"    call Decho("read via fetch (method #8)")
876    if g:netrw_fetch_cmd == ""
877     if !exists("g:netrw_quiet")
878      call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
879     endif
880"     call Dret("NetRead")
881    endif
882    if exists("g:netrw_option") && g:netrw_option == ":http"
883     let netrw_option= "http"
884    else
885     let netrw_option= "ftp"
886    endif
887"    call Decho("read via fetch for ".netrw_option)
888
889    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
890"     call Decho("exe ".s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".shellescape(tmpfile,1)." ".shellescape(netrw_option."://".g:netrw_uid.':'.s:netrw_passwd.'@'.g:netrw_machine."/".b:netrw_fname,1))
891     exe s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".shellescape(tmpfile,1)." ".shellescape(netrw_option."://".g:netrw_uid.':'.s:netrw_passwd.'@'.g:netrw_machine."/".b:netrw_fname,1)
892    else
893"     call Decho("exe ".s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".shellescape(tmpfile,1)." ".shellescape(netrw_option."://".g:netrw_machine."/".b:netrw_fname,1))
894     exe s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".shellescape(tmpfile,1)." ".shellescape(netrw_option."://".g:netrw_machine."/".b:netrw_fname,1)
895    endif
896
897    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
898    let b:netrw_lastfile = choice
899    setlocal ro
900
901   ".........................................
902   " NetRead: (sftp) NetRead Method #9 {{{3
903   elseif     b:netrw_method  == 9
904"    call Decho("read via sftp (method #9)")
905"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
906    exe s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile
907    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
908    let b:netrw_lastfile = choice
909
910   ".........................................
911   " NetRead: Complain {{{3
912   else
913    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
914   endif
915  endwhile
916
917  " NetRead: cleanup {{{3
918  if exists("b:netrw_method")
919"   call Decho("cleanup b:netrw_method and b:netrw_fname")
920   unlet b:netrw_method
921   unlet b:netrw_fname
922  endif
923  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't'
924"   call Decho("cleanup by deleting tmpfile<".tmpfile.">")
925   call s:NetrwDelete(tmpfile)
926  endif
927  call s:NetrwOptionRestore("w:")
928
929"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
930endfun
931
932" ------------------------------------------------------------------------
933" netrw#NetWrite: responsible for writing a file over the net {{{2
934fun! netrw#NetWrite(...) range
935"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
936
937  " NetWrite: option handling {{{3
938  let mod= 0
939  call s:NetrwOptionSave("w:")
940  call s:NetrwSafeOptions()
941
942  " NetWrite: Get Temporary Filename {{{3
943  let tmpfile= s:GetTempfile("")
944  if tmpfile == ""
945"   call Dret("netrw#NetWrite : unable to get a tempfile!")
946   return
947  endif
948
949  if a:0 == 0
950   let ichoice = 0
951  else
952   let ichoice = 1
953  endif
954
955  let curbufname= expand("%")
956"  call Decho("curbufname<".curbufname.">")
957  if &binary
958   " For binary writes, always write entire file.
959   " (line numbers don't really make sense for that).
960   " Also supports the writing of tar and zip files.
961"   call Decho("(write entire file) silent exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile))
962   exe "silent keepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
963  elseif g:netrw_cygwin
964   " write (selected portion of) file to temporary
965   let cygtmpfile= substitute(tmpfile,'/cygdrive/\(.\)','\1:','')
966"   call Decho("(write selected portion) silent exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile))
967   exe "sil keepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
968  else
969   " write (selected portion of) file to temporary
970"   call Decho("(write selected portion) silent exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile))
971   exe "sil keepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
972  endif
973
974  if curbufname == ""
975   " if the file is [No Name], and one attempts to Nwrite it, the buffer takes
976   " on the temporary file's name.  Deletion of the temporary file during
977   " cleanup then causes an error message.
978   0file!
979  endif
980
981  " NetWrite: while choice loop: {{{3
982  while ichoice <= a:0
983
984   " Process arguments: {{{4
985   " attempt to repeat with previous host-file-etc
986   if exists("b:netrw_lastfile") && a:0 == 0
987"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">")
988    let choice = b:netrw_lastfile
989    let ichoice= ichoice + 1
990   else
991    exe "let choice= a:" . ichoice
992
993    " Reconstruct Choice if choice starts with '"'
994    if match(choice,"?") == 0
995     echomsg 'NetWrite Usage:"'
996     echomsg ':Nwrite machine:path                        uses rcp'
997     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
998     echomsg ':Nwrite "machine id password path"          uses ftp'
999     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
1000     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
1001     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
1002     echomsg ':Nwrite rcp://machine/path                  uses rcp'
1003     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
1004     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
1005     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
1006     sleep 4
1007     break
1008
1009    elseif match(choice,"^\"") != -1
1010     if match(choice,"\"$") != -1
1011       " case "..."
1012      let choice=strpart(choice,1,strlen(choice)-2)
1013     else
1014      "  case "... ... ..."
1015      let choice      = strpart(choice,1,strlen(choice)-1)
1016      let wholechoice = ""
1017
1018      while match(choice,"\"$") == -1
1019       let wholechoice= wholechoice . " " . choice
1020       let ichoice    = ichoice + 1
1021       if choice > a:0
1022       	if !exists("g:netrw_quiet")
1023	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
1024	endif
1025"        call Dret("netrw#NetWrite")
1026        return
1027       endif
1028       let choice= a:{ichoice}
1029      endwhile
1030      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
1031     endif
1032    endif
1033   endif
1034   let ichoice= ichoice + 1
1035"   call Decho("choice<" . choice . "> ichoice=".ichoice)
1036
1037   " Determine method of write (ftp, rcp, etc) {{{4
1038   call s:NetrwMethod(choice)
1039   if !exists("b:netrw_method") || b:netrw_method < 0
1040"    call Dfunc("netrw#NetWrite : unsupported method")
1041    return
1042   endif
1043
1044   " =============
1045   " NetWrite: Perform Protocol-Based Write {{{3
1046   " ============================
1047   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
1048    echo "(netrw) Processing your write request..."
1049"    call Decho("(netrw) Processing your write request...")
1050   endif
1051
1052   ".........................................
1053   " NetWrite: (rcp) NetWrite Method #1 {{{3
1054   if  b:netrw_method == 1
1055"    call Decho("write via rcp (method #1)")
1056    if s:netrw_has_nt_rcp == 1
1057     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
1058      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
1059     else
1060      let uid_machine = g:netrw_machine .'.'. $USERNAME
1061     endif
1062    else
1063     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
1064      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
1065     else
1066      let uid_machine = g:netrw_machine
1067     endif
1068    endif
1069"    call Decho("executing: !".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".shellescape(tmpfile,1)." ".shellescape(uid_machine.":".b:netrw_fname,1))
1070    exe s:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".shellescape(tmpfile,1)." ".shellescape(uid_machine.":".b:netrw_fname,1)
1071    let b:netrw_lastfile = choice
1072
1073   ".........................................
1074   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
1075   elseif b:netrw_method == 2
1076"    call Decho("write via ftp+.netrc (method #2)")
1077    let netrw_fname = b:netrw_fname
1078
1079    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
1080    let bhkeep      = &l:bh
1081    let curbuf      = bufnr("%")
1082    setlocal bh=hide
1083    enew
1084
1085"    call Decho("filter input window#".winnr())
1086    setlocal ff=unix
1087    keepj put =g:netrw_ftpmode
1088"    call Decho("filter input: ".getline('$'))
1089    if exists("g:netrw_ftpextracmd")
1090     keepj put =g:netrw_ftpextracmd
1091"     call Decho("filter input: ".getline("$"))
1092    endif
1093    call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
1094"    call Decho("filter input: ".getline("$"))
1095    if exists("g:netrw_port") && g:netrw_port != ""
1096"     call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1))
1097     exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1)
1098    else
1099"     call Decho("filter input window#".winnr())
1100"     call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
1101     exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
1102    endif
1103    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1104    if getline(1) !~ "^$"
1105     if !exists("g:netrw_quiet")
1106      call netrw#ErrorMsg(s:ERROR,getline(1),14)
1107     endif
1108     let mod=1
1109    endif
1110
1111    " remove enew buffer (quietly)
1112    let filtbuf= bufnr("%")
1113    exe curbuf."b!"
1114    let &l:bh            = bhkeep
1115    exe filtbuf."bw!"
1116
1117    let b:netrw_lastfile = choice
1118
1119   ".........................................
1120   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
1121   elseif b:netrw_method == 3
1122    " Construct execution string (three or more lines) which will be passed through filter
1123"    call Decho("read via ftp+mipf (method #3)")
1124    let netrw_fname = b:netrw_fname
1125    let bhkeep      = &l:bh
1126
1127    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
1128    let curbuf      = bufnr("%")
1129    setlocal bh=hide
1130    enew
1131    setlocal ff=unix
1132
1133    if exists("g:netrw_port") && g:netrw_port != ""
1134     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
1135"     call Decho("filter input: ".getline('.'))
1136    else
1137     keepj put ='open '.g:netrw_machine
1138"     call Decho("filter input: ".getline('.'))
1139    endif
1140    if exists("g:netrw_ftp") && g:netrw_ftp == 1
1141     keepj put =g:netrw_uid
1142"     call Decho("filter input: ".getline('.'))
1143     keepj put ='\"'.s:netrw_passwd.'\"'
1144"     call Decho("filter input: ".getline('.'))
1145    else
1146     keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1147"     call Decho("filter input: ".getline('.'))
1148    endif
1149    keepj put =g:netrw_ftpmode
1150"    call Decho("filter input: ".getline('$'))
1151    if exists("g:netrw_ftpextracmd")
1152     keepj put =g:netrw_ftpextracmd
1153"     call Decho("filter input: ".getline("$"))
1154    endif
1155    keepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
1156"    call Decho("filter input: ".getline('.'))
1157    " save choice/id/password for future use
1158    let b:netrw_lastfile = choice
1159
1160    " perform ftp:
1161    " -i       : turns off interactive prompting from ftp
1162    " -n  unix : DON'T use <.netrc>, even though it exists
1163    " -n  win32: quit being obnoxious about password
1164    keepj norm! 1Gdd
1165"    call Decho("executing: %!".g:netrw_ftp_cmd." -i -n")
1166    exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
1167    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1168    if getline(1) !~ "^$"
1169     if  !exists("g:netrw_quiet")
1170      call netrw#ErrorMsg(s:ERROR,getline(1),15)
1171     endif
1172     let mod=1
1173    endif
1174
1175    " remove enew buffer (quietly)
1176    let filtbuf= bufnr("%")
1177    exe curbuf."b!"
1178    let &l:bh= bhkeep
1179    exe filtbuf."bw!"
1180
1181   ".........................................
1182   " NetWrite: (scp) NetWrite Method #4 {{{3
1183   elseif     b:netrw_method == 4
1184"    call Decho("write via scp (method #4)")
1185    if exists("g:netrw_port") && g:netrw_port != ""
1186     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
1187    else
1188     let useport= ""
1189    endif
1190"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".shellescape(tmpfile,1)." ".shellescape(g:netrw_machine.":".b:netrw_fname,1))
1191    exe s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".shellescape(tmpfile,1)." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)
1192    let b:netrw_lastfile = choice
1193
1194   ".........................................
1195   " NetWrite: (http) NetWrite Method #5 {{{3
1196   elseif     b:netrw_method == 5
1197"    call Decho("write via http (method #5)")
1198    if !exists("g:netrw_quiet")
1199     call netrw#ErrorMsg(s:ERROR,"currently <netrw.vim> does not support writing using http:",16)
1200    endif
1201
1202   ".........................................
1203   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
1204   elseif     b:netrw_method == 6
1205"    call Decho("write via cadaver (method #6)")
1206
1207    " Construct execution string (four lines) which will be passed through filter
1208    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
1209    let bhkeep      = &l:bh
1210
1211    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
1212    let curbuf      = bufnr("%")
1213    setlocal bh=hide
1214    enew
1215
1216    setlocal ff=unix
1217    if exists("g:netrw_port") && g:netrw_port != ""
1218     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
1219    else
1220     keepj put ='open '.g:netrw_machine
1221    endif
1222    if exists("g:netrw_uid") && exists("s:netrw_passwd")
1223     keepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
1224    endif
1225    keepj put ='put '.tmpfile.' '.netrw_fname
1226
1227    " perform cadaver operation:
1228    keepj norm! 1Gdd
1229"    call Decho("executing: %!".g:netrw_dav_cmd)
1230    exe s:netrw_silentxfer."%!".g:netrw_dav_cmd
1231
1232    " remove enew buffer (quietly)
1233    let filtbuf= bufnr("%")
1234    exe curbuf."b!"
1235    let &l:bh            = bhkeep
1236    exe filtbuf."bw!"
1237
1238    let b:netrw_lastfile = choice
1239
1240   ".........................................
1241   " NetWrite: (rsync) NetWrite Method #7 {{{3
1242   elseif     b:netrw_method == 7
1243"    call Decho("write via rsync (method #7)")
1244"    call Decho("executing: !".g:netrw_rsync_cmd." ".shellescape(tmpfile,1)." ".shellescape(g:netrw_machine.":".b:netrw_fname,1))
1245    exe s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".shellescape(tmpfile,1)." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)
1246    let b:netrw_lastfile = choice
1247
1248   ".........................................
1249   " NetWrite: (sftp) NetWrite Method #9 {{{3
1250   elseif     b:netrw_method == 9
1251"    call Decho("read via sftp (method #9)")
1252    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
1253    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
1254     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
1255    else
1256     let uid_machine = g:netrw_machine
1257    endif
1258
1259    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
1260    let bhkeep = &l:bh
1261    let curbuf = bufnr("%")
1262    setlocal bh=hide
1263    enew
1264
1265    setlocal ff=unix
1266    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
1267"    call Decho("filter input: ".getline('.'))
1268"    call Decho("executing: %!".g:netrw_sftp_cmd.' '.shellescape(uid_machine,1))
1269    exe s:netrw_silentxfer."%!".g:netrw_sftp_cmd.' '.shellescape(uid_machine,1)
1270    let filtbuf= bufnr("%")
1271    exe curbuf."b!"
1272    let &l:bh            = bhkeep
1273    exe filtbuf."bw!"
1274    let b:netrw_lastfile = choice
1275
1276   ".........................................
1277   " NetWrite: Complain {{{3
1278   else
1279    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
1280   endif
1281  endwhile
1282
1283  " NetWrite: Cleanup: {{{3
1284"  call Decho("cleanup")
1285  if s:FileReadable(tmpfile)
1286"   call Decho("tmpfile<".tmpfile."> readable, will now delete it")
1287   call s:NetrwDelete(tmpfile)
1288  endif
1289  call s:NetrwOptionRestore("w:")
1290
1291  if a:firstline == 1 && a:lastline == line("$")
1292   " restore modifiability; usually equivalent to set nomod
1293   let &mod= mod
1294  endif
1295
1296  " restore equalalways
1297"  call Dret("netrw#NetWrite")
1298endfun
1299
1300" ---------------------------------------------------------------------
1301" netrw#NetSource: source a remotely hosted vim script {{{2
1302" uses NetRead to get a copy of the file into a temporarily file,
1303"              then sources that file,
1304"              then removes that file.
1305fun! netrw#NetSource(...)
1306"  call Dfunc("netrw#NetSource() a:0=".a:0)
1307  if a:0 > 0 && a:1 == '?'
1308   " give help
1309   echomsg 'NetSource Usage:'
1310   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
1311   echomsg ':Nsource fetch://machine/path                 uses fetch'
1312   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
1313   echomsg ':Nsource http://[user@]machine/path           uses http  wget'
1314   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
1315   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
1316   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
1317   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
1318   sleep 4
1319  else
1320   let i= 1
1321   while i <= a:0
1322    call netrw#NetRead(3,a:{i})
1323"    call Decho("(netrw#NetSource) s:netread_tmpfile<".s:netrw_tmpfile.">")
1324    if s:FileReadable(s:netrw_tmpfile)
1325"     call Decho("(netrw#NetSource) exe so ".fnameescape(s:netrw_tmpfile))
1326     exe "so ".fnameescape(s:netrw_tmpfile)
1327"     call Decho("(netrw#NetSource) delete(".s:netrw_tmpfile.")")
1328     call delete(s:netrw_tmpfile)
1329     unlet s:netrw_tmpfile
1330    else
1331     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
1332    endif
1333    let i= i + 1
1334   endwhile
1335  endif
1336"  call Dret("netrw#NetSource")
1337endfun
1338
1339" ===========================================
1340" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
1341"    readcmd == %r : replace buffer with newly read file
1342"            == 0r : read file at top of buffer
1343"            == r  : read file after current line
1344"            == t  : leave file in temporary form (ie. don't read into buffer)
1345fun! s:NetrwGetFile(readcmd, tfile, method)
1346"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
1347
1348  " readcmd=='t': simply do nothing
1349  if a:readcmd == 't'
1350"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
1351"   call Dret("NetrwGetFile : skip read of <".a:tfile.">")
1352   return
1353  endif
1354
1355  " get name of remote filename (ie. url and all)
1356  let rfile= bufname("%")
1357"  call Decho("rfile<".rfile.">")
1358
1359  if exists("*NetReadFixup")
1360   " for the use of NetReadFixup (not otherwise used internally)
1361   let line2= line("$")
1362  endif
1363
1364  if a:readcmd[0] == '%'
1365  " get file into buffer
1366"   call Decho("get file into buffer")
1367
1368   " rename the current buffer to the temp file (ie. tfile)
1369   if g:netrw_cygwin
1370    let tfile= substitute(a:tfile,'/cygdrive/\(.\)','\1:','')
1371   else
1372    let tfile= a:tfile
1373   endif
1374"   call Decho("exe silent! keepalt file ".fnameescape(tfile))
1375   exe "silent! keepalt file ".fnameescape(tfile)
1376
1377   " edit temporary file (ie. read the temporary file in)
1378   if     rfile =~ '\.zip$'
1379"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)")
1380    call zip#Browse(tfile)
1381   elseif rfile =~ '\.tar$'
1382"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)")
1383    call tar#Browse(tfile)
1384   elseif rfile =~ '\.tar\.gz'
1385"    call Decho("handling remote gzip-compressed tar file")
1386    call tar#Browse(tfile)
1387   elseif rfile =~ '\.tar\.bz2'
1388"    call Decho("handling remote bz2-compressed tar file")
1389    call tar#Browse(tfile)
1390   else
1391"    call Decho("edit temporary file")
1392    e!
1393   endif
1394
1395   " rename buffer back to remote filename
1396"   call Decho("exe silent! keepalt file ".fnameescape(rfile))
1397   exe "sil! keepalt file ".fnameescape(rfile)
1398   filetype detect
1399"   call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!")
1400   let line1 = 1
1401   let line2 = line("$")
1402
1403  elseif s:FileReadable(a:tfile)
1404   " read file after current line
1405"   call Decho("read file<".a:tfile."> after current line")
1406   let curline = line(".")
1407   let lastline= line("$")
1408"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline)
1409   exe a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
1410   let line1= curline + 1
1411   let line2= line("$") - lastline + 1
1412
1413  else
1414   " not readable
1415"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
1416"   call Decho("tfile<".a:tfile."> not readable")
1417   call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
1418"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
1419   return
1420  endif
1421
1422  " User-provided (ie. optional) fix-it-up command
1423  if exists("*NetReadFixup")
1424"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")")
1425   call NetReadFixup(a:method, line1, line2)
1426"  else " Decho
1427"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")")
1428  endif
1429
1430  if has("gui") && has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
1431   " update the Buffers menu
1432   call s:UpdateBuffersMenu()
1433  endif
1434
1435"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile))
1436
1437 " make sure file is being displayed
1438"  redraw!
1439
1440"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
1441"  call Dret("NetrwGetFile")
1442endfun
1443
1444" ------------------------------------------------------------------------
1445" s:NetrwMethod:  determine method of transfer {{{2
1446" Input:
1447"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
1448" Output:
1449"  b:netrw_method= 1: rcp
1450"                  2: ftp + <.netrc>
1451"	           3: ftp + machine, id, password, and [path]filename
1452"	           4: scp
1453"	           5: http (wget)
1454"	           6: dav
1455"	           7: rsync
1456"	           8: fetch
1457"	           9: sftp
1458"  g:netrw_machine= hostname
1459"  b:netrw_fname  = filename
1460"  g:netrw_port   = optional port number (for ftp)
1461"  g:netrw_choice = copy of input url (choice)
1462fun! s:NetrwMethod(choice)
1463"   call Dfunc("NetrwMethod(a:choice<".a:choice.">)")
1464
1465   " record current g:netrw_machine, if any
1466   " curmachine used if protocol == ftp and no .netrc
1467   if exists("g:netrw_machine")
1468    let curmachine= g:netrw_machine
1469"    call Decho("curmachine<".curmachine.">")
1470   else
1471    let curmachine= "N O T A HOST"
1472   endif
1473
1474  " initialization
1475  let b:netrw_method  = 0
1476  let g:netrw_machine = ""
1477  let b:netrw_fname   = ""
1478  let g:netrw_port    = ""
1479  let g:netrw_choice  = a:choice
1480
1481  " Patterns:
1482  " mipf     : a:machine a:id password filename	     Use ftp
1483  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
1484  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
1485  " rcpurm   : rcp://[user@]host/filename	     Use rcp
1486  " rcphf    : [user@]host:filename		     Use rcp
1487  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
1488  " httpurm  : http://[user@]host/filename	     Use wget
1489  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
1490  " rsyncurm : rsync://host[:port]/path              Use rsync
1491  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
1492  " sftpurm  : sftp://[user@]host/filename  Use scp
1493  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
1494  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
1495  let ftpurm   = '^ftp://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
1496  let rcpurm   = '^rcp://\%(\([^/@]\{-}\)@\)\=\([^/]\{-}\)/\(.*\)$'
1497  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
1498  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
1499  let httpurm  = '^http://\([^/]\{-}\)\(/.*\)\=$'
1500  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
1501  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
1502  let fetchurm = '^fetch://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
1503  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
1504
1505"  call Decho("determine method:")
1506  " Determine Method
1507  " rcp://user@hostname/...path-to-file
1508  if match(a:choice,rcpurm) == 0
1509"   call Decho("rcp://...")
1510   let b:netrw_method  = 1
1511   let userid          = substitute(a:choice,rcpurm,'\1',"")
1512   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
1513   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
1514   if userid != ""
1515    let g:netrw_uid= userid
1516   endif
1517
1518  " scp://user@hostname/...path-to-file
1519  elseif match(a:choice,scpurm) == 0
1520"   call Decho("scp://...")
1521   let b:netrw_method  = 4
1522   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
1523   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
1524   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
1525
1526  " http://user@hostname/...path-to-file
1527  elseif match(a:choice,httpurm) == 0
1528"   call Decho("http://...")
1529   let b:netrw_method = 5
1530   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
1531   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
1532
1533  " dav://hostname[:port]/..path-to-file..
1534  elseif match(a:choice,davurm) == 0
1535"   call Decho("dav://...")
1536   let b:netrw_method= 6
1537   if a:choice =~ '^s'
1538    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
1539   else
1540    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
1541   endif
1542   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
1543
1544  " rsync://user@hostname/...path-to-file
1545  elseif match(a:choice,rsyncurm) == 0
1546"   call Decho("rsync://...")
1547   let b:netrw_method = 7
1548   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
1549   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
1550
1551  " ftp://[user@]hostname[[:#]port]/...path-to-file
1552  elseif match(a:choice,ftpurm) == 0
1553"   call Decho("ftp://...")
1554   let userid	      = substitute(a:choice,ftpurm,'\2',"")
1555   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
1556   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
1557   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
1558"   call Decho("g:netrw_machine<".g:netrw_machine.">")
1559   if userid != ""
1560    let g:netrw_uid= userid
1561   endif
1562   if exists("s:netrw_passwd") && curmachine != g:netrw_machine
1563    " if there's a change in hostname, require password re-entry
1564    unlet s:netrw_passwd
1565   endif
1566   if exists("g:netrw_uid") && exists("s:netrw_passwd")
1567    let b:netrw_method = 3
1568   else
1569    if s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
1570     let b:netrw_method= 2
1571    else
1572     if !exists("g:netrw_uid") || g:netrw_uid == ""
1573      call NetUserPass()
1574     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
1575      call NetUserPass(g:netrw_uid)
1576    " else just use current g:netrw_uid and s:netrw_passwd
1577     endif
1578     let b:netrw_method= 3
1579    endif
1580   endif
1581
1582  elseif match(a:choice,fetchurm) == 0
1583"   call Decho("fetch://...")
1584   let b:netrw_method = 8
1585   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
1586   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
1587   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
1588   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
1589
1590  " Issue an ftp : "machine id password [path/]filename"
1591  elseif match(a:choice,mipf) == 0
1592"   call Decho("(ftp) host id pass file")
1593   let b:netrw_method  = 3
1594   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
1595   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
1596   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
1597   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
1598
1599  " Issue an ftp: "hostname [path/]filename"
1600  elseif match(a:choice,mf) == 0
1601"   call Decho("(ftp) host file")
1602   if exists("g:netrw_uid") && exists("s:netrw_passwd")
1603    let b:netrw_method  = 3
1604    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
1605    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
1606
1607   elseif s:FileReadable(expand("$HOME/.netrc"))
1608    let b:netrw_method  = 2
1609    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
1610    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
1611   endif
1612
1613  " sftp://user@hostname/...path-to-file
1614  elseif match(a:choice,sftpurm) == 0
1615"   call Decho("sftp://...")
1616   let b:netrw_method = 9
1617   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
1618   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
1619
1620  " Issue an rcp: hostname:filename"  (this one should be last)
1621  elseif match(a:choice,rcphf) == 0
1622"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">")
1623   let b:netrw_method  = 1
1624   let userid          = substitute(a:choice,rcphf,'\2',"")
1625   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
1626   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
1627"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">")
1628"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">")
1629"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">")
1630"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">")
1631   if userid != ""
1632    let g:netrw_uid= userid
1633   endif
1634
1635  else
1636   if !exists("g:netrw_quiet")
1637    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
1638   endif
1639   let b:netrw_method  = -1
1640  endif
1641
1642  " remove any leading [:#] from port number
1643  if g:netrw_port != ""
1644    let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
1645  endif
1646
1647"  call Decho("a:choice       <".a:choice.">")
1648"  call Decho("b:netrw_method <".b:netrw_method.">")
1649"  call Decho("g:netrw_machine<".g:netrw_machine.">")
1650"  call Decho("g:netrw_port   <".g:netrw_port.">")
1651"  if exists("g:netrw_uid")		"Decho
1652"   call Decho("g:netrw_uid    <".g:netrw_uid.">")
1653"  endif					"Decho
1654"  if exists("s:netrw_passwd")		"Decho
1655"   call Decho("s:netrw_passwd <".s:netrw_passwd.">")
1656"  endif					"Decho
1657"  call Decho("b:netrw_fname  <".b:netrw_fname.">")
1658"  call Dret("NetrwMethod : b:netrw_method=".b:netrw_method)
1659endfun
1660
1661" ------------------------------------------------------------------------
1662" NetReadFixup: this sort of function is typically written by the user {{{2
1663"               to handle extra junk that their system's ftp dumps
1664"               into the transfer.  This function is provided as an
1665"               example and as a fix for a Windows 95 problem: in my
1666"               experience, win95's ftp always dumped four blank lines
1667"               at the end of the transfer.
1668if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
1669 fun! NetReadFixup(method, line1, line2)
1670"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
1671
1672   " sanity checks -- attempt to convert inputs to integers
1673   let method = a:method + 0
1674   let line1  = a:line1 + 0
1675   let line2  = a:line2 + 0
1676   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
1677"    call Dret("NetReadFixup")
1678    return
1679   endif
1680
1681   if method == 3   " ftp (no <.netrc>)
1682    let fourblanklines= line2 - 3
1683    if fourblanklines >= line1
1684     exe "sil keepj ".fourblanklines.",".line2."g/^\s*$/d"
1685     call histdel("/",-1)
1686    endif
1687   endif
1688
1689"   call Dret("NetReadFixup")
1690 endfun
1691endif
1692
1693" ---------------------------------------------------------------------
1694" NetUserPass: set username and password for subsequent ftp transfer {{{2
1695"   Usage:  :call NetUserPass()			-- will prompt for userid and password
1696"	    :call NetUserPass("uid")		-- will prompt for password
1697"	    :call NetUserPass("uid","password") -- sets global userid and password
1698fun! NetUserPass(...)
1699
1700 " get/set userid
1701 if a:0 == 0
1702"  call Dfunc("NetUserPass(a:0<".a:0.">)")
1703  if !exists("g:netrw_uid") || g:netrw_uid == ""
1704   " via prompt
1705   let g:netrw_uid= input('Enter username: ')
1706  endif
1707 else	" from command line
1708"  call Dfunc("NetUserPass(a:1<".a:1.">)")
1709  let g:netrw_uid= a:1
1710 endif
1711
1712 " get password
1713 if a:0 <= 1 " via prompt
1714"  call Decho("a:0=".a:0." case <=1:")
1715  let s:netrw_passwd= inputsecret("Enter Password: ")
1716 else " from command line
1717"  call Decho("a:0=".a:0." case >1: a:2<".a:2.">")
1718  let s:netrw_passwd=a:2
1719 endif
1720
1721"  call Dret("NetUserPass")
1722endfun
1723
1724" ===========================================
1725"  Shared Browsing Support:    {{{1
1726" ===========================================
1727
1728" ---------------------------------------------------------------------
1729" s:BrowserMaps: {{{2
1730fun! s:BrowserMaps(islocal)
1731"  call Dfunc("s:BrowserMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
1732  if a:islocal
1733"   call Decho("make local maps")
1734   nnoremap <buffer> <silent> <cr>	:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
1735   nnoremap <buffer> <silent> -		:exe "norm! 0"<bar>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,'../'))<cr>
1736   nnoremap <buffer> <silent> a		:call <SID>NetrwHide(1)<cr>
1737   nnoremap <buffer> <silent> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
1738   nnoremap <buffer> <silent> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
1739   nnoremap <buffer> <silent> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
1740   nnoremap <buffer> <silent> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
1741   nnoremap <buffer> <silent> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1742   nnoremap <buffer> <silent> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
1743   nnoremap <buffer> <silent> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
1744   nnoremap <buffer> <silent> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
1745   nnoremap <buffer> <silent> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
1746   nnoremap <buffer> <silent> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
1747   nnoremap <buffer> <silent> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
1748   nnoremap <buffer> <silent> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
1749   nnoremap <buffer> <silent> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
1750   nnoremap <buffer> <silent> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
1751   nnoremap <buffer> <silent> mx	:<c-u>call <SID>NetrwMarkFileExe(1)<cr>
1752   nnoremap <buffer> <silent> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
1753   nnoremap <buffer> <silent> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
1754   nnoremap <buffer> <silent> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
1755   nnoremap <buffer> <silent> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
1756   nnoremap <buffer> <silent> c		:exe "keepjumps lcd ".fnameescape(b:netrw_curdir)<cr>
1757   nnoremap <buffer> <silent> C		:let g:netrw_chgwin= winnr()<cr>
1758   nnoremap <buffer> <silent> d		:call <SID>NetrwMakeDir("")<cr>
1759   nnoremap <buffer> <silent> i		:call <SID>NetrwListStyle(1)<cr>
1760   nnoremap <buffer> <silent> I		:call <SID>NetrwBannerCtrl(1)<cr>
1761   nnoremap <buffer> <silent> o		:call <SID>NetrwSplit(3)<cr>
1762   nnoremap <buffer> <silent> O		:call <SID>NetrwObtain(1)<cr>
1763   nnoremap <buffer> <silent> p		:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
1764   nnoremap <buffer> <silent> P		:call <SID>NetrwPrevWinOpen(1)<cr>
1765   nnoremap <buffer> <silent> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
1766   nnoremap <buffer> <silent> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
1767   nnoremap <buffer> <silent> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
1768   nnoremap <buffer> <silent> r		:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr>
1769   nnoremap <buffer> <silent> s		:call <SID>NetrwSortStyle(1)<cr>
1770   nnoremap <buffer> <silent> S		:call <SID>NetSortSequence(1)<cr>
1771   nnoremap <buffer> <silent> t		:call <SID>NetrwSplit(4)<cr>
1772   nnoremap <buffer> <silent> T		:call <SID>NetrwSplit(4)<bar>norm! gT<cr>
1773   nnoremap <buffer> <silent> u		:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
1774   nnoremap <buffer> <silent> U		:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
1775   nnoremap <buffer> <silent> v		:call <SID>NetrwSplit(5)<cr>
1776   nnoremap <buffer> <silent> x		:call netrw#NetrwBrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
1777   nnoremap <buffer> <silent> %		:call <SID>NetrwOpenFile(1)<cr>
1778   inoremap <buffer> <silent> <cr>	<c-o>:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
1779   inoremap <buffer> <silent> -		<c-o>:exe "norm! 0"<bar>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,'../'))<cr>
1780   inoremap <buffer> <silent> a		<c-o>:call <SID>NetrwHide(1)<cr>
1781   inoremap <buffer> <silent> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
1782   inoremap <buffer> <silent> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
1783   inoremap <buffer> <silent> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
1784   inoremap <buffer> <silent> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
1785   inoremap <buffer> <silent> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1786   inoremap <buffer> <silent> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
1787   inoremap <buffer> <silent> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
1788   inoremap <buffer> <silent> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
1789   inoremap <buffer> <silent> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
1790   inoremap <buffer> <silent> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
1791   inoremap <buffer> <silent> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
1792   inoremap <buffer> <silent> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
1793   inoremap <buffer> <silent> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
1794   inoremap <buffer> <silent> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
1795   inoremap <buffer> <silent> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(1)<cr>
1796   inoremap <buffer> <silent> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
1797   inoremap <buffer> <silent> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
1798   inoremap <buffer> <silent> gh	<c-o>:<c-u>call <SID>NetrwHidden(1)<cr>
1799   inoremap <buffer> <silent> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
1800   inoremap <buffer> <silent> c		<c-o>:exe "keepjumps lcd ".fnameescape(b:netrw_curdir)<cr>
1801   inoremap <buffer> <silent> C		<c-o>:let g:netrw_chgwin= winnr()<cr>
1802   inoremap <buffer> <silent> d		<c-o>:call <SID>NetrwMakeDir("")<cr>
1803   inoremap <buffer> <silent> i		<c-o>:call <SID>NetrwListStyle(1)<cr>
1804   inoremap <buffer> <silent> I		<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
1805   inoremap <buffer> <silent> o		<c-o>:call <SID>NetrwSplit(3)<cr>
1806   inoremap <buffer> <silent> O		<c-o>:call <SID>NetrwObtain(1)<cr>
1807   inoremap <buffer> <silent> p		<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
1808   inoremap <buffer> <silent> P		<c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
1809   inoremap <buffer> <silent> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
1810   inoremap <buffer> <silent> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
1811   inoremap <buffer> <silent> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
1812   inoremap <buffer> <silent> r		<c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr>
1813   inoremap <buffer> <silent> s		<c-o>:call <SID>NetrwSortStyle(1)<cr>
1814   inoremap <buffer> <silent> S		<c-o>:call <SID>NetSortSequence(1)<cr>
1815   inoremap <buffer> <silent> t		<c-o>:call <SID>NetrwSplit(4)<cr>
1816   inoremap <buffer> <silent> T		<c-o>:call <SID>NetrwSplit(4)<bar>norm! gT<cr>
1817   inoremap <buffer> <silent> u		<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
1818   inoremap <buffer> <silent> U		<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
1819   inoremap <buffer> <silent> v		<c-o>:call <SID>NetrwSplit(5)<cr>
1820   inoremap <buffer> <silent> x		<c-o>:call netrw#NetrwBrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
1821   inoremap <buffer> <silent> %		<c-o>:call <SID>NetrwOpenFile(1)<cr>
1822   if !hasmapto('<Plug>NetrwHideEdit')
1823    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
1824    imap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
1825   endif
1826   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(1)<cr>
1827   if !hasmapto('<Plug>NetrwRefresh')
1828    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
1829    imap <buffer> <unique> <c-l> <Plug>NetrwRefresh
1830   endif
1831   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr>
1832   if s:didstarstar || !mapcheck("<s-down>","n")
1833    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
1834    inoremap <buffer> <silent> <s-down>	:Nexplore<cr>
1835   endif
1836   if s:didstarstar || !mapcheck("<s-up>","n")
1837    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
1838    inoremap <buffer> <silent> <s-up>	:Pexplore<cr>
1839   endif
1840   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
1841   if g:netrw_mousemaps == 1
1842    nnoremap <buffer> <silent> <leftmouse>   <leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
1843    nnoremap <buffer> <silent> <middlemouse> <leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
1844    nnoremap <buffer> <silent> <s-leftmouse> <leftmouse>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1845    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1846    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1847    inoremap <buffer> <silent> <leftmouse>   <c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(1)<cr>
1848    inoremap <buffer> <silent> <middlemouse> <c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
1849    inoremap <buffer> <silent> <s-leftmouse> <c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1850    exe 'inoremap <buffer> <silent> <rightmouse>  <c-o><leftmouse><c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1851   endif
1852   exe 'nnoremap <buffer> <silent> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1853   exe 'nnoremap <buffer> <silent> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1854   exe 'nnoremap <buffer> <silent> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
1855   exe 'nnoremap <buffer> <silent> <Leader>m	:call <SID>NetrwMakeDir("")<cr>'
1856   exe 'vnoremap <buffer> <silent> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1857   exe 'vnoremap <buffer> <silent> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1858   exe 'vnoremap <buffer> <silent> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
1859   exe 'inoremap <buffer> <silent> <del>	<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1860   exe 'inoremap <buffer> <silent> D		<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1861   exe 'inoremap <buffer> <silent> R		<c-o>:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
1862   exe 'inoremap <buffer> <silent> <Leader>m	<c-o>:call <SID>NetrwMakeDir("")<cr>'
1863   nnoremap <buffer> <F1>		:he netrw-quickhelp<cr>
1864
1865  else " remote
1866"   call Decho("make remote maps")
1867   call s:RemotePathAnalysis(b:netrw_curdir)
1868   nnoremap <buffer> <silent> <cr>	:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
1869   nnoremap <buffer> <silent> <c-l>	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
1870   nnoremap <buffer> <silent> -		:exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'../'))<cr>
1871   nnoremap <buffer> <silent> a		:call <SID>NetrwHide(0)<cr>
1872   nnoremap <buffer> <silent> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
1873   nnoremap <buffer> <silent> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
1874   nnoremap <buffer> <silent> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
1875   nnoremap <buffer> <silent> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
1876   nnoremap <buffer> <silent> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
1877   nnoremap <buffer> <silent> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
1878   nnoremap <buffer> <silent> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
1879   nnoremap <buffer> <silent> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
1880   nnoremap <buffer> <silent> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
1881   nnoremap <buffer> <silent> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
1882   nnoremap <buffer> <silent> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
1883   nnoremap <buffer> <silent> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
1884   nnoremap <buffer> <silent> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
1885   nnoremap <buffer> <silent> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
1886   nnoremap <buffer> <silent> mx	:<c-u>call <SID>NetrwMarkFileExe(0)<cr>
1887   nnoremap <buffer> <silent> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
1888   nnoremap <buffer> <silent> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_cur)<cr>
1889   nnoremap <buffer> <silent> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
1890   nnoremap <buffer> <silent> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
1891   nnoremap <buffer> <silent> C		:let g:netrw_chgwin= winnr()<cr>
1892   nnoremap <buffer> <silent> i		:call <SID>NetrwListStyle(0)<cr>
1893   nnoremap <buffer> <silent> I		:call <SID>NetrwBannerCtrl(1)<cr>
1894   nnoremap <buffer> <silent> o		:call <SID>NetrwSplit(0)<cr>
1895   nnoremap <buffer> <silent> O		:call <SID>NetrwObtain(0)<cr>
1896   nnoremap <buffer> <silent> p		:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
1897   nnoremap <buffer> <silent> P		:call <SID>NetrwPrevWinOpen(0)<cr>
1898   nnoremap <buffer> <silent> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
1899   nnoremap <buffer> <silent> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
1900   nnoremap <buffer> <silent> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
1901   nnoremap <buffer> <silent> r		:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
1902   nnoremap <buffer> <silent> s		:call <SID>NetrwSortStyle(0)<cr>
1903   nnoremap <buffer> <silent> S		:call <SID>NetSortSequence(0)<cr>
1904   nnoremap <buffer> <silent> t		:call <SID>NetrwSplit(1)<cr>
1905   nnoremap <buffer> <silent> T		:call <SID>NetrwSplit(1)<bar>norm! gT<cr>
1906   nnoremap <buffer> <silent> u		:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
1907   nnoremap <buffer> <silent> U		:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
1908   nnoremap <buffer> <silent> v		:call <SID>NetrwSplit(2)<cr>
1909   nnoremap <buffer> <silent> x		:call netrw#NetrwBrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
1910   nnoremap <buffer> <silent> %		:call <SID>NetrwOpenFile(0)<cr>
1911   inoremap <buffer> <silent> <cr>	<c-o>:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
1912   inoremap <buffer> <silent> <c-l>	<c-o>:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
1913   inoremap <buffer> <silent> -		<c-o>:exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'../'))<cr>
1914   inoremap <buffer> <silent> a		<c-o>:call <SID>NetrwHide(0)<cr>
1915   inoremap <buffer> <silent> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
1916   inoremap <buffer> <silent> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
1917   inoremap <buffer> <silent> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
1918   inoremap <buffer> <silent> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
1919   inoremap <buffer> <silent> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
1920   inoremap <buffer> <silent> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
1921   inoremap <buffer> <silent> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
1922   inoremap <buffer> <silent> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
1923   inoremap <buffer> <silent> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
1924   inoremap <buffer> <silent> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
1925   inoremap <buffer> <silent> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
1926   inoremap <buffer> <silent> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
1927   inoremap <buffer> <silent> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
1928   inoremap <buffer> <silent> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
1929   inoremap <buffer> <silent> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(0)<cr>
1930   inoremap <buffer> <silent> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
1931   inoremap <buffer> <silent> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_cur)<cr>
1932   inoremap <buffer> <silent> gh	<c-o>:<c-u>call <SID>NetrwHidden(0)<cr>
1933   inoremap <buffer> <silent> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
1934   inoremap <buffer> <silent> C		<c-o>:let g:netrw_chgwin= winnr()<cr>
1935   inoremap <buffer> <silent> i		<c-o>:call <SID>NetrwListStyle(0)<cr>
1936   inoremap <buffer> <silent> I		<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
1937   inoremap <buffer> <silent> o		<c-o>:call <SID>NetrwSplit(0)<cr>
1938   inoremap <buffer> <silent> O		<c-o>:call <SID>NetrwObtain(0)<cr>
1939   inoremap <buffer> <silent> p		<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
1940   inoremap <buffer> <silent> P		<c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
1941   inoremap <buffer> <silent> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
1942   inoremap <buffer> <silent> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
1943   inoremap <buffer> <silent> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
1944   inoremap <buffer> <silent> r		<c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
1945   inoremap <buffer> <silent> s		<c-o>:call <SID>NetrwSortStyle(0)<cr>
1946   inoremap <buffer> <silent> S		<c-o>:call <SID>NetSortSequence(0)<cr>
1947   inoremap <buffer> <silent> t		<c-o>:call <SID>NetrwSplit(1)<cr>
1948   inoremap <buffer> <silent> T		<c-o>:call <SID>NetrwSplit(1)<bar>norm! gT<cr>
1949   inoremap <buffer> <silent> u		<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
1950   inoremap <buffer> <silent> U		<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
1951   inoremap <buffer> <silent> v		<c-o>:call <SID>NetrwSplit(2)<cr>
1952   inoremap <buffer> <silent> x		<c-o>:call netrw#NetrwBrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
1953   inoremap <buffer> <silent> %		<c-o>:call <SID>NetrwOpenFile(0)<cr>
1954   if !hasmapto('<Plug>NetrwHideEdit')
1955    nmap <buffer> <c-h> <Plug>NetrwHideEdit
1956    imap <buffer> <c-h> <Plug>NetrwHideEdit
1957   endif
1958   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
1959   if !hasmapto('<Plug>NetrwRefresh')
1960    nmap <buffer> <c-l> <Plug>NetrwRefresh
1961    imap <buffer> <c-l> <Plug>NetrwRefresh
1962   endif
1963
1964   let mapsafepath     = escape(s:path, s:netrw_map_escape)
1965   let mapsafeusermach = escape(s:user.s:machine, s:netrw_map_escape)
1966
1967   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
1968   if g:netrw_mousemaps == 1
1969    nnoremap <buffer> <silent> <leftmouse>   <leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
1970    nnoremap <buffer> <silent> <middlemouse> <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
1971    nnoremap <buffer> <silent> <s-leftmouse> <leftmouse>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
1972    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1973    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1974    inoremap <buffer> <silent> <leftmouse>   <c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(0)<cr>
1975    inoremap <buffer> <silent> <middlemouse> <c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
1976    inoremap <buffer> <silent> <s-leftmouse> <c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
1977    exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1978   endif
1979   exe 'nnoremap <buffer> <silent> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1980   exe 'nnoremap <buffer> <silent> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
1981   exe 'nnoremap <buffer> <silent> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1982   exe 'nnoremap <buffer> <silent> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1983   exe 'vnoremap <buffer> <silent> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1984   exe 'vnoremap <buffer> <silent> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1985   exe 'vnoremap <buffer> <silent> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1986   exe 'inoremap <buffer> <silent> <del>	<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1987   exe 'inoremap <buffer> <silent> d		<c-o>:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
1988   exe 'inoremap <buffer> <silent> D		<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1989   exe 'inoremap <buffer> <silent> R		<c-o>:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1990   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
1991   inoremap <buffer> <F1>			<c-o>:he netrw-quickhelp<cr>
1992  endif
1993  call s:SetRexDir(a:islocal,b:netrw_curdir)
1994"  call Dret("s:BrowserMaps")
1995endfun
1996
1997" ---------------------------------------------------------------------
1998" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
1999fun! s:ExplorePatHls(pattern)
2000"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
2001  let repat= substitute(a:pattern,'^**/\{1,2}','','')
2002"  call Decho("repat<".repat.">")
2003  let repat= escape(repat,'][.\')
2004"  call Decho("repat<".repat.">")
2005  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
2006"  call Dret("s:ExplorePatHls repat<".repat.">")
2007  return repat
2008endfun
2009
2010" ---------------------------------------------------------------------
2011"  s:NetrwBookHistHandler: {{{2
2012"    0: (user: <mb>)   bookmark current directory
2013"    1: (user: <gb>)   change to the bookmarked directory
2014"    2: (user: <qb>)   list bookmarks
2015"    3: (browsing)     record current directory history
2016"    4: (user: <u>)    go up   (previous) bookmark
2017"    5: (user: <U>)    go down (next)     bookmark
2018"    6: (user: <mB>)   delete bookmark
2019fun! s:NetrwBookHistHandler(chg,curdir)
2020"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhist_cnt." histmax=".g:netrw_dirhistmax)
2021
2022  if a:chg == 0
2023   " bookmark the current directory
2024"   call Decho("(user: <b>) bookmark the current directory")
2025   if !exists("g:netrw_bookmarklist")
2026    let g:netrw_bookmarklist= []
2027   endif
2028   if index(g:netrw_bookmarklist,a:curdir) == -1
2029    " curdir not currently in g:netrw_bookmarklist, so include it
2030    call add(g:netrw_bookmarklist,a:curdir)
2031    call sort(g:netrw_bookmarklist)
2032   endif
2033   echo "bookmarked the current directory"
2034
2035  elseif a:chg == 1
2036   " change to the bookmarked directory
2037"   call Decho("(user: <".v:count."mb>) change to the bookmarked directory")
2038   if exists("g:netrw_bookmarklist[v:count-1]")
2039    exe "e ".fnameescape(g:netrw_bookmarklist[v:count-1])
2040   else
2041    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
2042   endif
2043
2044  elseif a:chg == 2
2045"   redraw!
2046   let didwork= 0
2047   " list user's bookmarks
2048"   call Decho("(user: <q>) list user's bookmarks")
2049   if exists("g:netrw_bookmarklist")
2050"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks')
2051    let cnt= 1
2052    for bmd in g:netrw_bookmarklist
2053"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1])
2054     echo "Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1]
2055     let didwork = 1
2056     let cnt     = cnt + 1
2057    endfor
2058   endif
2059
2060   " list directory history
2061   let cnt     = g:netrw_dirhist_cnt
2062   let first   = 1
2063   let histcnt = 0
2064   while ( first || cnt != g:netrw_dirhist_cnt )
2065"    call Decho("first=".first." cnt=".cnt." dirhist_cnt=".g:netrw_dirhist_cnt)
2066    let histcnt= histcnt + 1
2067    if exists("g:netrw_dirhist_{cnt}")
2068"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt})
2069     echo "Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt}
2070     let didwork= 1
2071    endif
2072    let first = 0
2073    let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
2074    if cnt < 0
2075     let cnt= cnt + g:netrw_dirhistmax
2076    endif
2077   endwhile
2078   if didwork
2079    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
2080   endif
2081
2082  elseif a:chg == 3
2083   " saves most recently visited directories (when they differ)
2084"   call Decho("(browsing) record curdir history")
2085   if !exists("g:netrw_dirhist_cnt") || !exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") || g:netrw_dirhist_{g:netrw_dirhist_cnt} != a:curdir
2086    let g:netrw_dirhist_cnt                   = ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
2087    let g:netrw_dirhist_{g:netrw_dirhist_cnt} = a:curdir
2088"    call Decho("save dirhist#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">")
2089   endif
2090
2091  elseif a:chg == 4
2092   " u: change to the previous directory stored on the history list
2093"   call Decho("(user: <u>) chg to prev dir from history")
2094   let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax
2095   if g:netrw_dirhist_cnt < 0
2096    let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
2097   endif
2098   if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
2099"    call Decho("changedir u#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">")
2100    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
2101     setlocal ma noro
2102"     call Decho("setlocal ma noro")
2103     keepj %d
2104     setlocal nomod
2105"     call Decho("setlocal nomod")
2106    endif
2107"    "    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}))
2108    exe "keepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
2109   else
2110    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
2111    echo "Sorry, no predecessor directory exists yet"
2112   endif
2113
2114  elseif a:chg == 5
2115   " U: change to the subsequent directory stored on the history list
2116"   call Decho("(user: <U>) chg to next dir from history")
2117   let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
2118   if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
2119"    call Decho("changedir U#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">")
2120    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
2121     setlocal ma noro
2122"     call Decho("setlocal ma noro")
2123     keepj %d
2124"     call Decho("removed all lines from buffer (%d)")
2125     setlocal nomod
2126"     call Decho("setlocal nomod")
2127    endif
2128"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}))
2129    exe "keepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
2130   else
2131    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax
2132    if g:netrw_dirhist_cnt < 0
2133     let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
2134    endif
2135    echo "Sorry, no successor directory exists yet"
2136   endif
2137
2138  elseif a:chg == 6
2139   " delete the v:count'th bookmark
2140"   call Decho("delete bookmark#".v:count."<".g:netrw_bookmarklist[v:count-1].">")
2141   let savefile= s:NetrwHome()."/.netrwbook"
2142   if filereadable(savefile)
2143    call s:NetrwBookHistSave() " done here to merge bookmarks first
2144    call delete(savefile)
2145   endif
2146   call remove(g:netrw_bookmarklist,v:count-1)
2147  endif
2148  call s:NetrwBookmarkMenu()
2149"  call Dret("s:NetrwBookHistHandler")
2150endfun
2151
2152" ---------------------------------------------------------------------
2153" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
2154"                      Sister function: s:NetrwBookHistSave()
2155fun! s:NetrwBookHistRead()
2156"  call Dfunc("s:NetrwBookHistRead()")
2157  if !exists("s:netrw_initbookhist")
2158   let home    = s:NetrwHome()
2159   let savefile= home."/.netrwbook"
2160   if filereadable(savefile)
2161"    call Decho("sourcing .netrwbook")
2162    exe "so ".savefile
2163   endif
2164   let savefile= home."/.netrwhist"
2165   if filereadable(savefile)
2166"    call Decho("sourcing .netrwhist")
2167    exe "so ".savefile
2168   endif
2169   let s:netrw_initbookhist= 1
2170   au VimLeave * call s:NetrwBookHistSave()
2171  endif
2172"  call Dret("s:NetrwBookHistRead")
2173endfun
2174
2175" ---------------------------------------------------------------------
2176" s:NetrwBookHistSave: this function saves bookmarks and history {{{2
2177"                      Sister function: s:NetrwBookHistRead()
2178"                      I used to do this via viminfo but that appears to
2179"                      be unreliable for long-term storage
2180"                      COMBAK: does $HOME work under windows???
2181fun! s:NetrwBookHistSave()
2182"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax)
2183  let savefile= s:NetrwHome()."/.netrwhist"
2184  1split
2185  call s:NetrwEnew()
2186  setlocal cino= com= cpo-=aA fo=nroql2 tw=0 report=10000 noswf
2187  setlocal nocin noai noci magic nospell nohid wig= noaw
2188  setlocal ma noro write
2189  if exists("&acd") | setlocal noacd | endif
2190  silent %d
2191
2192  " save .netrwhist -- no attempt to merge
2193  silent! file .netrwhist
2194  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
2195  call setline(2,"let g:netrw_dirhist_cnt =".g:netrw_dirhist_cnt)
2196  let lastline = line("$")
2197  let cnt      = 1
2198  while cnt <= g:netrw_dirhist_cnt
2199   call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
2200   let cnt= cnt + 1
2201  endwhile
2202  exe "sil! w! ".savefile
2203
2204  sil keepj %d
2205  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
2206   " merge and write .netrwbook
2207   let savefile= s:NetrwHome()."/.netrwbook"
2208
2209   if filereadable(savefile)
2210    let booklist= deepcopy(g:netrw_bookmarklist)
2211    exe "sil keepj so ".savefile
2212    for bdm in booklist
2213     if index(g:netrw_bookmarklist,bdm) == -1
2214      call add(g:netrw_bookmarklist,bdm)
2215     endif
2216    endfor
2217    call sort(g:netrw_bookmarklist)
2218    exe "sil! w! ".savefile
2219   endif
2220
2221   " construct and save .netrwbook
2222   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
2223   exe "sil! w! ".savefile
2224  endif
2225  let bgone= bufnr("%")
2226  q!
2227  exe bgone."bwipe!"
2228
2229"  call Dret("s:NetrwBookHistSave")
2230endfun
2231
2232" ---------------------------------------------------------------------
2233" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
2234"  list of the contents of a local or remote directory.  It is assumed that the
2235"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
2236"  with the requested remote hostname first.
2237fun! s:NetrwBrowse(islocal,dirname)
2238  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
2239"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
2240"  call Decho("tab#".tabpagenr()." win#".winnr())
2241"  call Dredir("ls!")
2242  if !exists("s:netrw_initbookhist")
2243   call s:NetrwBookHistRead()
2244  endif
2245"  call FOTEST(7)
2246"call Decho("COMBAK#01 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2247
2248  " simplify the dirname (especially for ".."s in dirnames)
2249  if a:dirname !~ '^\a\+://'
2250   let dirname= simplify(a:dirname)
2251  else
2252   let dirname= a:dirname
2253  endif
2254"  call FOTEST(8)
2255"call Decho("COMBAK#02 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2256
2257  if exists("s:netrw_skipbrowse")
2258   unlet s:netrw_skipbrowse
2259"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2260"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse=".s:netrw_skipbrowse)
2261   return
2262  endif
2263  if !exists("*shellescape")
2264   call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
2265"   call Dret("s:NetrwBrowse : missing shellescape()")
2266   return
2267  endif
2268  if !exists("*fnameescape")
2269   call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
2270"   call Dret("s:NetrwBrowse : missing fnameescape()")
2271   return
2272  endif
2273
2274  call s:NetrwOptionSave("w:")
2275"  call FOTEST(9)
2276"call Decho("COMBAK#03 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2277
2278  " re-instate any marked files
2279  if exists("s:netrwmarkfilelist_{bufnr('%')}")
2280"   call Decho("clearing marked files")
2281   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
2282  endif
2283"  call FOTEST(10)
2284"call Decho("COMBAK#04 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2285
2286  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
2287"   call Decho("handle w:netrw_acdkeep:")
2288"   call Decho("keepjumps lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")")
2289   exe 'keepj lcd '.fnameescape(dirname)
2290   call s:NetrwSafeOptions()
2291"   call Decho("getcwd<".getcwd().">")
2292
2293  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
2294   " looks like a regular file, attempt transfer
2295"   call Decho("attempt transfer as regular file<".dirname.">")
2296
2297   " remove any filetype indicator from end of dirname, except for the {{{3
2298   " "this is a directory" indicator (/).
2299   " There shouldn't be one of those here, anyway.
2300   let path= substitute(dirname,'[*=@|]\r\=$','','e')
2301"   call Decho("new path<".path.">")
2302   call s:RemotePathAnalysis(dirname)
2303
2304   " remote-read the requested file into current buffer {{{3
2305   keepj mark '
2306   call s:NetrwEnew(dirname)
2307   call s:NetrwSafeOptions()
2308   setlocal ma noro
2309"   call Decho("setlocal ma noro")
2310   let b:netrw_curdir= dirname
2311"   call Decho("exe silent! keepalt file ".fnameescape(s:method."://".s:user.s:machine."/".s:path)." (bt=".&bt.")")
2312   exe "sil! keepalt file ".fnameescape(s:method."://".s:user.s:machine."/".s:path)
2313   exe "sil keepalt doau BufReadPre ".fnameescape(s:fname)
2314   silent call netrw#NetRead(2,s:method."://".s:user.s:machine."/".s:path)
2315   if s:path !~ '.tar.bz2$' && s:path !~ '.tar.gz'
2316    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
2317    exe "sil keepalt doau BufReadPost ".fnameescape(s:fname)
2318   endif
2319
2320   " save certain window-oriented variables into buffer-oriented variables {{{3
2321   call s:SetBufWinVars()
2322   call s:NetrwOptionRestore("w:")
2323   setlocal ma nomod
2324
2325"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2326"   call Dret("s:NetrwBrowse : file<".s:fname.">")
2327   return
2328  endif
2329"  call FOTEST(11)
2330"call Decho("COMBAK#05 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2331
2332  " use buffer-oriented WinVars if buffer ones exist but window ones don't {{{3
2333  call s:UseBufWinVars()
2334
2335  " set up some variables {{{3
2336  let b:netrw_browser_active = 1
2337  let dirname                = dirname
2338  let s:last_sort_by         = g:netrw_sort_by
2339
2340  " set up menu {{{3
2341  call s:NetrwMenu(1)
2342"  call FOTEST(12)
2343"call Decho("COMBAK#06 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2344
2345  " set up buffer {{{3
2346  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
2347  " maintain markfile highlighting
2348  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
2349"   call Decho("bufnr(%)=".bufnr('%'))
2350"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/")
2351   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
2352  else
2353"   call Decho("2match none")
2354   2match none
2355  endif
2356  if reusing
2357   call s:NetrwOptionRestore("w:")
2358   setlocal noma nomod nowrap
2359"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2360"   call Dret("s:NetrwBrowse : re-using buffer")
2361   return
2362  endif
2363""  call FOTEST(13) " PROBLEM WITH LISTING
2364"call Decho("COMBAK#07 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2365
2366  " set b:netrw_curdir to the new directory name {{{3
2367"  call Decho("set b:netrw_curdir to the new directory name:  (buf#".bufnr("%").")")
2368   let b:netrw_curdir= dirname
2369  if b:netrw_curdir =~ '[/\\]$'
2370   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
2371  endif
2372  if b:netrw_curdir == ''
2373   if has("amiga")
2374    " On the Amiga, the empty string connotes the current directory
2375    let b:netrw_curdir= getcwd()
2376   else
2377    " under unix, when the root directory is encountered, the result
2378    " from the preceding substitute is an empty string.
2379    let b:netrw_curdir= '/'
2380   endif
2381  endif
2382  if !a:islocal && b:netrw_curdir !~ '/$'
2383   let b:netrw_curdir= b:netrw_curdir.'/'
2384  endif
2385"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
2386""  call FOTEST(14) " PROBLEM WITH LISTING
2387"call Decho("COMBAK#08 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2388
2389  " ------------
2390  " (local only) {{{3
2391  " ------------
2392  if a:islocal
2393"   call Decho("local only:")
2394
2395   " Set up ShellCmdPost handling.  Append current buffer to browselist
2396   call s:LocalFastBrowser()
2397
2398  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
2399   if !g:netrw_keepdir
2400"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd)
2401"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"))
2402    if !exists("&l:acd") || !&l:acd
2403"     call Decho('exe keepjumps lcd '.fnameescape(b:netrw_curdir))
2404     try
2405      exe 'keepj lcd '.fnameescape(b:netrw_curdir)
2406     catch /^Vim\%((\a\+)\)\=:E472/
2407      call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".b:netrw_curdir."> (permissions?)",61)
2408      if exists("w:netrw_prvdir")
2409       let b:netrw_curdir= w:netrw_prvdir
2410      else
2411       call s:NetrwOptionRestore("w:")
2412       setlocal noma nomod nowrap
2413       let b:netrw_curdir= dirname
2414"       call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2415"       call Dret("s:NetrwBrowse : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
2416       return
2417      endif
2418     endtry
2419    endif
2420   endif
2421
2422  " --------------------------------
2423  " remote handling: {{{3
2424  " --------------------------------
2425  else
2426"   call Decho("remote only:")
2427
2428   " analyze dirname and g:netrw_list_cmd {{{4
2429"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">")
2430   if dirname =~ "^NetrwTreeListing\>"
2431    let dirname= b:netrw_curdir
2432"    call Decho("(dirname was ".dirname.") dirname<".dirname.">")
2433   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
2434    let dirname= substitute(b:netrw_curdir,'\\','/','g')
2435    if dirname !~ '/$'
2436     let dirname= dirname.'/'
2437    endif
2438    let b:netrw_curdir = dirname
2439"    call Decho("(liststyle is TREELIST) dirname<".dirname.">")
2440   else
2441    let dirname = substitute(dirname,'\\','/','g')
2442"    call Decho("(normal) dirname<".dirname.">")
2443   endif
2444
2445   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
2446   if dirname !~ dirpat
2447    if !exists("g:netrw_quiet")
2448     call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
2449    endif
2450    call s:NetrwOptionRestore("w:")
2451    setlocal noma nomod nowrap
2452"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2453"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
2454    return
2455   endif
2456   let b:netrw_curdir= dirname
2457"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)")
2458  endif  " (additional remote handling)
2459""  call FOTEST(15) " PROBLEM WITH LISTING
2460"call Decho("COMBAK#09 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2461
2462  " -----------------------
2463  " Directory Listing: {{{3
2464  " -----------------------
2465  call s:BrowserMaps(a:islocal)
2466""  call FOTEST(16) " PROBLEM WITH LISTING
2467  call s:PerformListing(a:islocal)
2468"  call FOTEST(17)
2469"call Decho("COMBAK#10 buf(%)#".bufnr("%")."<".bufname("%")."> win#".winnr()." bufnr(win#1)=".winbufnr(1)."<".bufname(winbufnr(1))." bufnr(win#2)=".winbufnr(2)."<".bufname(winbufnr(2)).">")
2470
2471  " The s:LocalBrowseShellCmdRefresh() function is called by an autocmd
2472  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow, medium speed).
2473  " However, s:NetrwBrowse() causes the ShellCmdPost event itself to fire once; setting
2474  " the variable below avoids that second refresh of the screen.  The s:LocalBrowseShellCmdRefresh()
2475  " function gets called due to that autocmd; it notices that the following variable is set
2476  " and skips the refresh and sets s:locbrowseshellcmd to zero. Oct 13, 2008
2477  let s:locbrowseshellcmd= 1
2478
2479"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2480"  call Dret("s:NetrwBrowse : did PerformListing")
2481  return
2482endfun
2483
2484" ---------------------------------------------------------------------
2485" s:NetrwFileInfo: supports qf (query for file information) {{{2
2486fun! s:NetrwFileInfo(islocal,fname)
2487"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">)")
2488  if a:islocal
2489   if (has("unix") || has("macunix")) && executable("/bin/ls")
2490    if exists("b:netrw_curdir")
2491"     call Decho('using ls with b:netrw_curdir<'.b:netrw_curdir.'>')
2492     if b:netrw_curdir =~ '/$'
2493      echo system("/bin/ls -lsad ".shellescape(b:netrw_curdir.a:fname))
2494     else
2495      echo system("/bin/ls -lsad ".shellescape(b:netrw_curdir."/".a:fname))
2496     endif
2497    else
2498"     call Decho('using ls '.a:fname." using cwd<".getcwd().">")
2499     echo system("/bin/ls -lsad ".shellescape(a:fname))
2500    endif
2501   else
2502    " use vim functions to return information about file below cursor
2503"    call Decho("using vim functions to query for file info")
2504    if !isdirectory(a:fname) && !filereadable(a:fname) && a:fname =~ '[*@/]'
2505     let fname= substitute(a:fname,".$","","")
2506    else
2507     let fname= a:fname
2508    endif
2509    let t  = getftime(fname)
2510    let sz = getfsize(fname)
2511    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname))
2512"    call Decho(fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)))
2513   endif
2514  else
2515   echo "sorry, \"qf\" not supported yet for remote files"
2516  endif
2517"  call Dret("s:NetrwFileInfo")
2518endfun
2519
2520" ---------------------------------------------------------------------
2521" s:NetrwGetBuffer: {{{2
2522"   returns 0=cleared buffer
2523"           1=re-used buffer
2524fun! s:NetrwGetBuffer(islocal,dirname)
2525"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
2526  let dirname= a:dirname
2527
2528  " re-use buffer if possible {{{3
2529"  call Decho("--re-use a buffer if possible--")
2530  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
2531   " find NetrwTreeList buffer if there is one
2532"   call Decho("find NetrwTreeList buffer if there is one")
2533   if exists("w:netrw_treebufnr") && w:netrw_treebufnr > 0
2534"    call Decho("  re-use w:netrw_treebufnr=".w:netrw_treebufnr)
2535    let eikeep= &ei
2536    set ei=all
2537    exe "b ".w:netrw_treebufnr
2538    let &ei= eikeep
2539"    call Dret("s:NetrwGetBuffer : bufnum#".w:netrw_treebufnr."<NetrwTreeListing>")
2540    return
2541   endif
2542   let bufnum= -1
2543"   call Decho("  liststyle=TREE but w:netrw_treebufnr doesn't exist")
2544
2545  else
2546   " find buffer number of buffer named precisely the same as dirname {{{3
2547"   call Decho("--find buffer numnber of buffer named precisely the same as dirname--")
2548"   call Dredir("ls!")
2549
2550   " get dirname and associated buffer number
2551   let bufnum  = bufnr(escape(dirname,'\'))
2552"   call Decho("  find buffer<".dirname.">'s number ")
2553"   call Decho("  bufnr(dirname<".escape(dirname,'\').">)=".bufnum)
2554
2555   if bufnum < 0 && dirname !~ '/$'
2556    " try appending a trailing /
2557"    call Decho("  try appending a trailing / to dirname<".dirname.">")
2558    let bufnum= bufnr(escape(dirname.'/','\'))
2559    if bufnum > 0
2560     let dirname= dirname.'/'
2561    endif
2562   endif
2563
2564   if bufnum < 0 && dirname =~ '/$'
2565    " try removing a trailing /
2566"    call Decho("  try removing a trailing / from dirname<".dirname.">")
2567    let bufnum= bufnr(escape(substitute(dirname,'/$','',''),'\'))
2568    if bufnum > 0
2569     let dirname= substitute(dirname,'/$','','')
2570    endif
2571   endif
2572
2573"   call Decho("  findbuf1: bufnum=bufnr('".dirname."')=".bufnum." bufname(".bufnum.")<".bufname(bufnum)."> (initial)")
2574   " note: !~ was used just below, but that means using ../ to go back would match (ie. abc/def/  and abc/ matches)
2575   if bufnum > 0 && bufname(bufnum) != dirname && bufname(bufnum) != '.'
2576    " handle approximate matches
2577"    call Decho("  handling approx match: bufnum#".bufnum."<".bufname(bufnum)."> approx-dirname<".dirname.">")
2578    let ibuf    = 1
2579    let buflast = bufnr("$")
2580"    call Decho("  findbuf2: buflast=bufnr($)=".buflast)
2581    while ibuf <= buflast
2582     let bname= substitute(bufname(ibuf),'\\','/','g')
2583     let bname= substitute(bname,'.\zs/$','','')
2584"     call Decho("  findbuf3: while [ibuf=",ibuf."]<=[buflast=".buflast."]: dirname<".dirname."> bname=bufname(".ibuf.")<".bname.">")
2585     if bname != '' && dirname =~ '/'.bname.'/\=$' && dirname !~ '^/'
2586      " bname is not empty
2587      " dirname ends with bname,
2588      " dirname doesn't start with /, so its not a absolute path
2589"      call Decho("  findbuf3a: passes test 1 : dirname<".dirname.'> =~ /'.bname.'/\=$ && dirname !~ ^/')
2590      break
2591     endif
2592     if bname =~ '^'.dirname.'/\=$'
2593      " bname begins with dirname
2594"      call Decho('  findbuf3b: passes test 2 : bname<'.bname.'>=~^'.dirname.'/\=$')
2595      break
2596     endif
2597     if dirname =~ '^'.bname.'/$'
2598"      call Decho('  findbuf3c: passes test 3 : dirname<'.dirname.'>=~^'.bname.'/$')
2599      break
2600     endif
2601     if bname != '' && dirname =~ '/'.bname.'$' && bname == bufname("%") && line("$") == 1
2602"      call Decho('  findbuf3d: passes test 4 : dirname<'.dirname.'>=~ /'.bname.'$')
2603      break
2604     endif
2605     let ibuf= ibuf + 1
2606    endwhile
2607    if ibuf > buflast
2608     let bufnum= -1
2609    else
2610     let bufnum= ibuf
2611    endif
2612"    call Decho("  findbuf4: bufnum=".bufnum." (ibuf=".ibuf." buflast=".buflast.")")
2613   endif
2614  endif
2615
2616  " get enew buffer and name it -or- re-use buffer {{{3
2617  keepj mark '
2618  if bufnum < 0 || !bufexists(bufnum)
2619"   call Decho("--get enew buffer and name it (bufexists([bufnum=".bufnum."])=".bufexists(bufnum).")")
2620   call s:NetrwEnew(dirname)
2621"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)")
2622   " name the buffer
2623   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
2624    " Got enew buffer; transform into a NetrwTreeListing
2625"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --")
2626    if !exists("s:netrw_treelistnum")
2627     let s:netrw_treelistnum= 1
2628    else
2629     let s:netrw_treelistnum= s:netrw_treelistnum + 1
2630    endif
2631    let w:netrw_treebufnr= bufnr("%")
2632"    call Decho("  exe silent! keepalt file NetrwTreeListing ".fnameescape(s:netrw_treelistnum))
2633    exe 'sil! keepalt file NetrwTreeListing\ '.fnameescape(s:netrw_treelistnum)
2634    set bt=nofile noswf
2635    nnoremap <silent> <buffer> [	:silent call <SID>TreeListMove('[')<cr>
2636    nnoremap <silent> <buffer> ]	:silent call <SID>TreeListMove(']')<cr>
2637    nnoremap <silent> <buffer> [[       :silent call <SID>TreeListMove('[')<cr>
2638    nnoremap <silent> <buffer> ]]       :silent call <SID>TreeListMove(']')<cr>
2639"    call Decho("  tree listing#".s:netrw_treelistnum." bufnr=".w:netrw_treebufnr)
2640   else
2641"    let v:errmsg= "" " Decho
2642    let escdirname= fnameescape(dirname)
2643"    call Decho("  errmsg<".v:errmsg."> bufnr(escdirname<".escdirname.">)=".bufnr(escdirname)." bufname()<".bufname(bufnr(escdirname)).">")
2644"    call Decho('  exe silent! keepalt file '.escdirname)
2645"    let v:errmsg= "" " Decho
2646    exe 'sil! keepalt file '.escdirname
2647"    call Decho("  errmsg<".v:errmsg."> bufnr(".escdirname.")=".bufnr(escdirname)."<".bufname(bufnr(escdirname)).">")
2648   endif
2649"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">")
2650
2651  else " Re-use the buffer
2652"   call Decho("--re-use buffer#".bufnum." (bufexists([bufnum=".bufnum."])=".bufexists(bufnum).")")
2653   let eikeep= &ei
2654   set ei=all
2655   if getline(2) =~ '^" Netrw Directory Listing'
2656"    call Decho("  re-use buffer#".bufnum."<".((bufnum > 0)? bufname(bufnum) : "")."> using:  keepalt b ".bufnum)
2657    exe "keepalt b ".bufnum
2658   else
2659"    call Decho("  reusing buffer#".bufnum."<".((bufnum > 0)? bufname(bufnum) : "")."> using:  b ".bufnum)
2660    exe "b ".bufnum
2661   endif
2662   if bufname("%") == '.'
2663"    call Decho("exe silent! keepalt file ".fnameescape(getcwd()))
2664    exe "sil! keepalt file ".fnameescape(getcwd())
2665   endif
2666   let &ei= eikeep
2667   if line("$") <= 1
2668    call s:NetrwListSettings(a:islocal)
2669"    call Dret("s:NetrwGetBuffer 0 : re-using buffer#".bufnr("%").", but its empty, so refresh it")
2670    return 0
2671   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
2672"    call Decho("--re-use tree listing--")
2673"    call Decho("  clear buffer<".expand("%")."> with :%d")
2674    sil keepj %d
2675    call s:NetrwListSettings(a:islocal)
2676"    call Dret("s:NetrwGetBuffer 0 : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
2677    return 0
2678   else
2679"    call Dret("s:NetrwGetBuffer 1 : buf#".bufnr("%"))
2680    return 1
2681   endif
2682  endif
2683
2684  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
2685  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
2686  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
2687  "  med    1         D      H
2688  "  fast   2         H      H
2689"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--")
2690  let fname= expand("%")
2691  call s:NetrwListSettings(a:islocal)
2692"  call Decho("exe keepalt file ".fnameescape(fname))
2693  exe "keepalt file ".fnameescape(fname)
2694
2695  " delete all lines from buffer {{{3
2696"  call Decho("--delete all lines from buffer--")
2697"  call Decho("  clear buffer<".expand("%")."> with :%d")
2698  sil! keepalt keepj %d
2699
2700"  call Dret("s:NetrwGetBuffer 0 : buf#".bufnr("%"))
2701  return 0
2702endfun
2703
2704" ---------------------------------------------------------------------
2705" s:NetrwGetcwd: get the current directory. {{{2
2706"   Change backslashes to forward slashes, if any.
2707"   If doesc is true, escape certain troublesome characters
2708fun! s:NetrwGetcwd(doesc)
2709"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
2710  let curdir= substitute(getcwd(),'\\','/','ge')
2711  if curdir !~ '[\/]$'
2712   let curdir= curdir.'/'
2713  endif
2714  if a:doesc
2715   let curdir= fnameescape(curdir)
2716  endif
2717"  call Dret("NetrwGetcwd <".curdir.">")
2718  return curdir
2719endfun
2720
2721" ---------------------------------------------------------------------
2722"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
2723fun! s:NetrwGetWord()
2724"  call Dfunc("s:NetrwGetWord() line#".line(".")." liststyle=".g:netrw_liststyle." virtcol=".virtcol("."))
2725  call s:UseBufWinVars()
2726
2727  " insure that w:netrw_liststyle is set up
2728  if !exists("w:netrw_liststyle")
2729   if exists("g:netrw_liststyle")
2730    let w:netrw_liststyle= g:netrw_liststyle
2731   else
2732    let w:netrw_liststyle= s:THINLIST
2733   endif
2734"   call Decho("w:netrw_liststyle=".w:netrw_liststyle)
2735  endif
2736
2737  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
2738   " Active Banner support
2739"   call Decho("active banner handling")
2740   keepj norm! 0
2741   let dirname= "./"
2742   let curline= getline('.')
2743
2744   if curline =~ '"\s*Sorted by\s'
2745    keepj norm s
2746    let s:netrw_skipbrowse= 1
2747    echo 'Pressing "s" also works'
2748
2749   elseif curline =~ '"\s*Sort sequence:'
2750    let s:netrw_skipbrowse= 1
2751    echo 'Press "S" to edit sorting sequence'
2752
2753   elseif curline =~ '"\s*Quick Help:'
2754    keepj norm ?
2755    let s:netrw_skipbrowse= 1
2756    echo 'Pressing "?" also works'
2757
2758   elseif curline =~ '"\s*\%(Hiding\|Showing\):'
2759    keepj norm a
2760    let s:netrw_skipbrowse= 1
2761    echo 'Pressing "a" also works'
2762
2763   elseif line("$") > w:netrw_bannercnt
2764    exe 'sil keepj '.w:netrw_bannercnt
2765   endif
2766
2767  elseif w:netrw_liststyle == s:THINLIST
2768"   call Decho("thin column handling")
2769   keepj norm! 0
2770   let dirname= getline('.')
2771
2772  elseif w:netrw_liststyle == s:LONGLIST
2773"   call Decho("long column handling")
2774   keepj norm! 0
2775   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
2776
2777  elseif w:netrw_liststyle == s:TREELIST
2778"   call Decho("treelist handling")
2779   let dirname= substitute(getline('.'),'^\(| \)*','','e')
2780
2781  else
2782"   call Decho("obtain word from wide listing")
2783   let dirname= getline('.')
2784
2785   if !exists("b:netrw_cpf")
2786    let b:netrw_cpf= 0
2787    exe 'silent keepjumps '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
2788    call histdel("/",-1)
2789"   call Decho("computed cpf=".b:netrw_cpf)
2790   endif
2791
2792"   call Decho("buf#".bufnr("%")."<".bufname("%").">")
2793   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
2794"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt)
2795"   call Decho("1: dirname<".dirname.">")
2796   if filestart == 0
2797    keepj norm! 0ma
2798   else
2799    call cursor(line("."),filestart+1)
2800    keepj norm! ma
2801   endif
2802   let rega= @a
2803   let eofname= filestart + b:netrw_cpf + 1
2804   if eofname <= col("$")
2805    call cursor(line("."),filestart+b:netrw_cpf+1)
2806    keepj norm! "ay`a
2807   else
2808    keepj norm! "ay$
2809   endif
2810   let dirname = @a
2811   let @a      = rega
2812"   call Decho("2: dirname<".dirname.">")
2813   let dirname= substitute(dirname,'\s\+$','','e')
2814"   call Decho("3: dirname<".dirname.">")
2815  endif
2816
2817  " symlinks are indicated by a trailing "@".  Remove it before further processing.
2818  let dirname= substitute(dirname,"@$","","")
2819
2820  " executables are indicated by a trailing "*".  Remove it before further processing.
2821  let dirname= substitute(dirname,"\*$","","")
2822
2823"  call Dret("s:NetrwGetWord <".dirname.">")
2824  return dirname
2825endfun
2826
2827" ---------------------------------------------------------------------
2828" s:NetrwListSettings: make standard settings for a netrw listing {{{2
2829fun! s:NetrwListSettings(islocal)
2830"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
2831  let fname= bufname("%")
2832"  call Decho("setlocal bt=nofile nobl ma nonu nowrap noro")
2833  setlocal bt=nofile nobl ma nonu nowrap noro
2834"  call Decho("exe keepalt file ".fnameescape(fname))
2835  exe "keepalt file ".fnameescape(fname)
2836  if g:netrw_use_noswf
2837   setlocal noswf
2838  endif
2839"  call Dredir("ls!")
2840"  call Decho("exe setlocal ts=".g:netrw_maxfilenamelen)
2841  exe "setlocal ts=".g:netrw_maxfilenamelen
2842  setlocal isk+=.,~,-
2843  if g:netrw_fastbrowse > a:islocal
2844   setlocal bh=hide
2845  else
2846   setlocal bh=delete
2847  endif
2848"  call Dret("s:NetrwListSettings")
2849endfun
2850
2851" ---------------------------------------------------------------------
2852"  s:NetrwListStyle: {{{2
2853"  islocal=0: remote browsing
2854"         =1: local browsing
2855fun! s:NetrwListStyle(islocal)
2856"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
2857  let fname             = s:NetrwGetWord()
2858  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
2859  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
2860"  call Decho("fname<".fname.">")
2861"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle)
2862"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">")
2863
2864  if w:netrw_liststyle == s:THINLIST
2865   " use one column listing
2866"   call Decho("use one column list")
2867   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
2868
2869  elseif w:netrw_liststyle == s:LONGLIST
2870   " use long list
2871"   call Decho("use long list")
2872   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
2873
2874  elseif w:netrw_liststyle == s:WIDELIST
2875   " give wide list
2876"   call Decho("use wide list")
2877   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
2878
2879  elseif w:netrw_liststyle == s:TREELIST
2880"   call Decho("use tree list")
2881   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
2882
2883  else
2884   call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
2885   let g:netrw_liststyle = s:THINLIST
2886   let w:netrw_liststyle = g:netrw_liststyle
2887   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
2888  endif
2889  setlocal ma noro
2890"  call Decho("setlocal ma noro")
2891
2892  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
2893"  call Decho("clear buffer<".expand("%")."> with :%d")
2894  keepj %d
2895  " following prevents tree listing buffer from being marked "modified"
2896  setlocal nomod
2897
2898  " refresh the listing
2899"  call Decho("refresh the listing")
2900  let svpos= netrw#NetrwSavePosn()
2901  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
2902  call netrw#NetrwRestorePosn(svpos)
2903  call s:NetrwCursorline()
2904
2905  " keep cursor on the filename
2906  sil keepj $
2907  let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
2908"  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'))
2909  if result <= 0 && exists("w:netrw_bannercnt")
2910   exe "keepj ".w:netrw_bannercnt
2911  endif
2912
2913"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
2914endfun
2915
2916" ---------------------------------------------------------------------
2917" s:NetrwBannerCtrl: toggles the display of the banner {{{2
2918fun! s:NetrwBannerCtrl(islocal)
2919"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
2920
2921  " toggle the banner (enable/suppress)
2922  let g:netrw_banner= !g:netrw_banner
2923
2924  " refresh the listing
2925  let svpos= netrw#NetrwSavePosn()
2926  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
2927
2928  " keep cursor on the filename
2929  let fname= s:NetrwGetWord()
2930  sil keepj $
2931  let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
2932"  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'))
2933  if result <= 0 && exists("w:netrw_bannercnt")
2934   exe "keepj ".w:netrw_bannercnt
2935  endif
2936"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
2937endfun
2938
2939" ---------------------------------------------------------------------
2940" s:NetrwBookmarkMenu: Uses menu priorities {{{2
2941"                      .2.[cnt] for bookmarks, and
2942"                      .3.[cnt] for history
2943"                      (see s:NetrwMenu())
2944fun! s:NetrwBookmarkMenu()
2945  if !exists("s:netrw_menucnt")
2946   return
2947  endif
2948"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhist_cnt." menucnt=".s:netrw_menucnt)
2949
2950  " the following test assures that gvim is running, has menus available, and has menus enabled.
2951  if has("gui") && has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
2952   if exists("g:NetrwTopLvlMenu")
2953"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)")
2954    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
2955    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
2956   endif
2957   if !exists("s:netrw_initbookhist")
2958    call s:NetrwBookHistRead()
2959   endif
2960
2961   " show bookmarked places
2962   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
2963    let cnt= 1
2964    for bmd in g:netrw_bookmarklist
2965"     call Decho('silent! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd)
2966     let bmd= escape(bmd,g:netrw_menu_escape)
2967
2968     " show bookmarks for goto menu
2969     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
2970
2971     " show bookmarks for deletion menu
2972     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
2973     let cnt= cnt + 1
2974    endfor
2975
2976   endif
2977
2978   " show directory browsing history
2979   let cnt     = g:netrw_dirhist_cnt
2980   let first   = 1
2981   let histcnt = 0
2982   while ( first || cnt != g:netrw_dirhist_cnt )
2983    let histcnt  = histcnt + 1
2984    let priority = g:netrw_dirhist_cnt + histcnt
2985    if exists("g:netrw_dirhist_{cnt}")
2986     let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
2987"     call Decho('silent! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir)
2988     exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
2989    endif
2990    let first = 0
2991    let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
2992    if cnt < 0
2993     let cnt= cnt + g:netrw_dirhistmax
2994    endif
2995   endwhile
2996
2997  endif
2998"  call Dret("NetrwBookmarkMenu")
2999endfun
3000
3001" ---------------------------------------------------------------------
3002"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
3003"                       directory and a new directory name.  Also, if the
3004"                       "new directory name" is actually a file,
3005"                       NetrwBrowseChgDir() edits the file.
3006fun! s:NetrwBrowseChgDir(islocal,newdir,...)
3007"  call Dfunc("s:NetrwBrowseChgDir(islocal=".a:islocal."> newdir<".a:newdir.">) a:0=".a:0." curpos<".string(getpos("."))."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "").">")
3008
3009  if !exists("b:netrw_curdir")
3010   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
3011   " and the current window is the NetrwMessage window.
3012"   call Decho("(NetrwBrowseChgDir) b:netrw_curdir doesn't exist!")
3013"   call Decho("getcwd<".getcwd().">")
3014"   call Dredir("ls!")
3015"   call Dret("s:NetrwBrowseChgDir")
3016   return
3017  endif
3018
3019  call s:NetrwOptionSave("s:")
3020  call s:NetrwSafeOptions()
3021  let nbcd_curpos                = netrw#NetrwSavePosn()
3022  let s:nbcd_curpos_{bufnr('%')} = nbcd_curpos
3023  if (has("win32") || has("win95") || has("win64") || has("win16"))
3024   let dirname                   = substitute(b:netrw_curdir,'\\','/','ge')
3025  else
3026   let dirname= b:netrw_curdir
3027  endif
3028  let newdir    = a:newdir
3029  let dolockout = 0
3030
3031  " set up o/s-dependent directory recognition pattern
3032  if has("amiga")
3033   let dirpat= '[\/:]$'
3034  else
3035   let dirpat= '[\/]$'
3036  endif
3037"  call Decho("dirname<".dirname.">  dirpat<".dirpat.">")
3038
3039  if dirname !~ dirpat
3040   " apparently vim is "recognizing" that it is in a directory and
3041   " is removing the trailing "/".  Bad idea, so I put it back.
3042   let dirname= dirname.'/'
3043"   call Decho("adjusting dirname<".dirname.">")
3044  endif
3045
3046  if newdir !~ dirpat
3047   " ------------
3048   " edit a file:
3049   " ------------
3050"   call Decho('case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">")
3051   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
3052    let dirname= s:NetrwTreeDir()
3053    if dirname =~ '/$'
3054     let dirname= dirname.newdir
3055    else
3056     let dirname= s:NetrwTreeDir()."/".newdir
3057    endif
3058"    call Decho("dirname<".dirname.">")
3059"    call Decho("tree listing")
3060   elseif newdir =~ '^\(/\|\a:\)'
3061    let dirname= newdir
3062   else
3063    let dirname= s:ComposePath(dirname,newdir)
3064   endif
3065"   call Decho("handling a file: dirname<".dirname."> (a:0=".a:0.")")
3066   " this lets NetrwBrowseX avoid the edit
3067   if a:0 < 1
3068"    call Decho("set up windows for editing<".fnameescape(dirname).">  didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist"))
3069    call s:NetrwOptionRestore("s:")
3070    if !exists("s:didsplit")
3071     if     g:netrw_browse_split == 1
3072      new
3073      if !&ea
3074       wincmd _
3075      endif
3076     elseif g:netrw_browse_split == 2
3077      rightb vert new
3078      if !&ea
3079       wincmd |
3080      endif
3081     elseif g:netrw_browse_split == 3
3082      tabnew
3083     elseif g:netrw_browse_split == 4
3084      if s:NetrwPrevWinOpen(2) == 3
3085"       call Dret("s:NetrwBrowseChgDir")
3086       return
3087      endif
3088     else
3089      " handling a file, didn't split, so remove menu
3090"      call Decho("handling a file+didn't split, so remove menu")
3091      call s:NetrwMenu(0)
3092      " optional change to window
3093      if g:netrw_chgwin >= 1
3094       exe "keepjumps ".g:netrw_chgwin."wincmd w"
3095      endif
3096     endif
3097    endif
3098    " the point where netrw actually edits the (local) file
3099    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
3100    if a:islocal
3101"     call Decho("edit local file: exe e! ".fnameescape(dirname))
3102     exe "e! ".fnameescape(dirname)
3103    else
3104"     call Decho("remote file: NetrwBrowse will edit it")
3105    endif
3106    let dolockout= 1
3107
3108    " handle g:Netrw_funcref -- call external-to-netrw functions
3109    "   This code will handle g:Netrw_funcref as an individual function reference
3110    "   or as a list of function references.  It will ignore anything that's not
3111    "   a function reference.  See  :help Funcref  for information about function references.
3112    if exists("g:Netrw_funcref")
3113     if type(g:Netrw_funcref) == 2
3114      call g:Netrw_funcref()
3115     elseif type(g:Netrw_funcref) == 3
3116      for Fncref in g:Netrw_funcref
3117       if type(FncRef) == 2
3118        call FncRef()
3119       endif
3120      endfor
3121     endif
3122    endif
3123   endif
3124
3125  elseif newdir =~ '^/'
3126   " ---------------------------------
3127   " just go to the new directory spec
3128   " ---------------------------------
3129"   call Decho('case "just go to new directory spec": newdir<'.newdir.'>')
3130   let dirname= newdir
3131   call s:SetRexDir(a:islocal,dirname)
3132   call s:NetrwOptionRestore("s:")
3133
3134  elseif newdir == './'
3135   " --------------------------
3136   " refresh the directory list
3137   " --------------------------
3138"   call Decho('case "refresh directory listing": newdir == "./"')
3139   call s:SetRexDir(a:islocal,dirname)
3140
3141  elseif newdir == '../'
3142   " -------------------
3143   " go up one directory
3144   " -------------------
3145"   call Decho('case "go up one directory": newdir == "../"')
3146
3147   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
3148    " force a refresh
3149"    call Decho("clear buffer<".expand("%")."> with :%d")
3150    setlocal noro ma
3151"    call Decho("setlocal noro ma")
3152    keepj %d
3153   endif
3154
3155   if has("amiga")
3156    " amiga
3157"    call Decho('case "go up one directory": newdir == "../" and amiga')
3158    if a:islocal
3159     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
3160     let dirname= substitute(dirname,'/$','','')
3161    else
3162     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
3163    endif
3164"    call Decho("amiga: dirname<".dirname."> (go up one dir)")
3165
3166   else
3167    " unix or cygwin
3168"    call Decho('case "go up one directory": newdir == "../" and unix or cygwin')
3169    if a:islocal
3170     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
3171     if dirname == ""
3172      let dirname= '/'
3173     endif
3174    else
3175     let dirname= substitute(dirname,'^\(\a\+://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
3176    endif
3177"    call Decho("unix: dirname<".dirname."> (go up one dir)")
3178   endif
3179   call s:SetRexDir(a:islocal,dirname)
3180
3181  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
3182"   call Decho('case liststyle is TREELIST and w:netrw_treedict exists')
3183   " force a refresh (for TREELIST, wait for NetrwTreeDir() to force the refresh)
3184   setlocal noro ma
3185"   call Decho("setlocal noro ma")
3186   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
3187"    call Decho("clear buffer<".expand("%")."> with :%d")
3188    keepj %d
3189   endif
3190   let treedir      = s:NetrwTreeDir()
3191   let s:treecurpos = nbcd_curpos
3192   let haskey= 0
3193"   call Decho("w:netrw_treedict<".string(w:netrw_treedict).">")
3194
3195   " search treedict for tree dir as-is
3196   if has_key(w:netrw_treedict,treedir)
3197"    call Decho('....searched for treedir<'.treedir.'> : found it!')
3198    let haskey= 1
3199   else
3200"    call Decho('....searched for treedir<'.treedir.'> : not found')
3201   endif
3202
3203   " search treedict for treedir with a / appended
3204   if !haskey && treedir !~ '/$'
3205    if has_key(w:netrw_treedict,treedir."/")
3206     let treedir= treedir."/"
3207"     call Decho('....searched.for treedir<'.treedir.'> found it!')
3208     let haskey = 1
3209    else
3210"     call Decho('....searched for treedir<'.treedir.'/> : not found')
3211    endif
3212   endif
3213
3214   " search treedict for treedir with any trailing / elided
3215   if !haskey && treedir =~ '/$'
3216    let treedir= substitute(treedir,'/$','','')
3217    if has_key(w:netrw_treedict,treedir)
3218"     call Decho('....searched.for treedir<'.treedir.'> found it!')
3219     let haskey = 1
3220    else
3221"     call Decho('....searched for treedir<'.treedir.'> : not found')
3222    endif
3223   endif
3224
3225   if haskey
3226    " close tree listing for selected subdirectory
3227"    call Decho("closing selected subdirectory<".dirname.">")
3228    call remove(w:netrw_treedict,treedir)
3229"    call Decho("removed     entry<".treedir."> from treedict")
3230"    call Decho("yielding treedict<".string(w:netrw_treedict).">")
3231    let dirname= w:netrw_treetop
3232   else
3233    " go down one directory
3234    let dirname= substitute(treedir,'/*$','/','')
3235"    call Decho("go down one dir: treedir<".treedir.">")
3236   endif
3237   call s:SetRexDir(a:islocal,dirname)
3238   let s:treeforceredraw = 1
3239
3240  else
3241   " go down one directory
3242   let dirname= s:ComposePath(dirname,newdir)
3243"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">")
3244   call s:SetRexDir(a:islocal,dirname)
3245  endif
3246
3247  call s:NetrwOptionRestore("s:")
3248  if dolockout
3249"   call Decho("doing modification lockout settings: ma nomod noro")
3250   setlocal ma nomod noro
3251"   call Decho("setlocal ma nomod noro")
3252  endif
3253
3254"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
3255  return dirname
3256endfun
3257
3258" ---------------------------------------------------------------------
3259" s:NetrwBrowseX:  (implements "x") executes a special "viewer" script or program for the {{{2
3260"              given filename; typically this means given their extension.
3261"              0=local, 1=remote
3262fun! netrw#NetrwBrowseX(fname,remote)
3263"  call Dfunc("NetrwBrowseX(fname<".a:fname."> remote=".a:remote.")")
3264
3265  " special core dump handler
3266  if a:fname =~ '/core\(\.\d\+\)\=$'
3267   if exists("g:Netrw_corehandler")
3268    if type(g:Netrw_corehandler) == 2
3269     " g:Netrw_corehandler is a function reference (see :help Funcref)
3270"     call Decho("g:Netrw_corehandler is a funcref")
3271     call g:Netrw_corehandler(a:fname)
3272    elseif type(g:netrw_corehandler) == 3)
3273     " g:Netrw_corehandler is a List of function references (see :help Funcref)
3274"     call Decho("g:Netrw_corehandler is a List")
3275     for Fncref in g:Netrw_corehandler
3276      if type(FncRef) == 2
3277       call FncRef(a:fname)
3278      endif
3279     endfor
3280    endif
3281"    call Dret("NetrwBrowseX : coredump handler invoked")
3282    return
3283   endif
3284  endif
3285
3286  " set up the filename
3287  " (lower case the extension, make a local copy of a remote file)
3288  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
3289  if has("win32") || has("win95") || has("win64") || has("win16")
3290   let exten= substitute(exten,'^.*$','\L&\E','')
3291  endif
3292"  call Decho("exten<".exten.">")
3293
3294  " seems kde systems often have gnome-open due to dependencies, even though
3295  " gnome-open's subsidiary display tools are largely absent.  Kde systems
3296  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
3297  if !exists("s:haskdeinit")
3298   if has("unix")
3299    let s:haskdeinit= system("ps -e") =~ 'kdeinit'
3300    if v:shell_error
3301     let s:haskdeinit = 0
3302    endif
3303   else
3304    let s:haskdeinit= 0
3305   endif
3306"   call Decho("setting s:haskdeinit=".s:haskdeinit)
3307  endif
3308
3309  if a:remote == 1
3310   " create a local copy
3311"   call Decho("a:remote=".a:remote.": create a local copy of <".a:fname.">")
3312   setlocal bh=delete
3313   call netrw#NetRead(3,a:fname)
3314   " attempt to rename tempfile
3315   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
3316   let newname= substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
3317"   call Decho("basename<".basename.">")
3318"   call Decho("newname <".newname.">")
3319   if rename(s:netrw_tmpfile,newname) == 0
3320    " renaming succeeded
3321    let fname= newname
3322   else
3323    " renaming failed
3324    let fname= s:netrw_tmpfile
3325   endif
3326  else
3327   let fname= a:fname
3328   " special ~ handler for local
3329   if fname =~ '^\~' && expand("$HOME") != ""
3330"    call Decho('invoking special ~ handler')
3331    let fname= substitute(fname,'^\~',expand("$HOME"),'')
3332   endif
3333  endif
3334"  call Decho("fname<".fname.">")
3335"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten))
3336
3337  " set up redirection
3338  if &srr =~ "%s"
3339   if (has("win32") || has("win95") || has("win64") || has("win16"))
3340    let redir= substitute(&srr,"%s","nul","")
3341   else
3342    let redir= substitute(&srr,"%s","/dev/null","")
3343   endif
3344  elseif (has("win32") || has("win95") || has("win64") || has("win16"))
3345   let redir= &srr . "nul"
3346  else
3347   let redir= &srr . "/dev/null"
3348  endif
3349"  call Decho("redir{".redir."} srr{".&srr."}")
3350
3351  " extract any viewing options.  Assumes that they're set apart by quotes.
3352  if exists("g:netrw_browsex_viewer")
3353"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">")
3354   if g:netrw_browsex_viewer =~ '\s'
3355    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
3356    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
3357    let oviewer = ''
3358    let cnt     = 1
3359    while !executable(viewer) && viewer != oviewer
3360     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
3361     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
3362     let cnt     = cnt + 1
3363     let oviewer = viewer
3364"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">")
3365    endwhile
3366   else
3367    let viewer  = g:netrw_browsex_viewer
3368    let viewopt = ""
3369   endif
3370"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">")
3371  endif
3372
3373  " execute the file handler
3374  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
3375"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">")
3376   let ret= netrwFileHandlers#Invoke(exten,fname)
3377
3378  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
3379"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">")
3380"   call Decho("exe silent !".viewer." ".viewopt.shellescape(fname,1).redir)
3381   exe "silent !".viewer." ".viewopt.shellescape(fname,1).redir
3382   let ret= v:shell_error
3383
3384  elseif has("win32") || has("win64")
3385   if executable("start")
3386"    call Decho('exe silent !start rundll32 url.dll,FileProtocolHandler '.shellescape(fname,1))
3387    exe 'silent !start rundll32 url.dll,FileProtocolHandler '.shellescape(fname,1)
3388   elseif executable("rundll32")
3389"    call Decho('exe silent !rundll32 url.dll,FileProtocolHandler '.shellescape(fname,1))
3390    exe 'silent !rundll32 url.dll,FileProtocolHandler '.shellescape(fname,1)
3391   else
3392    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
3393   endif
3394   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3395   let ret= v:shell_error
3396
3397  elseif has("unix") && executable("gnome-open") && !s:haskdeinit
3398"   call Decho("exe silent !gnome-open ".shellescape(fname,1)." ".redir)
3399   exe "sil !gnome-open ".shellescape(fname,1).redir
3400   let ret= v:shell_error
3401
3402  elseif has("unix") && executable("kfmclient") && s:haskdeinit
3403"   call Decho("exe silent !kfmclient exec ".shellescape(fname,1)." ".redir)
3404   exe "sil !kfmclient exec ".shellescape(fname,1)." ".redir
3405   let ret= v:shell_error
3406
3407  elseif has("macunix") && executable("open")
3408"   call Decho("exe silent !open ".shellescape(fname,1)." ".redir)
3409   exe "sil !open ".shellescape(fname,1)." ".redir
3410   let ret= v:shell_error
3411
3412  else
3413   " netrwFileHandlers#Invoke() always returns 0
3414   let ret= netrwFileHandlers#Invoke(exten,fname)
3415  endif
3416
3417  " if unsuccessful, attempt netrwFileHandlers#Invoke()
3418  if ret
3419   let ret= netrwFileHandlers#Invoke(exten,fname)
3420  endif
3421
3422  " restoring redraw! after external file handlers
3423  redraw!
3424
3425  " cleanup: remove temporary file,
3426  "          delete current buffer if success with handler,
3427  "          return to prior buffer (directory listing)
3428  "          Feb 12, 2008: had to de-activiate removal of
3429  "          temporary file because it wasn't getting seen.
3430"  if a:remote == 1 && fname != a:fname
3431"   call Decho("deleting temporary file<".fname.">")
3432"   call s:NetrwDelete(fname)
3433"  endif
3434
3435  if a:remote == 1
3436   setlocal bh=delete bt=nofile
3437   if g:netrw_use_noswf
3438    setlocal noswf
3439   endif
3440   exe "keepj norm! \<c-o>"
3441"   redraw!
3442  endif
3443
3444"  call Dret("NetrwBrowseX")
3445endfun
3446
3447" ---------------------------------------------------------------------
3448" s:NetrwChgPerm: (implements "gp") change file permission {{{2
3449fun! s:NetrwChgPerm(islocal,curdir)
3450"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
3451  call inputsave()
3452  let newperm= input("Enter new permission: ")
3453  call inputrestore()
3454  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',shellescape(expand("<cfile>")),'')
3455  let chgperm= substitute(chgperm,'\<PERM\>',shellescape(newperm),'')
3456"  call Decho("chgperm<".chgperm.">")
3457  call system(chgperm)
3458  if v:shell_error != 0
3459   call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
3460  endif
3461  if a:islocal
3462   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
3463  endif
3464"  call Dret("s:NetrwChgPerm")
3465endfun
3466
3467" ---------------------------------------------------------------------
3468" s:NetrwClearExplore: clear explore variables (if any) {{{2
3469fun! s:NetrwClearExplore()
3470"  call Dfunc("s:NetrwClearExplore()")
3471  2match none
3472  if exists("s:explore_match")        |unlet s:explore_match        |endif
3473  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
3474  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
3475  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
3476  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
3477  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
3478  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
3479  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
3480  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
3481"   redraw!
3482  echo " "
3483  echo " "
3484"  call Dret("s:NetrwClearExplore")
3485endfun
3486
3487" ---------------------------------------------------------------------
3488" netrw#Explore: launch the local browser in the directory of the current file {{{2
3489"          indx:  == -1: Nexplore
3490"                 == -2: Pexplore
3491"                 ==  +: this is overloaded:
3492"                      * If Nexplore/Pexplore is in use, then this refers to the
3493"                        indx'th item in the w:netrw_explore_list[] of items which
3494"                        matched the */pattern **/pattern *//pattern **//pattern
3495"                      * If Hexplore or Vexplore, then this will override
3496"                        g:netrw_winsize to specify the qty of rows or columns the
3497"                        newly split window should have.
3498"          dosplit==0: the window will be split iff the current file has been modified
3499"          dosplit==1: the window will be split before running the local browser
3500"          style == 0: Explore     style == 1: Explore!
3501"                == 2: Hexplore    style == 3: Hexplore!
3502"                == 4: Vexplore    style == 5: Vexplore!
3503"                == 6: Texplore
3504fun! netrw#Explore(indx,dosplit,style,...)
3505"  call Dfunc("netrw#Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.",a:1<".a:1.">) &modified=".&modified." a:0=".a:0)
3506  if !exists("b:netrw_curdir")
3507   let b:netrw_curdir= getcwd()
3508"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)")
3509  endif
3510  let curdir     = simplify(b:netrw_curdir)
3511  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
3512"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">")
3513"  call FOTEST(1)
3514
3515  " save registers
3516  sil! let keepregstar = @*
3517  sil! let keepregplus = @+
3518  sil! let keepregslash= @/
3519
3520  " if dosplit or file has been modified
3521  if a:dosplit || &modified || a:style == 6
3522"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified")
3523   call s:SaveWinVars()
3524   let winsize= g:netrw_winsize
3525   if a:indx > 0
3526    let winsize= a:indx
3527   endif
3528
3529   if a:style == 0      " Explore, Sexplore
3530"    call Decho("style=0: Explore or Sexplore")
3531    exe winsize."wincmd s"
3532
3533   elseif a:style == 1  "Explore!, Sexplore!
3534"    call Decho("style=1: Explore! or Sexplore!")
3535    exe winsize."wincmd v"
3536
3537   elseif a:style == 2  " Hexplore
3538"    call Decho("style=2: Hexplore")
3539    exe "bel ".winsize."wincmd s"
3540
3541   elseif a:style == 3  " Hexplore!
3542"    call Decho("style=3: Hexplore!")
3543    exe "abo ".winsize."wincmd s"
3544
3545   elseif a:style == 4  " Vexplore
3546"    call Decho("style=4: Vexplore")
3547    exe "lefta ".winsize."wincmd v"
3548
3549   elseif a:style == 5  " Vexplore!
3550"    call Decho("style=5: Vexplore!")
3551    exe "rightb ".winsize."wincmd v"
3552
3553   elseif a:style == 6  " Texplore
3554    call s:SaveBufVars()
3555"    call Decho("style  = 6: Texplore")
3556    tabnew
3557    call s:RestoreBufVars()
3558   endif
3559   call s:RestoreWinVars()
3560"  else " Decho
3561"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6")
3562  endif
3563  keepj norm! 0
3564"  call FOTEST(2)
3565
3566  if a:0 > 0
3567"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">")
3568   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
3569"    call Decho("case a:1: ~ and unix or cygwin")
3570    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
3571"    call Decho("using dirname<".dirname.">  (case: ~ && unix||cygwin)")
3572   elseif a:1 == '.'
3573"    call Decho("case a:1: .")
3574    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
3575    if dirname !~ '/$'
3576     let dirname= dirname."/"
3577    endif
3578"    call Decho("using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")")
3579   elseif a:1 =~ '\$'
3580"    call Decho("case a:1: $")
3581    let dirname= simplify(expand(a:1))
3582"    call Decho("using user-specified dirname<".dirname."> with $env-var")
3583   elseif a:1 !~ '^\*/'
3584"    call Decho("case a:1: other, not pattern or filepattern")
3585    let dirname= simplify(a:1)
3586"    call Decho("using user-specified dirname<".dirname.">")
3587   else
3588"    call Decho("case a:1: pattern or filepattern")
3589    let dirname= a:1
3590   endif
3591  else
3592   " clear explore
3593"   call Decho("case a:0=".a:0.": clearing Explore list")
3594   call s:NetrwClearExplore()
3595"   call Dret("netrw#Explore : cleared list")
3596   return
3597  endif
3598
3599"  call FOTEST(3)
3600"  call Decho("dirname<".dirname.">")
3601  if dirname =~ '\.\./\=$'
3602   let dirname= simplify(fnamemodify(dirname,':p:h'))
3603  elseif dirname =~ '\.\.' || dirname == '.'
3604   let dirname= simplify(fnamemodify(dirname,':p'))
3605  endif
3606"  call Decho("dirname<".dirname.">  (after simplify)")
3607
3608  if dirname =~ '/\*\*/'
3609   " handle .../**/.../filepat
3610"   call Decho("case Explore .../**/.../filepat")
3611   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
3612   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
3613    let b:netrw_curdir = prefixdir
3614   else
3615    let b:netrw_curdir= getcwd().'/'.prefixdir
3616   endif
3617   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
3618   let starpat= 4;
3619"   call Decho("pwd<".getcwd()."> dirname<".dirname.">")
3620"   call Decho("case Explore ../**/../filepat (starpat=".starpat.")")
3621
3622  elseif dirname =~ '^\*//'
3623   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
3624"   call Decho("case Explore *//pattern")
3625   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
3626   let starpat= 1
3627"   call Decho("Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">")
3628   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
3629
3630  elseif dirname =~ '^\*\*//'
3631   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
3632"   call Decho("case Explore **//pattern")
3633   let pattern= substitute(dirname,'^\*\*//','','')
3634   let starpat= 2
3635"   call Decho("Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">")
3636
3637  elseif dirname =~ '^\*/'
3638   " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
3639   let starpat= 3
3640"   call Decho("case Explore */filepat (starpat=".starpat.")")
3641
3642  elseif dirname=~ '^\*\*/'
3643   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
3644   let starpat= 4
3645"   call Decho("case Explore **/filepat (starpat=".starpat.")")
3646
3647  else
3648   let starpat= 0
3649"   call Decho("default case: starpat=".starpat)
3650  endif
3651"  call FOTEST(4)
3652
3653  if starpat == 0 && a:indx >= 0
3654   " [Explore Hexplore Vexplore Sexplore] [dirname]
3655"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname."> Explore Hexplore Vexplore Sexplore")
3656   if dirname == ""
3657    let dirname= curfiledir
3658"    call Decho("empty dirname, using current file's directory<".dirname.">")
3659   endif
3660   if dirname =~ '^scp:' || dirname =~ '^ftp:'
3661"    call Decho("calling NetrwBrowse(0,dirname<".dirname.">)")
3662    call s:NetrwBrowse(0,dirname)
3663   else
3664    if dirname == ""|let dirname= getcwd()|endif
3665"    call Decho("calling LocalBrowseCheck(dirname<".dirname.">)")
3666    call netrw#LocalBrowseCheck(dirname)
3667   endif
3668
3669"   call Decho("curdir<".curdir.">")
3670   if has("win32") || has("win95") || has("win64") || has("win16")
3671    keepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
3672   else
3673    keepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
3674   endif
3675
3676  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
3677  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
3678  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
3679  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
3680  elseif a:indx <= 0
3681   " Nexplore, Pexplore, Explore: handle starpat
3682"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx)
3683   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
3684"    call Decho("set up <s-up> and <s-down> maps")
3685    let s:didstarstar= 1
3686    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
3687    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
3688   endif
3689
3690   if has("path_extra")
3691"    call Decho("starpat=".starpat.": has +path_extra")
3692    if !exists("w:netrw_explore_indx")
3693     let w:netrw_explore_indx= 0
3694    endif
3695
3696    let indx = a:indx
3697"    call Decho("starpat=".starpat.": set indx= [a:indx=".indx."]")
3698
3699    if indx == -1
3700     " Nexplore
3701"     call Decho("case Nexplore with starpat=".starpat.": (indx=".indx.")")
3702     if !exists("w:netrw_explore_list") " sanity check
3703      call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
3704      sil! let @* = keepregstar
3705      sil! let @+ = keepregstar
3706      sil! let @/ = keepregslash
3707"      call Dret("netrw#Explore")
3708      return
3709     endif
3710     let indx= w:netrw_explore_indx
3711     if indx < 0                        | let indx= 0                           | endif
3712     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
3713     let curfile= w:netrw_explore_list[indx]
3714"     call Decho("indx=".indx." curfile<".curfile.">")
3715     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
3716      let indx= indx + 1
3717"      call Decho("indx=".indx." (Nexplore while loop)")
3718     endwhile
3719     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
3720"     call Decho("Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx)
3721
3722    elseif indx == -2
3723     " Pexplore
3724"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")")
3725     if !exists("w:netrw_explore_list") " sanity check
3726      call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
3727      sil! let @* = keepregstar
3728      sil! let @+ = keepregstar
3729      sil! let @/ = keepregslash
3730"      call Dret("netrw#Explore")
3731      return
3732     endif
3733     let indx= w:netrw_explore_indx
3734     if indx < 0                        | let indx= 0                           | endif
3735     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
3736     let curfile= w:netrw_explore_list[indx]
3737"     call Decho("indx=".indx." curfile<".curfile.">")
3738     while indx >= 0 && curfile == w:netrw_explore_list[indx]
3739      let indx= indx - 1
3740"      call Decho("indx=".indx." (Pexplore while loop)")
3741     endwhile
3742     if indx < 0                        | let indx= 0                           | endif
3743"     call Decho("Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx)
3744
3745    else
3746     " Explore -- initialize
3747     " build list of files to Explore with Nexplore/Pexplore
3748"     call Decho("starpat=".starpat.": case Explore: initialize (indx=".indx.")")
3749     call s:NetrwClearExplore()
3750     let w:netrw_explore_indx= 0
3751     if !exists("b:netrw_curdir")
3752      let b:netrw_curdir= getcwd()
3753     endif
3754"     call Decho("starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">")
3755
3756     " switch on starpat to build the w:netrw_explore_list of files
3757     if starpat == 1
3758      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
3759"      call Decho("starpat=".starpat.": build *//pattern list")
3760"      call Decho("pattern<".pattern.">")
3761      try
3762       exe "keepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
3763      catch /^Vim\%((\a\+)\)\=:E480/
3764       call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
3765"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
3766       return
3767      endtry
3768      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
3769      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
3770
3771     elseif starpat == 2
3772      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
3773"      call Decho("starpat=".starpat.": build **//pattern list")
3774      try
3775       exe "sil keepj noautocmd vimgrep /".pattern."/gj "."**/*"
3776      catch /^Vim\%((\a\+)\)\=:E480/
3777       call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
3778       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
3779       silent! let @* = keepregstar
3780       silent! let @+ = keepregstar
3781       silent! let @/ = keepregslash
3782"       call Dret("netrw#Explore : no files matched pattern")
3783       return
3784      endtry
3785      let s:netrw_curdir       = b:netrw_curdir
3786      let w:netrw_explore_list = getqflist()
3787      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
3788
3789     elseif starpat == 3
3790      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
3791"      call Decho("starpat=".starpat.": build */filepat list")
3792      let filepat= substitute(dirname,'^\*/','','')
3793      let filepat= substitute(filepat,'^[%#<]','\\&','')
3794"      call Decho("b:netrw_curdir<".b:netrw_curdir.">")
3795"      call Decho("filepat<".filepat.">")
3796      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
3797      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
3798
3799     elseif starpat == 4
3800      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
3801"      call Decho("starpat=".starpat.": build **/filepat list")
3802      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
3803      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
3804     endif " switch on starpat to build w:netrw_explore_list
3805
3806     let w:netrw_explore_listlen = len(w:netrw_explore_list)
3807"     call Decho("w:netrw_explore_list<".string(w:netrw_explore_list).">")
3808"     call Decho("w:netrw_explore_listlen=".w:netrw_explore_listlen)
3809
3810     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
3811      call netrw#ErrorMsg(s:WARNING,"no files matched",42)
3812      sil! let @* = keepregstar
3813      sil! let @+ = keepregstar
3814      sil! let @/ = keepregslash
3815"      call Dret("netrw#Explore : no files matched")
3816      return
3817     endif
3818    endif  " if indx ... endif
3819
3820    " NetrwStatusLine support - for exploring support
3821    let w:netrw_explore_indx= indx
3822"    call Decho("w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen)
3823
3824    " wrap the indx around, but issue a note
3825    if indx >= w:netrw_explore_listlen || indx < 0
3826"     call Decho("wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")")
3827     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
3828     let w:netrw_explore_indx= indx
3829     call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
3830    endif
3831
3832    exe "let dirfile= w:netrw_explore_list[".indx."]"
3833"    call Decho("dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">")
3834    let newdir= substitute(dirfile,'/[^/]*$','','e')
3835"    call Decho("newdir<".newdir.">")
3836
3837"    call Decho("calling LocalBrowseCheck(newdir<".newdir.">)")
3838    call netrw#LocalBrowseCheck(newdir)
3839    if !exists("w:netrw_liststyle")
3840     let w:netrw_liststyle= g:netrw_liststyle
3841    endif
3842    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
3843     keepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
3844    else
3845     keepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
3846    endif
3847    let w:netrw_explore_mtchcnt = indx + 1
3848    let w:netrw_explore_bufnr   = bufnr("%")
3849    let w:netrw_explore_line    = line(".")
3850    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
3851"    call Decho("explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line)
3852
3853   else
3854"    call Decho("your vim does not have +path_extra")
3855    if !exists("g:netrw_quiet")
3856     call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
3857    endif
3858    sil! let @* = keepregstar
3859    sil! let @+ = keepregstar
3860    sil! let @/ = keepregslash
3861"    call Dret("netrw#Explore : missing +path_extra")
3862    return
3863   endif
3864
3865  else
3866"   call Decho("default case: Explore newdir<".dirname.">")
3867   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
3868    sil! unlet w:netrw_treedict
3869    sil! unlet w:netrw_treetop
3870   endif
3871   let newdir= dirname
3872   if !exists("b:netrw_curdir")
3873    call netrw#LocalBrowseCheck(getcwd())
3874   else
3875    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
3876   endif
3877  endif
3878"  call FOTEST(5)
3879
3880  " visual display of **/ **// */ Exploration files
3881"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"))
3882"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">")
3883  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
3884"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"))
3885   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
3886    " only update match list if current directory isn't the same as before
3887"    call Decho("only update match list if current directory not the same as before")
3888    let s:explore_prvdir = b:netrw_curdir
3889    let s:explore_match  = ""
3890    let dirlen           = s:Strlen(b:netrw_curdir)
3891    if b:netrw_curdir !~ '/$'
3892     let dirlen= dirlen + 1
3893    endif
3894    let prvfname= ""
3895    for fname in w:netrw_explore_list
3896"     call Decho("fname<".fname.">")
3897     if fname =~ '^'.b:netrw_curdir
3898      if s:explore_match == ""
3899       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
3900      else
3901       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
3902      endif
3903     elseif fname !~ '^/' && fname != prvfname
3904      if s:explore_match == ""
3905       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
3906      else
3907       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
3908      endif
3909     endif
3910     let prvfname= fname
3911    endfor
3912"    call Decho("explore_match<".s:explore_match.">")
3913    exe "2match netrwMarkFile /".s:explore_match."/"
3914   endif
3915   echo "<s-up>==Pexplore  <s-down>==Nexplore"
3916  else
3917   2match none
3918   if exists("s:explore_match")  | unlet s:explore_match  | endif
3919   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
3920   echo " "
3921"   call Decho("cleared explore match list")
3922  endif
3923"  call FOTEST(6)
3924
3925  sil! let @* = keepregstar
3926  sil! let @+ = keepregstar
3927  sil! let @/ = keepregslash
3928"  call Dret("netrw#Explore : @/<".@/.">")
3929endfun
3930
3931" ---------------------------------------------------------------------
3932" s:NetrwExploreListUniq: {{{2
3933fun! s:NetrwExploreListUniq(explist)
3934"  call Dfunc("s:NetrwExploreListUniq(explist)")
3935
3936  " this assumes that the list is already sorted
3937  let newexplist= []
3938  for member in a:explist
3939   if !exists("uniqmember") || member != uniqmember
3940    let uniqmember = member
3941    let newexplist = newexplist + [ member ]
3942   endif
3943  endfor
3944
3945"  call Dret("s:NetrwExploreListUniq")
3946  return newexplist
3947endfun
3948
3949" ---------------------------------------------------------------------
3950" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
3951"          and switches the hiding mode.  The actual hiding is done by
3952"          s:NetrwListHide().
3953"             g:netrw_hide= 0: show all
3954"                           1: show not-hidden files
3955"                           2: show hidden files only
3956fun! s:NetrwHide(islocal)
3957"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
3958  let svpos= netrw#NetrwSavePosn()
3959
3960  if exists("s:netrwmarkfilelist_{bufnr('%')}")
3961"   call Decho(((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">")
3962"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">")
3963
3964   " hide the files in the markfile list
3965   for fname in s:netrwmarkfilelist_{bufnr("%")}
3966"    call Decho("match(g:netrw_list_hide<".g:netrw_list_hide.'> fname<\<'.fname.'\>>)='.match(g:netrw_list_hide,'\<'.fname.'\>')." isk=".&isk)
3967    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
3968     " remove fname from hiding list
3969     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
3970     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
3971     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
3972"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">")
3973    else
3974     " append fname to hiding list
3975     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
3976      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
3977     else
3978      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
3979     endif
3980"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">")
3981    endif
3982   endfor
3983   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
3984   let g:netrw_hide= 1
3985
3986  else
3987
3988   " switch between show-all/show-not-hidden/show-hidden
3989   let g:netrw_hide=(g:netrw_hide+1)%3
3990   exe "keepj norm! 0"
3991   if g:netrw_hide && g:netrw_list_hide == ""
3992    call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
3993"    call Dret("NetrwHide")
3994    return
3995   endif
3996  endif
3997
3998  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
3999  call netrw#NetrwRestorePosn(svpos)
4000"  call Dret("NetrwHide")
4001endfun
4002
4003" ---------------------------------------------------------------------
4004" s:NetrwHidden: invoked by "gh" {{{2
4005fun! s:NetrwHidden(islocal)
4006"  call Dfunc("s:NetrwHidden()")
4007  "  save current position
4008  let svpos= netrw#NetrwSavePosn()
4009
4010  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
4011   " remove pattern from hiding list
4012   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
4013  elseif s:Strlen(g:netrw_list_hide) >= 1
4014   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
4015  else
4016   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
4017  endif
4018
4019  " refresh screen and return to saved position
4020  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4021  call netrw#NetrwRestorePosn(svpos)
4022"  call Dret("s:NetrwHidden")
4023endfun
4024
4025" ---------------------------------------------------------------------
4026"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
4027fun! s:NetrwHome()
4028  if exists("g:netrw_home")
4029   let home= g:netrw_home
4030  else
4031   " go to vim plugin home
4032   for home in split(&rtp,',') + ['']
4033    if isdirectory(home) && filewritable(home) | break | endif
4034     let basehome= substitute(home,'[/\\]\.vim$','','')
4035    if isdirectory(basehome) && filewritable(basehome)
4036     let home= basehome."/.vim"
4037     break
4038    endif
4039   endfor
4040   if home == ""
4041    " just pick the first directory
4042    let home= substitute(&rtp,',.*$','','')
4043   endif
4044   if (has("win32") || has("win95") || has("win64") || has("win16"))
4045    let home= substitute(home,'/','\\','g')
4046   endif
4047  endif
4048  " insure that the home directory exists
4049  if !isdirectory(home)
4050   if exists("g:netrw_mkdir")
4051    call system(g:netrw_mkdir." ".shellescape(home))
4052   else
4053    call mkdir(home)
4054   endif
4055  endif
4056  let g:netrw_home= home
4057  return home
4058endfun
4059
4060" ---------------------------------------------------------------------
4061" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
4062fun! s:NetrwLeftmouse(islocal)
4063"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
4064
4065  " check if the status bar was clicked on instead of a file/directory name
4066  call feedkeys("\<LeftMouse>")
4067  let c= getchar()
4068  let mouse_lnum = v:mouse_lnum
4069  let wlastline  = line('w$')
4070  let lastline   = line('$')
4071"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr())
4072"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0))
4073  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
4074   " appears to be a status bar leftmouse click
4075"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
4076   return
4077  endif
4078  if v:mouse_col != col('.')
4079"   call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
4080   return
4081  endif
4082
4083  if a:islocal
4084   if exists("b:netrw_curdir")
4085    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
4086   endif
4087  else
4088   if exists("b:netrw_curdir")
4089    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
4090   endif
4091  endif
4092"  call Dret("s:NetrwLeftmouse")
4093endfun
4094
4095" ---------------------------------------------------------------------
4096" s:NetrwListHide: uses [range]g~...~d to delete files that match comma {{{2
4097" separated patterns given in g:netrw_list_hide
4098fun! s:NetrwListHide()
4099"  call Dfunc("NetrwListHide() hide=".g:netrw_hide." listhide<".g:netrw_list_hide.">")
4100
4101  " find a character not in the "hide" string to use as a separator for :g and :v commands
4102  " How-it-works: take the hiding command, convert it into a range.  Duplicate
4103  " characters don't matter.  Remove all such characters from the '/~...90'
4104  " string.  Use the first character left as a separator character.
4105  let listhide= g:netrw_list_hide
4106  let sep     = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
4107"  call Decho("sep=".sep)
4108
4109  while listhide != ""
4110   if listhide =~ ','
4111    let hide     = substitute(listhide,',.*$','','e')
4112    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
4113   else
4114    let hide     = listhide
4115    let listhide = ""
4116   endif
4117
4118   " Prune the list by hiding any files which match
4119   if g:netrw_hide == 1
4120"    call Decho("hiding<".hide."> listhide<".listhide.">")
4121    exe 'sil keepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
4122   elseif g:netrw_hide == 2
4123"    call Decho("showing<".hide."> listhide<".listhide.">")
4124    exe 'sil keepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
4125   endif
4126  endwhile
4127  if g:netrw_hide == 2
4128   exe 'sil keepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
4129   exe 'sil keepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
4130  endif
4131
4132"  call Dret("NetrwListHide")
4133endfun
4134
4135" ---------------------------------------------------------------------
4136" NetrwHideEdit: allows user to edit the file/directory hiding list
4137fun! s:NetrwHideEdit(islocal)
4138"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
4139
4140  " save current cursor position
4141  let svpos= netrw#NetrwSavePosn()
4142
4143  " get new hiding list from user
4144  call inputsave()
4145  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
4146  call inputrestore()
4147  let g:netrw_list_hide= newhide
4148"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">")
4149
4150  " refresh the listing
4151  silent keepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
4152
4153  " restore cursor position
4154  call netrw#NetrwRestorePosn(svpos)
4155
4156"  call Dret("NetrwHideEdit")
4157endfun
4158
4159" ---------------------------------------------------------------------
4160" NetSortSequence: allows user to edit the sorting sequence
4161fun! s:NetSortSequence(islocal)
4162"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
4163
4164  let svpos= netrw#NetrwSavePosn()
4165  call inputsave()
4166  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
4167  call inputrestore()
4168
4169  " refresh the listing
4170  let g:netrw_sort_sequence= newsortseq
4171  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4172  call netrw#NetrwRestorePosn(svpos)
4173
4174"  call Dret("NetSortSequence")
4175endfun
4176
4177" ---------------------------------------------------------------------
4178" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
4179fun! s:NetrwMakeDir(usrhost)
4180"  call Dfunc("NetrwMakeDir(usrhost<".a:usrhost.">)")
4181
4182  " get name of new directory from user.  A bare <CR> will skip.
4183  " if its currently a directory, also request will be skipped, but with
4184  " a message.
4185  call inputsave()
4186  let newdirname= input("Please give directory name: ")
4187  call inputrestore()
4188"  call Decho("newdirname<".newdirname.">")
4189
4190  if newdirname == ""
4191"   call Dret("NetrwMakeDir : user aborted with bare <cr>")
4192   return
4193  endif
4194
4195  if a:usrhost == ""
4196"   call Decho("local mkdir")
4197
4198   " Local mkdir:
4199   " sanity checks
4200   let fullnewdir= b:netrw_curdir.'/'.newdirname
4201"   call Decho("fullnewdir<".fullnewdir.">")
4202   if isdirectory(fullnewdir)
4203    if !exists("g:netrw_quiet")
4204     call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
4205    endif
4206"    call Dret("NetrwMakeDir : directory<".newdirname."> exists previously")
4207    return
4208   endif
4209   if s:FileReadable(fullnewdir)
4210    if !exists("g:netrw_quiet")
4211     call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
4212    endif
4213"    call Dret("NetrwMakeDir : file<".newdirname."> exists previously")
4214    return
4215   endif
4216
4217   " requested new local directory is neither a pre-existing file or
4218   " directory, so make it!
4219   if exists("*mkdir")
4220    call mkdir(fullnewdir,"p")
4221   else
4222    let netrw_origdir= s:NetrwGetcwd(1)
4223    exe 'keepj lcd '.fnameescape(b:netrw_curdir)
4224"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">")
4225"    call Decho("exe silent! !".g:netrw_local_mkdir.' '.shellescape(newdirname,1))
4226    exe "sil! !".g:netrw_local_mkdir.' '.shellescape(newdirname,1)
4227    if !g:netrw_keepdir
4228     exe 'keepj lcd '.fnameescape(netrw_origdir)
4229"     call Decho("netrw_keepdir=".g:netrw_keepdir.": keepjumps lcd ".fnameescape(netrw_origdir)." getcwd<".getcwd().">")
4230    endif
4231   endif
4232
4233   if v:shell_error == 0
4234    " refresh listing
4235"    call Decho("refresh listing")
4236    let svpos= netrw#NetrwSavePosn()
4237    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
4238    call netrw#NetrwRestorePosn(svpos)
4239   elseif !exists("g:netrw_quiet")
4240    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
4241   endif
4242"   redraw!
4243
4244  elseif !exists("b:netrw_method") || b:netrw_method == 4
4245   " Remote mkdir:
4246"   call Decho("remote mkdir")
4247   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
4248   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
4249"   call Decho("exe silent! !".mkdircmd." ".shellescape(newdirname,1))
4250   exe "sil! !".mkdircmd." ".shellescape(newdirname,1)
4251   if v:shell_error == 0
4252    " refresh listing
4253    let svpos= netrw#NetrwSavePosn()
4254    call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
4255    call netrw#NetrwRestorePosn(svpos)
4256   elseif !exists("g:netrw_quiet")
4257    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
4258   endif
4259"   redraw!
4260
4261  elseif b:netrw_method == 2
4262   " COMBAK -- future work
4263   call netrw#ErrorMsg(s:ERROR,"making directories via ftp not currently supported",68)
4264  elseif b:netrw_method == 3
4265   " COMBAK -- future work
4266   call netrw#ErrorMsg(s:ERROR,"making directories via ftp not currently supported",68)
4267  endif
4268
4269"  call Dret("NetrwMakeDir")
4270endfun
4271
4272" ---------------------------------------------------------------------
4273" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
4274"                  mark and unmark files.  If a markfile list exists,
4275"                  then the rename and delete functions will use it instead
4276"                  of whatever may happen to be under the cursor at that
4277"                  moment.  When the mouse and gui are available,
4278"                  shift-leftmouse may also be used to mark files.
4279"
4280"  Creates two lists
4281"    s:netrwmarkfilelist    -- holds complete paths to all marked files
4282"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
4283"
4284"  Creates a marked file match string
4285"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
4286"
4287"  Creates a buffer version of islocal
4288"    b:netrw_islocal
4289"
4290fun! s:NetrwMarkFile(islocal,fname)
4291"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
4292  let curbufnr= bufnr("%")
4293  let curdir  = b:netrw_curdir
4294  let trailer = '[@=|\/\*]\=\>'
4295  if exists("s:netrwmarkfilelist_{curbufnr}")
4296   " markfile list exists
4297"   call Decho("starting s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">")
4298"   call Decho("starting s:netrwmarkfilemtch_{curbufnr}<".s:netrwmarkfilemtch_{curbufnr}.">")
4299   let b:netrw_islocal= a:islocal
4300
4301   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
4302    " append filename to buffer's markfilelist
4303"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">")
4304    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
4305    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|\<'.escape(a:fname,g:netrw_markfileesc."'".g:netrw_markfileesc."'").trailer
4306
4307   else
4308    " remove filename from buffer's markfilelist
4309"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">")
4310    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
4311    if s:netrwmarkfilelist_{curbufnr} == []
4312     " local markfilelist is empty; remove it entirely
4313"     call Decho("markfile list now empty")
4314     call s:NetrwUnmarkList(curbufnr,curdir)
4315    else
4316     " rebuild match list to display markings correctly
4317"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr)
4318     let s:netrwmarkfilemtch_{curbufnr}= ""
4319     let first                           = 1
4320     for fname in s:netrwmarkfilelist_{curbufnr}
4321      if first
4322       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\<'.escape(fname,g:netrw_markfileesc."'".g:netrw_markfileesc."'").trailer
4323      else
4324       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|\<'.escape(fname,g:netrw_markfileesc."'".g:netrw_markfileesc."'").trailer
4325      endif
4326      let first= 0
4327     endfor
4328"     call Decho("ending s:netrwmarkfilelist_"curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">")
4329"     call Decho("ending s:netrwmarkfilemtch_"curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">")
4330    endif
4331   endif
4332
4333  else
4334   " initialize new markfilelist
4335
4336"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr)
4337   let s:netrwmarkfilelist_{curbufnr}= []
4338   call add(s:netrwmarkfilelist_{curbufnr},a:fname)
4339"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">")
4340
4341   " build initial markfile matching pattern
4342   if a:fname =~ '/$'
4343    let s:netrwmarkfilemtch_{curbufnr}= '\<'.escape(a:fname,g:netrw_markfileesc)
4344   else
4345    let s:netrwmarkfilemtch_{curbufnr}= '\<'.escape(a:fname,g:netrw_markfileesc).trailer
4346   endif
4347"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">")
4348  endif
4349
4350  " handle global markfilelist
4351  if exists("s:netrwmarkfilelist")
4352   let dname= s:ComposePath(b:netrw_curdir,a:fname)
4353   if index(s:netrwmarkfilelist,dname) == -1
4354    " append new filename to global markfilelist
4355    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
4356"    call Decho("append filename<".a:fname."> to global markfilelist<".string(s:netrwmarkfilelist).">")
4357   else
4358    " remove new filename from global markfilelist
4359"    call Decho("filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")")
4360    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
4361"    call Decho("ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">")
4362    if s:netrwmarkfilelist == []
4363     unlet s:netrwmarkfilelist
4364    endif
4365   endif
4366  else
4367   " initialize new global-directory markfilelist
4368   let s:netrwmarkfilelist= []
4369   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
4370"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">")
4371  endif
4372
4373  " set up 2match'ing to netrwmarkfilemtch list
4374  if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
4375"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/")
4376   if exists("g:did_drchip_netrwlist_syntax")
4377    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
4378   endif
4379  else
4380"   call Decho("2match none")
4381   2match none
4382  endif
4383"  call Dret("s:NetrwMarkFile : netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">")
4384endfun
4385
4386" ---------------------------------------------------------------------
4387" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
4388"                          compress/decompress files using the programs
4389"                          in g:netrw_compress and g:netrw_uncompress,
4390"                          using g:netrw_compress_suffix to know which to
4391"                          do.  By default:
4392"                            g:netrw_compress        = "gzip"
4393"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf"}
4394fun! s:NetrwMarkFileCompress(islocal)
4395"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
4396  let svpos    = netrw#NetrwSavePosn()
4397  let curdir   = b:netrw_curdir
4398  let curbufnr = bufnr("%")
4399
4400  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
4401   for fname in s:netrwmarkfilelist_{curbufnr}
4402    " for every filename in the marked list
4403    for sfx in sort(keys(g:netrw_decompress))
4404     if fname =~ '\'.sfx.'$'
4405      " fname has a suffix indicating that its compressed; apply associated decompression routine
4406      let exe= netrw#WinPath(g:netrw_decompress[sfx])
4407"      call Decho("fname<".fname."> is compressed so decompress with <".exe.">")
4408      if a:islocal
4409       if g:netrw_keepdir
4410        let fname= shellescape(s:ComposePath(curdir,fname))
4411       endif
4412      else
4413       let fname= shellescape(b:netrw_curdir.fname,1)
4414      endif
4415      if executable(exe)
4416       if a:islocal
4417	call system(exe." ".fname)
4418       else
4419        call s:RemoteSystem(exe." ".fname)
4420       endif
4421      else
4422       call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
4423      endif
4424      break
4425     endif
4426    endfor
4427    if exists("exe")
4428     unlet exe
4429    elseif a:islocal
4430     " fname not a compressed file, so compress it
4431     call system(netrw#WinPath(g:netrw_compress)." ".shellescape(s:ComposePath(b:netrw_curdir,fname)))
4432    else
4433     " fname not a compressed file, so compress it
4434     call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".shellescape(fname))
4435    endif
4436   endfor
4437   call s:NetrwUnmarkList(curbufnr,curdir)
4438   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4439   call netrw#NetrwRestorePosn(svpos)
4440  endif
4441"  call Dret("s:NetrwMarkFileCompress")
4442endfun
4443
4444" ---------------------------------------------------------------------
4445" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
4446"                      If no marked files, then set up directory as the
4447"                      target.  Currently does not support copying entire
4448"                      directories.  Uses the local-buffer marked file list.
4449"                      Returns 1=success  (used by NetrwMarkFileMove())
4450"                              0=failure
4451fun! s:NetrwMarkFileCopy(islocal)
4452"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---').">")
4453
4454  " sanity checks
4455  if !exists("s:netrwmarkfilelist_{bufnr('%')}") || empty(s:netrwmarkfilelist_{bufnr('%')})
4456   call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
4457"   call Dret("s:NetrwMarkFileCopy 0")
4458   return 0
4459  endif
4460"  call Decho("sanity chk passed: s:netrwmarkfilelist_".bufnr('%')."<".string(s:netrwmarkfilelist_{bufnr('%')}))
4461  if !exists("s:netrwmftgt")
4462   call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
4463"   call Dret("s:NetrwMarkFileCopy 0")
4464   return 0
4465  endif
4466"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">")
4467  let curdir   = b:netrw_curdir
4468  let curbufnr = bufnr("%")
4469
4470  if      a:islocal &&  s:netrwmftgt_islocal
4471   " Copy marked files, local directory to local directory
4472"   call Decho("copy from local to local")
4473   let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"shellescape(b:netrw_curdir.\"/\".v:val)"))
4474"   call Decho("system(".g:netrw_localcopycmd." ".args." ".shellescape(s:netrwmftgt).")")
4475   call system(netrw#WinPath(g:netrw_localcopycmd)." ".args." ".shellescape(s:netrwmftgt))
4476
4477  elseif  a:islocal && !s:netrwmftgt_islocal
4478   " Copy marked files, local directory to remote directory
4479"   call Decho("copy from local to remote")
4480   call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
4481
4482  elseif !a:islocal &&  s:netrwmftgt_islocal
4483"   call Decho("copy from remote to local")
4484   call netrw#NetrwObtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
4485
4486  elseif !a:islocal && !s:netrwmftgt_islocal
4487"   call Decho("copy from remote to remote")
4488   let curdir = getcwd()
4489   let tmpdir = s:GetTempfile("")
4490   if tmpdir !~ '/'
4491    let tmpdir= curdir."/".tmpdir
4492   endif
4493   if exists("*mkdir")
4494    call mkdir(tmpdir)
4495   else
4496    exe "sil! !".g:netrw_local_mkdir.' '.shellescape(tmpdir,1)
4497   endif
4498   if isdirectory(tmpdir)
4499    exe "keepj lcd ".fnameescape(tmpdir)
4500    call netrw#NetrwObtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
4501    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
4502    call s:NetrwUpload(localfiles,s:netrwmftgt)
4503    if getcwd() == tmpdir
4504     for fname in s:netrwmarkfilelist_{bufnr('%')}
4505      call s:NetrwDelete(fname)
4506     endfor
4507     exe "keepj lcd ".fnameescape(curdir)
4508     exe "sil !".g:netrw_local_rmdir." ".shellescape(tmpdir,1)
4509    else
4510     exe "keepj lcd ".fnameescape(curdir)
4511    endif
4512   endif
4513  endif
4514
4515  " -------
4516  " cleanup
4517  " -------
4518"  call Decho("cleanup")
4519
4520  " remove markings from local buffer
4521  call s:NetrwUnmarkList(curbufnr,curdir)
4522
4523  " refresh buffers
4524  if !s:netrwmftgt_islocal
4525   call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
4526  endif
4527  if a:islocal
4528   call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
4529  endif
4530  if g:netrw_fastbrowse <= 1
4531   call s:LocalBrowseShellCmdRefresh()
4532  endif
4533
4534"  call Dret("s:NetrwMarkFileCopy 1")
4535  return 1
4536endfun
4537
4538" ---------------------------------------------------------------------
4539" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
4540"                      invoke vim's diff mode on the marked files.
4541"                      Either two or three files can be so handled.
4542"                      Uses the global marked file list.
4543fun! s:NetrwMarkFileDiff(islocal)
4544"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
4545  let curbufnr= bufnr("%")
4546
4547  if exists("s:netrwmarkfilelist_{curbufnr}")
4548   let cnt    = 0
4549   let curdir = b:netrw_curdir
4550   for fname in s:netrwmarkfilelist
4551    let cnt= cnt + 1
4552    if cnt == 1
4553"     call Decho("diffthis: fname<".fname.">")
4554     exe "e ".fnameescape(fname)
4555     diffthis
4556    elseif cnt == 2 || cnt == 3
4557     vsplit
4558     wincmd l
4559"     call Decho("diffthis: ".fname)
4560     exe "e ".fnameescape(fname)
4561     diffthis
4562    else
4563     break
4564    endif
4565   endfor
4566   call s:NetrwUnmarkList(curbufnr,curdir)
4567  endif
4568
4569"  call Dret("s:NetrwMarkFileDiff")
4570endfun
4571
4572" ---------------------------------------------------------------------
4573" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
4574"                       Uses global markfilelist
4575fun! s:NetrwMarkFileEdit(islocal)
4576"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
4577
4578  let curdir   = b:netrw_curdir
4579  let curbufnr = bufnr("%")
4580  if exists("s:netrwmarkfilelist_{curbufnr}")
4581   call s:SetRexDir(a:islocal,curdir)
4582   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
4583   " unmark markedfile list
4584"   call s:NetrwUnmarkList(curbufnr,curdir)
4585   call s:NetrwUnmarkAll()
4586"   call Decho("exe silent args ".flist)
4587   exe "silent args ".flist
4588  endif
4589
4590"  call Dret("s:NetrwMarkFileEdit")
4591endfun
4592
4593" ---------------------------------------------------------------------
4594" s:NetrwMarkFileExe: (invoked by mx) execute arbitrary command on marked files, one at a time {{{2
4595"                     Uses the local marked-file list.
4596fun! s:NetrwMarkFileExe(islocal)
4597"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.")")
4598  let svpos    = netrw#NetrwSavePosn()
4599  let curdir   = b:netrw_curdir
4600  let curbufnr = bufnr("%")
4601
4602  if exists("s:netrwmarkfilelist_{curbufnr}")
4603   " get the command
4604   call inputsave()
4605   let cmd= input("Enter command: ","","file")
4606   call inputrestore()
4607"   call Decho("cmd<".cmd.">")
4608
4609   " apply command to marked files.  Substitute: filename -> %
4610   " If no %, then append a space and the filename to the command
4611   for fname in s:netrwmarkfilelist_{curbufnr}
4612    if a:islocal
4613     if g:netrw_keepdir
4614      let fname= shellescape(netrw#WinPath(s:ComposePath(curdir,fname)))
4615     endif
4616    else
4617     let fname= shellescape(netrw#WinPath(b:netrw_curdir.fname))
4618    endif
4619    if cmd =~ '%'
4620     let xcmd= substitute(cmd,'%',fname,'g')
4621    else
4622     let xcmd= cmd.' '.fname
4623    endif
4624    if a:islocal
4625"     call Decho("local: xcmd<".xcmd.">")
4626     let ret= system(xcmd)
4627    else
4628"     call Decho("remote: xcmd<".xcmd.">")
4629     let ret= s:RemoteSystem(xcmd)
4630    endif
4631    if v:shell_error < 0
4632     call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
4633     break
4634    else
4635     echo ret
4636    endif
4637   endfor
4638
4639   " unmark marked file list
4640   call s:NetrwUnmarkList(curbufnr,curdir)
4641
4642   " refresh the listing
4643   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4644   call netrw#NetrwRestorePosn(svpos)
4645  else
4646   call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
4647  endif
4648
4649"  call Dret("s:NetrwMarkFileExe")
4650endfun
4651
4652" ---------------------------------------------------------------------
4653" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
4654"                  as the marked file(s) (toggles suffix presence)
4655"                  Uses the local marked file list.
4656fun! s:NetrwMarkHideSfx(islocal)
4657"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
4658  let svpos    = netrw#NetrwSavePosn()
4659  let curbufnr = bufnr("%")
4660
4661  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
4662  if exists("s:netrwmarkfilelist_{curbufnr}")
4663
4664   for fname in s:netrwmarkfilelist_{curbufnr}
4665"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">")
4666     " construct suffix pattern
4667     if fname =~ '\.'
4668      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
4669     else
4670      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
4671     endif
4672     " determine if its in the hiding list or not
4673     let inhidelist= 0
4674     if g:netrw_list_hide != ""
4675      let itemnum = 0
4676      let hidelist= split(g:netrw_list_hide,',')
4677      for hidepat in hidelist
4678       if sfxpat == hidepat
4679        let inhidelist= 1
4680        break
4681       endif
4682       let itemnum= itemnum + 1
4683      endfor
4684     endif
4685"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">")
4686     if inhidelist
4687      " remove sfxpat from list
4688      call remove(hidelist,itemnum)
4689      let g:netrw_list_hide= join(hidelist,",")
4690     elseif g:netrw_list_hide != ""
4691      " append sfxpat to non-empty list
4692      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
4693     else
4694      " set hiding list to sfxpat
4695      let g:netrw_list_hide= sfxpat
4696     endif
4697    endfor
4698
4699   " refresh the listing
4700   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4701   call netrw#NetrwRestorePosn(svpos)
4702  else
4703   call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
4704  endif
4705
4706"  call Dret("s:NetrwMarkHideSfx")
4707endfun
4708
4709" ---------------------------------------------------------------------
4710" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
4711"                     Uses the global markfilelist
4712fun! s:NetrwMarkFileGrep(islocal)
4713"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
4714  let svpos    = netrw#NetrwSavePosn()
4715  let curbufnr = bufnr("%")
4716
4717  if exists("s:netrwmarkfilelist")
4718"  call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">")
4719   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
4720   call s:NetrwUnmarkAll()
4721
4722   " ask user for pattern
4723   call inputsave()
4724   let pat= input("Enter pattern: ","")
4725   call inputrestore()
4726   if pat !~ '^\s'
4727    if pat !~ '^/'
4728     let pat= '/'.pat.'/'
4729    endif
4730    let pat= " ".pat
4731   endif
4732
4733   " use vimgrep for both local and remote
4734"   call Decho("exe vimgrep".pat." ".netrwmarkfilelist)
4735   try
4736    exe "keepj noautocmd vimgrep".pat." ".netrwmarkfilelist
4737    catch /^Vim\%((\a\+)\)\=:E480/
4738     call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
4739"     call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pattern.">")
4740     return
4741   endtry
4742
4743   2match none
4744   call netrw#NetrwRestorePosn(svpos)
4745  endif
4746
4747"  call Dret("s:NetrwMarkFileGrep")
4748endfun
4749
4750" ---------------------------------------------------------------------
4751" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
4752"                      uses the global marked file list
4753"                      s:netrwmfloc= 0: target directory is remote
4754"                                  = 1: target directory is local
4755fun! s:NetrwMarkFileMove(islocal)
4756"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
4757  let curdir   = b:netrw_curdir
4758  let curbufnr = bufnr("%")
4759
4760  " sanity check
4761  if !exists("s:netrwmarkfilelist_{bufnr('%')}") || empty(s:netrwmarkfilelist_{bufnr('%')})
4762   call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
4763"   call Dret("s:NetrwMarkFileMove")
4764   return
4765  endif
4766"  call Decho("sanity chk passed: s:netrwmarkfilelist_".bufnr('%')."<".string(s:netrwmarkfilelist_{bufnr('%')}))
4767  if !exists("s:netrwmftgt")
4768   call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
4769"   call Dret("s:NetrwMarkFileCopy 0")
4770   return 0
4771  endif
4772"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">")
4773
4774  if      a:islocal &&  s:netrwmftgt_islocal
4775   " move: local -> local
4776"   call Decho("move from local to local")
4777"   call Decho("(s:NetrwMarkFileMove) local to local move")
4778   if executable(g:netrw_localmovecmd)
4779    for fname in s:netrwmarkfilelist_{bufnr("%")}
4780"     call Decho("system(".g:netrw_localmovecmd." ".shellescape(fname)." ".shellescape(s:netrwmftgt).")")
4781     let ret= system(g:netrw_localmovecmd." ".shellescape(fname)." ".shellescape(s:netrwmftgt))
4782     if v:shell_error < 0
4783      call netrw#ErrorMsg(s:ERROR,"command<".g:netrw_localmovecmd."> failed, aborting",54)
4784      break
4785     endif
4786    endfor
4787   else
4788    call netrw#ErrorMsg(s:ERROR,"command<".g:netrw_localmovecmd."> is not executable!",57)
4789   endif
4790
4791  elseif  a:islocal && !s:netrwmftgt_islocal
4792   " move: local -> remote
4793"   call Decho("move from local to remote")
4794"   call Decho("copy")
4795   let mflist= s:netrwmarkfilelist_{bufnr("%")}
4796   call s:NetrwMarkFileCopy(a:islocal)
4797"   call Decho("remove")
4798   for fname in mflist
4799    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
4800    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
4801   endfor
4802   unlet mflist
4803
4804  elseif !a:islocal &&  s:netrwmftgt_islocal
4805   " move: remote -> local
4806"   call Decho("move from remote to local")
4807"   call Decho("copy")
4808   let mflist= s:netrwmarkfilelist_{bufnr("%")}
4809   call s:NetrwMarkFileCopy(a:islocal)
4810"   call Decho("remove")
4811   for fname in mflist
4812    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
4813    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
4814   endfor
4815   unlet mflist
4816
4817  elseif !a:islocal && !s:netrwmftgt_islocal
4818   " move: remote -> remote
4819"   call Decho("move from remote to remote")
4820"   call Decho("copy")
4821   let mflist= s:netrwmarkfilelist_{bufnr("%")}
4822   call s:NetrwMarkFileCopy(a:islocal)
4823"   call Decho("remove")
4824   for fname in mflist
4825    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
4826    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
4827   endfor
4828   unlet mflist
4829  endif
4830
4831  " -------
4832  " cleanup
4833  " -------
4834"  call Decho("cleanup")
4835
4836  " remove markings from local buffer
4837  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
4838
4839  " refresh buffers
4840  if !s:netrwmftgt_islocal
4841   call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
4842  endif
4843  if a:islocal
4844   call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
4845  endif
4846  if g:netrw_fastbrowse <= 1
4847   call s:LocalBrowseShellCmdRefresh()
4848  endif
4849
4850"  call Dret("s:NetrwMarkFileMove")
4851endfun
4852
4853" ---------------------------------------------------------------------
4854" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
4855"                       using the hardcopy command.  Local marked-file list only.
4856fun! s:NetrwMarkFilePrint(islocal)
4857"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
4858  let curbufnr= bufnr("%")
4859  if exists("s:netrwmarkfilelist_{curbufnr}")
4860   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
4861   let curdir            = b:netrw_curdir
4862   call s:NetrwUnmarkList(curbufnr,curdir)
4863   for fname in netrwmarkfilelist
4864    if a:islocal
4865     if g:netrw_keepdir
4866      let fname= s:ComposePath(curdir,fname)
4867     endif
4868    else
4869     let fname= curdir.fname
4870    endif
4871    1split
4872    " the autocmds will handle both local and remote files
4873"    call Decho("exe silent e ".escape(fname,' '))
4874    exe "silent e ".fnameescape(fname)
4875"    call Decho("hardcopy")
4876    hardcopy
4877    q
4878   endfor
4879   2match none
4880  endif
4881"  call Dret("s:NetrwMarkFilePrint")
4882endfun
4883
4884" ---------------------------------------------------------------------
4885" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
4886"                        files when given a regexp (for which a prompt is
4887"                        issued).
4888fun! s:NetrwMarkFileRegexp(islocal)
4889"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
4890
4891  " get the regular expression
4892  call inputsave()
4893  let regexp= input("Enter regexp: ","","file")
4894  call inputrestore()
4895
4896  if a:islocal
4897   " get the matching list of files using local glob()
4898"   call Decho("handle local regexp")
4899   let dirname  = escape(b:netrw_curdir,g:netrw_glob_escape)
4900   let files = glob(s:ComposePath(dirname,regexp))
4901"   call Decho("files<".files.">")
4902   let filelist= split(files,"\n")
4903
4904  " mark the list of files
4905  for fname in filelist
4906"   call Decho("fname<".fname.">")
4907   call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
4908  endfor
4909
4910  else
4911"   call Decho("handle remote regexp")
4912
4913   " convert displayed listing into a filelist
4914   let eikeep = &ei
4915   let areg   = @a
4916   sil keepj %y a
4917   set ei=all ma
4918"   call Decho("set ei=all ma")
4919   1split
4920   call s:NetrwEnew()
4921   call s:NetrwSafeOptions()
4922   sil keepj norm! "ap
4923   keepj 2
4924   let bannercnt= search('^" =====','W')
4925   exe "sil keepj 1,".bannercnt."d"
4926   set bt=nofile
4927   if     g:netrw_liststyle == s:LONGLIST
4928    sil keepj %s/\s\{2,}\S.*$//e
4929    call histdel("/",-1)
4930   elseif g:netrw_liststyle == s:WIDELIST
4931    sil keepj %s/\s\{2,}/\r/ge
4932    call histdel("/",-1)
4933   elseif g:netrw_liststyle == s:TREELIST
4934    sil keepj %s/^| //e
4935    sil! keepj g/^ .*$/d
4936    call histdel("/",-1)
4937    call histdel("/",-1)
4938   endif
4939   " convert regexp into the more usual glob-style format
4940   let regexp= substitute(regexp,'\*','.*','g')
4941"   call Decho("regexp<".regexp.">")
4942   exe "sil! keepj v/".escape(regexp,'/')."/d"
4943   call histdel("/",-1)
4944   let filelist= getline(1,line("$"))
4945   q!
4946   for filename in filelist
4947    call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
4948   endfor
4949   unlet filelist
4950   let @a  = areg
4951   let &ei = eikeep
4952  endif
4953
4954"  call Dret("s:NetrwMarkFileRegexp")
4955endfun
4956
4957" ---------------------------------------------------------------------
4958" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
4959"                        Uses the local marked file list.
4960fun! s:NetrwMarkFileSource(islocal)
4961"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
4962  let curbufnr= bufnr("%")
4963  if exists("s:netrwmarkfilelist_{curbufnr}")
4964   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
4965   let curdir            = b:netrw_curdir
4966   call s:NetrwUnmarkList(curbufnr,curdir)
4967   for fname in netrwmarkfilelist
4968    if a:islocal
4969     if g:netrw_keepdir
4970      let fname= s:ComposePath(curdir,fname)
4971     endif
4972    else
4973     let fname= curdir.fname
4974    endif
4975    " the autocmds will handle sourcing both local and remote files
4976"    call Decho("exe so ".fnameescape(fname))
4977    exe "so ".fnameescape(fname)
4978   endfor
4979   2match none
4980  endif
4981"  call Dret("s:NetrwMarkFileSource")
4982endfun
4983
4984" ---------------------------------------------------------------------
4985" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
4986"                     Uses the global markfilelist
4987fun! s:NetrwMarkFileTag(islocal)
4988"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
4989  let svpos    = netrw#NetrwSavePosn()
4990  let curdir   = b:netrw_curdir
4991  let curbufnr = bufnr("%")
4992
4993  if exists("s:netrwmarkfilelist")
4994"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">")
4995   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "shellescape(v:val,".!a:islocal.")"))
4996   call s:NetrwUnmarkAll()
4997
4998   if a:islocal
4999    if executable(g:netrw_ctags)
5000"     call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")")
5001     call system(g:netrw_ctags." ".netrwmarkfilelist)
5002    else
5003     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
5004    endif
5005   else
5006    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
5007    call netrw#NetrwObtain(a:islocal,"tags")
5008    let curdir= b:netrw_curdir
5009    1split
5010    e tags
5011    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
5012"    call Decho("curdir<".curdir."> path<".path.">")
5013    exe 'keepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
5014    call histdel("/",-1)
5015    wq!
5016   endif
5017   2match none
5018   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5019   call netrw#NetrwRestorePosn(svpos)
5020  endif
5021
5022"  call Dret("s:NetrwMarkFileTag")
5023endfun
5024
5025" ---------------------------------------------------------------------
5026" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
5027"   Sets up two variables,
5028"     s:netrwmftgt : holds the target directory
5029"     s:netrwmftgt_islocal : 0=target directory is remote
5030"                    1=target directory is local
5031fun! s:NetrwMarkFileTgt(islocal)
5032"  call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
5033  let svpos  = netrw#NetrwSavePosn()
5034  let curdir = b:netrw_curdir
5035  let hadtgt = exists("s:netrwmftgt")
5036  if !exists("w:netrw_bannercnt")
5037   let w:netrw_bannercnt= b:netrw_bannercnt
5038  endif
5039
5040  " set up target
5041  if line(".") < w:netrw_bannercnt
5042   " if cursor in banner region, use b:netrw_curdir for the target
5043   let s:netrwmftgt= b:netrw_curdir
5044"   call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">")
5045
5046  else
5047   " get word under cursor.
5048   "  * If directory, use it for the target.
5049   "  * If file, use b:netrw_curdir for the target
5050   let curword= s:NetrwGetWord()
5051   let tgtdir = s:ComposePath(curdir,curword)
5052   if a:islocal && isdirectory(tgtdir)
5053    let s:netrwmftgt = tgtdir
5054"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">")
5055   elseif !a:islocal && tgtdir =~ '/$'
5056    let s:netrwmftgt = tgtdir
5057"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">")
5058   else
5059    let s:netrwmftgt = curdir
5060"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">")
5061   endif
5062  endif
5063  if a:islocal
5064   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
5065   let s:netrwmftgt= simplify(s:netrwmftgt)
5066"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">")
5067  endif
5068  if g:netrw_cygwin
5069   let s:netrwmftgt= substitute(system("cygpath ".shellescape(s:netrwmftgt)),'\n$','','')
5070   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
5071  endif
5072  let s:netrwmftgt_islocal= a:islocal
5073
5074  if g:netrw_fastbrowse <= 1
5075   call s:LocalBrowseShellCmdRefresh()
5076  endif
5077  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5078  call netrw#NetrwRestorePosn(svpos)
5079  if !hadtgt
5080   sil! keepj norm! j
5081  endif
5082
5083"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
5084endfun
5085
5086" ---------------------------------------------------------------------
5087" s:NetrwOpenFile: query user for a filename and open it {{{2
5088fun! s:NetrwOpenFile(islocal)
5089"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
5090  call inputsave()
5091  let fname= input("Enter filename: ")
5092  call inputrestore()
5093  if fname !~ '[/\\]'
5094   if exists("b:netrw_curdir")
5095    if exists("g:netrw_quiet")
5096     let netrw_quiet_keep = g:netrw_quiet
5097    endif
5098    let g:netrw_quiet    = 1
5099    if b:netrw_curdir =~ '/$'
5100     exe "e ".fnameescape(b:netrw_curdir.fname)
5101    else
5102     exe "e ".fnameescape(b:netrw_curdir."/".fname)
5103    endif
5104    if exists("netrw_quiet_keep")
5105     let g:netrw_quiet= netrw_quiet_keep
5106    else
5107     unlet g:netrw_quiet
5108    endif
5109   endif
5110  else
5111   exe "e ".fnameescape(fname)
5112  endif
5113"  call Dret("s:NetrwOpenFile")
5114endfun
5115
5116" ---------------------------------------------------------------------
5117" s:NetrwUnmarkList: delete local marked file lists and remove their contents from the global marked-file list {{{2
5118fun! s:NetrwUnmarkList(curbufnr,curdir)
5119"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
5120
5121  "  remove all files in local marked-file list from global list
5122  if exists("s:netrwmarkfilelist_{a:curbufnr}")
5123   for mfile in s:netrwmarkfilelist_{a:curbufnr}
5124    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
5125    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
5126    call remove(s:netrwmarkfilelist,idx)            " remove from global list
5127   endfor
5128   if s:netrwmarkfilelist == []
5129    unlet s:netrwmarkfilelist
5130   endif
5131
5132   " getting rid of the local marked-file lists is easy
5133   unlet s:netrwmarkfilelist_{a:curbufnr}
5134  endif
5135  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
5136   unlet s:netrwmarkfilemtch_{a:curbufnr}
5137  endif
5138  2match none
5139"  call Dret("s:NetrwUnmarkList")
5140endfun
5141
5142" ---------------------------------------------------------------------
5143" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
5144fun! s:NetrwUnmarkAll()
5145"  call Dfunc("s:NetrwUnmarkAll()")
5146  if exists("s:netrwmarkfilelist")
5147   unlet s:netrwmarkfilelist
5148  endif
5149  silent call s:NetrwUnmarkAll2()
5150  2match none
5151"  call Dret("s:NetrwUnmarkAll")
5152endfun
5153
5154" ---------------------------------------------------------------------
5155" s:NetrwUnmarkAll2: {{{2
5156fun! s:NetrwUnmarkAll2()
5157"  call Dfunc("s:NetrwUnmarkAll2()")
5158  redir => netrwmarkfilelist_let
5159  let
5160  redir END
5161  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
5162  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
5163  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
5164  for flist in netrwmarkfilelist_list
5165   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
5166   unlet s:netrwmarkfilelist_{curbufnr}
5167   unlet s:netrwmarkfilemtch_{curbufnr}
5168  endfor
5169"  call Dret("s:NetrwUnmarkAll2")
5170endfun
5171
5172" ---------------------------------------------------------------------
5173" s:NetrwUnMarkFile: {{{2
5174fun! s:NetrwUnMarkFile(islocal)
5175"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
5176  let svpos    = netrw#NetrwSavePosn()
5177  let curbufnr = bufnr("%")
5178
5179  " unmark marked file list (although I expect s:NetrwUpload()
5180  " to do it, I'm just making sure)
5181  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5182"   call Decho("unlet'ing: s:netrwmarkfile[list|mtch]_".bufnr("%"))
5183   unlet s:netrwmarkfilelist
5184   unlet s:netrwmarkfilelist_{curbufnr}
5185   unlet s:netrwmarkfilemtch_{curbufnr}
5186   2match none
5187  endif
5188
5189"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5190  call netrw#NetrwRestorePosn(svpos)
5191"  call Dret("s:NetrwUnMarkFile")
5192endfun
5193
5194" ---------------------------------------------------------------------
5195" s:NetrwMenu: generates the menu for gvim and netrw {{{2
5196fun! s:NetrwMenu(domenu)
5197
5198  if !exists("g:NetrwMenuPriority")
5199   let g:NetrwMenuPriority= 80
5200  endif
5201
5202  if has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
5203"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
5204
5205   if !exists("s:netrw_menu_enabled") && a:domenu
5206"    call Decho("initialize menu")
5207    let s:netrw_menu_enabled= 1
5208    exe 'sil! menu '.g:NetrwMenuPriority.'.1     '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
5209    exe 'sil! menu '.g:NetrwMenuPriority.'.5     '.g:NetrwTopLvlMenu.'-Sep1-	:'
5210    exe 'sil! menu '.g:NetrwMenuPriority.'.6     '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
5211    exe 'sil! menu '.g:NetrwMenuPriority.'.7     '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
5212    exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
5213    exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
5214    exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
5215    exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
5216    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1   '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
5217    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2   '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
5218    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3   '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
5219    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4   '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
5220    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5   '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
5221    exe 'sil! menu '.g:NetrwMenuPriority.'.10    '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
5222    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
5223    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
5224    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
5225    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
5226    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
5227    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1  '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
5228    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2  '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
5229    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2  '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
5230    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3  '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
5231    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4  '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
5232    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4  '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
5233    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4  '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
5234    exe 'sil! menu '.g:NetrwMenuPriority.'.13    '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
5235    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1  '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
5236    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2  '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
5237    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3  '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
5238    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4  '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
5239    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5  '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
5240    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6  '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
5241    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7  '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
5242    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8  '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
5243    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9  '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
5244    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10 '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
5245    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11 '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
5246    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12 '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
5247    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13 '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
5248    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14 '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
5249    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15 '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
5250    exe 'sil! menu '.g:NetrwMenuPriority.'.15    '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
5251    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1  '.g:NetrwTopLvlMenu.'Style.Listing\ Style\ (thin-long-wide-tree)<tab>i	i'
5252    exe 'sil! menu '.g:NetrwMenuPriority.'.16.2  '.g:NetrwTopLvlMenu.'Style.Normal-Hide-Show<tab>a	a'
5253    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3  '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
5254    exe 'sil! menu '.g:NetrwMenuPriority.'.16.4  '.g:NetrwTopLvlMenu.'Style.Sorting\ Method\ (name-time-size)<tab>s	s'
5255    exe 'sil! menu '.g:NetrwMenuPriority.'.17    '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
5256    exe 'sil! menu '.g:NetrwMenuPriority.'.18    '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
5257    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
5258    let s:netrw_menucnt= 28
5259
5260   elseif !a:domenu
5261    let s:netrwcnt = 0
5262    let curwin     = winnr()
5263    windo if getline(2) =~ "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
5264    exe curwin."wincmd w"
5265
5266    if s:netrwcnt <= 1
5267"     call Decho("clear menus")
5268     exe 'sil! unmenu '.g:NetrwTopLvlMenu
5269"     call Decho('exe silent! unmenu '.g:NetrwTopLvlMenu.'*')
5270     sil! unlet s:netrw_menu_enabled
5271    endif
5272   endif
5273"   call Dret("NetrwMenu")
5274  endif
5275
5276endfun
5277
5278" ---------------------------------------------------------------------
5279" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
5280"                Used by the O maps (as <SID>NetrwObtain())
5281fun! s:NetrwObtain(islocal)
5282"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
5283
5284  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5285   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\+://'
5286   call netrw#NetrwObtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
5287   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
5288  else
5289   call netrw#NetrwObtain(a:islocal,expand("<cWORD>"))
5290  endif
5291
5292"  call Dret("NetrwObtain")
5293endfun
5294
5295" ---------------------------------------------------------------------
5296" netrw#NetrwObtain: {{{2
5297"   netrw#NetrwObtain(islocal,fname[,tgtdirectory])
5298"     islocal=0  obtain from remote source
5299"            =1  obtain from local source
5300"     fname  :   a filename or a list of filenames
5301"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
5302fun! netrw#NetrwObtain(islocal,fname,...)
5303"  call Dfunc("netrw#NetrwObtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
5304  " NetrwStatusLine support - for obtaining support
5305
5306  if type(a:fname) == 1
5307   let fnamelist= [ a:fname ]
5308  elseif type(a:fname) == 3
5309   let fnamelist= a:fname
5310  else
5311   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
5312"   call Dret("netrw#NetrwObtain")
5313   return
5314  endif
5315"  call Decho("fnamelist<".string(fnamelist).">")
5316  if a:0 > 0
5317   let tgtdir= a:1
5318  else
5319   let tgtdir= getcwd()
5320  endif
5321"  call Decho("tgtdir<".tgtdir.">")
5322
5323  if exists("b:netrw_islocal") && b:netrw_islocal
5324   " obtain a file from local b:netrw_curdir to (local) tgtdir
5325"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir)
5326   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
5327    let topath= s:ComposePath(tgtdir,"")
5328    if (has("win32") || has("win95") || has("win64") || has("win16"))
5329     " transfer files one at time
5330"     call Decho("transfer files one at a time")
5331     for fname in fnamelist
5332"      call Decho("system(".g:netrw_localcopycmd." ".shellescape(fname)." ".shellescape(topath).")")
5333      call system(g:netrw_localcopycmd." ".shellescape(fname)." ".shellescape(topath))
5334     endfor
5335    else
5336     " transfer files with one command
5337"     call Decho("transfer files with one command")
5338     let filelist= join(map(deepcopy(fnamelist),"shellescape(v:val)"))
5339"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".shellescape(topath).")")
5340     call system(g:netrw_localcopycmd." ".filelist." ".shellescape(topath))
5341    endif
5342   elseif !exists("b:netrw_curdir")
5343    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
5344   else
5345    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
5346   endif
5347
5348  else
5349   " obtain files from remote b:netrw_curdir to local tgtdir
5350"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir)
5351   if type(a:fname) == 1
5352    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
5353   endif
5354   call s:NetrwMethod(b:netrw_curdir)
5355
5356   if b:netrw_method == 4
5357    " obtain file using scp
5358"    call Decho("obtain via scp (method#4)")
5359    if exists("g:netrw_port") && g:netrw_port != ""
5360     let useport= " ".g:netrw_scpport." ".g:netrw_port
5361    else
5362     let useport= ""
5363    endif
5364    if b:netrw_fname =~ '/'
5365     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
5366    else
5367     let path= ""
5368    endif
5369    let filelist= join(map(deepcopy(fnamelist),'shellescape(g:netrw_machine.":".path.v:val,1)'))
5370"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_scp_cmd.shellescape(useport,1)." ".filelist." ".shellescape(tgtdir,1))
5371    exe s:netrw_silentxfer."!".g:netrw_scp_cmd.shellescape(useport,1)." ".filelist." ".shellescape(tgtdir,1)
5372
5373   elseif b:netrw_method == 2
5374    " obtain file using ftp + .netrc
5375"     call Decho("obtain via ftp+.netrc (method #2)")
5376     call s:SaveBufVars()|silent keepjumps new|call s:RestoreBufVars()
5377     let tmpbufnr= bufnr("%")
5378     setlocal ff=unix
5379     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
5380      keepj put =g:netrw_ftpmode
5381"      call Decho("filter input: ".getline('$'))
5382     endif
5383
5384     if exists("b:netrw_fname") && b:netrw_fname != ""
5385      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
5386"      call Decho("filter input: ".getline('$'))
5387     endif
5388
5389     if exists("g:netrw_ftpextracmd")
5390      keepj put =g:netrw_ftpextracmd
5391"      call Decho("filter input: ".getline('$'))
5392     endif
5393     for fname in fnamelist
5394      call setline(line("$")+1,'get "'.fname.'"')
5395"      call Decho("filter input: ".getline('$'))
5396     endfor
5397     if exists("g:netrw_port") && g:netrw_port != ""
5398"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1))
5399      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1)
5400     else
5401"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
5402      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
5403     endif
5404     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
5405     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
5406      let debugkeep= &debug
5407      setlocal debug=msg
5408      call netrw#ErrorMsg(s:ERROR,getline(1),4)
5409      let &debug= debugkeep
5410     endif
5411
5412   elseif b:netrw_method == 3
5413    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
5414"    call Decho("obtain via ftp+mipf (method #3)")
5415    call s:SaveBufVars()|silent keepjumps new|call s:RestoreBufVars()
5416    let tmpbufnr= bufnr("%")
5417    setlocal ff=unix
5418
5419    if exists("g:netrw_port") && g:netrw_port != ""
5420     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
5421"     call Decho("filter input: ".getline('$'))
5422    else
5423     keepj put ='open '.g:netrw_machine
5424"     call Decho("filter input: ".getline('$'))
5425    endif
5426
5427    if exists("g:netrw_ftp") && g:netrw_ftp == 1
5428     keepj put =g:netrw_uid
5429"     call Decho("filter input: ".getline('$'))
5430     keepj put ='\"'.s:netrw_passwd.'\"'
5431"     call Decho("filter input: ".getline('$'))
5432    else
5433     keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
5434"     call Decho("filter input: ".getline('$'))
5435    endif
5436
5437    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
5438     keepj put =g:netrw_ftpmode
5439"     call Decho("filter input: ".getline('$'))
5440    endif
5441
5442    if exists("b:netrw_fname") && b:netrw_fname != ""
5443     keepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
5444"     call Decho("filter input: ".getline('$'))
5445    endif
5446
5447    if exists("g:netrw_ftpextracmd")
5448     keepj put =g:netrw_ftpextracmd
5449"     call Decho("filter input: ".getline('$'))
5450    endif
5451
5452    if exists("g:netrw_ftpextracmd")
5453     keepj put =g:netrw_ftpextracmd
5454"     call Decho("filter input: ".getline('$'))
5455    endif
5456    for fname in fnamelist
5457     keepj call setline(line("$")+1,'get "'.fname.'"')
5458    endfor
5459"    call Decho("filter input: ".getline('$'))
5460
5461    " perform ftp:
5462    " -i       : turns off interactive prompting from ftp
5463    " -n  unix : DON'T use <.netrc>, even though it exists
5464    " -n  win32: quit being obnoxious about password
5465    keepj norm! 1Gdd
5466"    call Decho("executing: %!".g:netrw_ftp_cmd." -i -n")
5467    exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
5468    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
5469    if getline(1) !~ "^$"
5470"     call Decho("error<".getline(1).">")
5471     if !exists("g:netrw_quiet")
5472      call netrw#ErrorMsg(s:ERROR,getline(1),5)
5473     endif
5474    endif
5475   elseif !exists("b:netrw_method") || b:netrw_method < 0
5476"    call Dfunc("netrw#NetrwObtain : unsupported method")
5477    return
5478   endif
5479
5480   " restore status line
5481   if type(a:fname) == 1 && exists("s:netrw_users_stl")
5482    call s:SetupNetrwStatusLine(s:netrw_users_stl)
5483   endif
5484
5485  endif
5486
5487  " cleanup
5488  if exists("tmpbufnr")
5489   if bufnr("%") != tmpbufnr
5490    exe tmpbufnr."bw!"
5491   else
5492    q!
5493   endif
5494  endif
5495
5496"  call Dret("netrw#NetrwObtain")
5497endfun
5498
5499" ---------------------------------------------------------------------
5500" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
5501"   If there's only one window, then the window will first be split.
5502"   Returns:
5503"     choice = 0 : didn't have to choose
5504"     choice = 1 : saved modified file in window first
5505"     choice = 2 : didn't save modified file, opened window
5506"     choice = 3 : cancel open
5507fun! s:NetrwPrevWinOpen(islocal)
5508"  call Dfunc("NetrwPrevWinOpen(islocal=".a:islocal.")")
5509
5510  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
5511  let curdir    = b:netrw_curdir
5512
5513  " get last window number and the word currently under the cursor
5514  let lastwinnr = winnr("$")
5515  let curword   = s:NetrwGetWord()
5516  let choice    = 0
5517"  call Decho("lastwinnr=".lastwinnr." curword<".curword.">")
5518
5519  let didsplit  = 0
5520  if lastwinnr == 1
5521   " if only one window, open a new one first
5522"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")")
5523   if g:netrw_preview
5524"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".g:netrw_winsize."wincmd s")
5525    exe (g:netrw_alto? "top " : "bot ")."vert ".g:netrw_winsize."wincmd s"
5526   else
5527"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s")
5528    exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
5529   endif
5530   let didsplit  = 1
5531
5532  else
5533   call s:SaveBufVars()
5534"   call Decho("wincmd p")
5535   wincmd p
5536   call s:RestoreBufVars()
5537   " if the previous window's buffer has been changed (is modified),
5538   " and it doesn't appear in any other extant window, then ask the
5539   " user if s/he wants to abandon modifications therein.
5540   let bnr    = winbufnr(0)
5541   let bnrcnt = 0
5542   if &mod
5543"    call Decho("detected: prev window's buffer has been modified: bnr=".bnr." winnr#".winnr())
5544    let eikeep= &ei
5545    set ei=all
5546    windo if winbufnr(0) == bnr | let bnrcnt=bnrcnt+1 | endif
5547    exe bnr."wincmd p"
5548    let &ei= eikeep
5549"    call Decho("bnr=".bnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr#".winnr())
5550    if bnrcnt == 1
5551     let bufname = bufname(winbufnr(winnr()))
5552     let choice  = confirm("Save modified file<".bufname.">?","&Yes\n&No\n&Cancel")
5553"     call Decho("bufname<".bufname."> choice=".choice." winnr#".winnr())
5554
5555     if choice == 1
5556      " Yes -- write file & then browse
5557      let v:errmsg= ""
5558      silent w
5559      if v:errmsg != ""
5560       call netrw#ErrorMsg(s:ERROR,"unable to write <".bufname.">!",30)
5561       if didsplit
5562       	q
5563       else
5564       	wincmd p
5565       endif
5566"       call Dret("NetrwPrevWinOpen ".choice." : unable to write <".bufname.">")
5567       return choice
5568      endif
5569
5570     elseif choice == 2
5571      " No -- don't worry about changed file, just browse anyway
5572      setlocal nomod
5573      call netrw#ErrorMsg(s:WARNING,bufname." changes to ".bufname." abandoned",31)
5574      wincmd p
5575
5576     else
5577      " Cancel -- don't do this
5578      if didsplit
5579       q
5580      else
5581       wincmd p
5582      endif
5583"      call Dret("NetrwPrevWinOpen ".choice." : cancelled")
5584      return choice
5585     endif
5586    endif
5587   endif
5588  endif
5589
5590  " restore b:netrw_curdir (window split/enew may have lost it)
5591  let b:netrw_curdir= curdir
5592  if a:islocal < 2
5593   if a:islocal
5594    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
5595   else
5596    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
5597   endif
5598  endif
5599"  call Dret("NetrwPrevWinOpen ".choice)
5600  return choice
5601endfun
5602
5603" ---------------------------------------------------------------------
5604" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
5605"                Always assumed to be local -> remote
5606"                call s:NetrwUpload(filename, target)
5607"                call s:NetrwUpload(filename, target, fromdirectory)
5608fun! s:NetrwUpload(fname,tgt,...)
5609"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
5610
5611  if a:tgt =~ '^\a\+://'
5612   let tgtdir= substitute(a:tgt,'^\a\+://[^/]\+/\(.\{-}\)$','\1','')
5613  else
5614   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
5615  endif
5616"  call Decho("tgtdir<".tgtdir.">")
5617
5618  if a:0 > 0
5619   let fromdir= a:1
5620  else
5621   let fromdir= getcwd()
5622  endif
5623"  call Decho("fromdir<".fromdir.">")
5624
5625  if type(a:fname) == 1
5626   " handle uploading a single file using NetWrite
5627"   call Decho("handle uploading a single file via NetWrite")
5628   1split
5629"   call Decho("exe e ".fnameescape(a:fname))
5630   exe "e ".fnameescape(a:fname)
5631"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines")
5632   if a:tgt =~ '/$'
5633    let wfname= substitute(a:fname,'^.*/','','')
5634"    call Decho("exe w! ".fnameescape(wfname))
5635    exe "w! ".fnameescape(a:tgt.wfname)
5636   else
5637"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt))
5638    exe "w ".fnameescape(a:tgt)
5639"    call Decho("done writing local->remote")
5640   endif
5641   q!
5642
5643  elseif type(a:fname) == 3
5644   " handle uploading a list of files via scp
5645"   call Decho("handle uploading a list of files via scp")
5646   let curdir= getcwd()
5647   if a:tgt =~ '^scp:'
5648    exe "keepjumps silent lcd ".fnameescape(fromdir)
5649    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
5650    let args    = join(map(filelist,"shellescape(v:val, 1)"))
5651    if exists("g:netrw_port") && g:netrw_port != ""
5652     let useport= " ".g:netrw_scpport." ".g:netrw_port
5653    else
5654     let useport= ""
5655    endif
5656    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
5657    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
5658"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_scp_cmd.shellescape(useport,1)." ".args." ".shellescape(machine.":".tgt,1))
5659    exe s:netrw_silentxfer."!".g:netrw_scp_cmd.shellescape(useport,1)." ".args." ".shellescape(machine.":".tgt,1)
5660    exe "keepjumps silent lcd ".fnameescape(curdir)
5661
5662   elseif a:tgt =~ '^ftp:'
5663    call s:NetrwMethod(a:tgt)
5664
5665    if b:netrw_method == 2
5666     " handle uploading a list of files via ftp+.netrc
5667     let netrw_fname = b:netrw_fname
5668     sil keepj new
5669"     call Decho("filter input window#".winnr())
5670
5671     keepj put =g:netrw_ftpmode
5672"     call Decho("filter input: ".getline('$'))
5673
5674     if exists("g:netrw_ftpextracmd")
5675      keepj put =g:netrw_ftpextracmd
5676"      call Decho("filter input: ".getline('$'))
5677     endif
5678
5679     keepj call setline(line("$")+1,'lcd "'.fromdir.'"')
5680"     call Decho("filter input: ".getline('$'))
5681
5682     keepj call setline(line("$")+1,'cd "'.tgtdir.'"')
5683"     call Decho("filter input: ".getline('$'))
5684
5685     for fname in a:fname
5686      keepj call setline(line("$")+1,'put "'.fname.'"')
5687"      call Decho("filter input: ".getline('$'))
5688     endfor
5689
5690     if exists("g:netrw_port") && g:netrw_port != ""
5691"      call Decho("executing: ".s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1))
5692      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1)
5693     else
5694"      call Decho("filter input window#".winnr())
5695"      call Decho("executing: ".s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
5696      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
5697     endif
5698     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
5699     sil keepj g/Local directory now/d
5700     call histdel("/",-1)
5701     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
5702      call netrw#ErrorMsg(s:ERROR,getline(1),14)
5703     else
5704      bw!|q
5705     endif
5706
5707    elseif b:netrw_method == 3
5708     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
5709     let netrw_fname= b:netrw_fname
5710     call s:SaveBufVars()|silent keepjumps new|call s:RestoreBufVars()
5711     let tmpbufnr= bufnr("%")
5712     setlocal ff=unix
5713
5714     if exists("g:netrw_port") && g:netrw_port != ""
5715      keepj put ='open '.g:netrw_machine.' '.g:netrw_port
5716"      call Decho("filter input: ".getline('$'))
5717     else
5718      keepj put ='open '.g:netrw_machine
5719"      call Decho("filter input: ".getline('$'))
5720     endif
5721
5722     if exists("g:netrw_ftp") && g:netrw_ftp == 1
5723      keepj put =g:netrw_uid
5724"      call Decho("filter input: ".getline('$'))
5725      keepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
5726"      call Decho("filter input: ".getline('$'))
5727     else
5728      keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
5729"      call Decho("filter input: ".getline('$'))
5730     endif
5731
5732     keepj call setline(line("$")+1,'lcd "'.fromdir.'"')
5733"     call Decho("filter input: ".getline('$'))
5734
5735     if exists("b:netrw_fname") && b:netrw_fname != ""
5736      keepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
5737"      call Decho("filter input: ".getline('$'))
5738     endif
5739
5740     if exists("g:netrw_ftpextracmd")
5741      keepj put =g:netrw_ftpextracmd
5742"      call Decho("filter input: ".getline('$'))
5743     endif
5744
5745     for fname in a:fname
5746      keepj call setline(line("$")+1,'put "'.fname.'"')
5747"      call Decho("filter input: ".getline('$'))
5748     endfor
5749
5750     " perform ftp:
5751     " -i       : turns off interactive prompting from ftp
5752     " -n  unix : DON'T use <.netrc>, even though it exists
5753     " -n  win32: quit being obnoxious about password
5754     keepj norm! 1Gdd
5755"     call Decho("executing: ".s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n")
5756     exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
5757     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
5758     sil keepj g/Local directory now/d
5759     call histdel("/",-1)
5760     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
5761      let debugkeep= &debug
5762      setlocal debug=msg
5763      call netrw#ErrorMsg(s:ERROR,getline(1),15)
5764      let &debug = debugkeep
5765      let mod    = 1
5766     else
5767      bw!|q
5768     endif
5769    elseif !exists("b:netrw_method") || b:netrw_method < 0
5770"     call Dfunc("netrw#NetrwUpload : unsupported method")
5771     return
5772    endif
5773   else
5774    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
5775   endif
5776  endif
5777
5778"  call Dret("s:NetrwUpload")
5779endfun
5780
5781" ---------------------------------------------------------------------
5782" s:NetrwPreview: {{{2
5783fun! s:NetrwPreview(path) range
5784"  call Dfunc("NetrwPreview(path<".a:path.">)")
5785  call s:NetrwOptionSave("s:")
5786  call s:NetrwSafeOptions()
5787  if has("quickfix")
5788   if !isdirectory(a:path)
5789    if g:netrw_preview && !g:netrw_alto
5790     let pvhkeep= &pvh
5791     let &pvh   = winwidth(0) - g:netrw_winsize
5792    endif
5793    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
5794    if exists("pvhkeep")
5795     let &pvh= pvhkeep
5796    endif
5797   elseif !exists("g:netrw_quiet")
5798    call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
5799   endif
5800  elseif !exists("g:netrw_quiet")
5801   call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
5802  endif
5803  call s:NetrwOptionRestore("s:")
5804"  call Dret("NetrwPreview")
5805endfun
5806
5807" ---------------------------------------------------------------------
5808" s:NetrwRefresh: {{{2
5809fun! s:NetrwRefresh(islocal,dirname)
5810"  call Dfunc("NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction)
5811  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
5812  " NetrwBrowseChgDir() may clear the display; hence a NetrwSavePosn() may not work if its placed here.
5813  " Also, NetrwBrowseChgDir() now does a NetrwSavePosn() itself.
5814  setlocal ma noro
5815"  call Decho("setlocal ma noro")
5816"  call Decho("clear buffer<".expand("%")."> with :%d")
5817  keepj %d
5818  if a:islocal
5819   call netrw#LocalBrowseCheck(a:dirname)
5820  else
5821   call s:NetrwBrowse(a:islocal,a:dirname)
5822  endif
5823  call netrw#NetrwRestorePosn()
5824
5825  " restore file marks
5826  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
5827"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/")
5828   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
5829  else
5830"   call Decho("2match none")
5831   2match none
5832  endif
5833
5834"  redraw!
5835"  call Dret("NetrwRefresh")
5836endfun
5837
5838" ---------------------------------------------------------------------
5839" s:NetrwRefreshDir: refreshes a directory by name {{{2
5840"                    Called by NetrwMarkFileCopy()
5841"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseShellCmdRefresh()
5842fun! s:NetrwRefreshDir(islocal,dirname)
5843"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) fastbrowse=".g:netrw_fastbrowse)
5844  if g:netrw_fastbrowse == 0
5845   " slowest mode (keep buffers refreshed, local or remote)
5846"   call Decho("slowest mode: keep buffers refreshed, local or remote")
5847   let tgtwin= bufwinnr(a:dirname)
5848"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin)
5849
5850   if tgtwin > 0
5851    " tgtwin is being displayed, so refresh it
5852    let curwin= winnr()
5853"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")")
5854    exe tgtwin."wincmd w"
5855    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5856    exe curwin."wincmd w"
5857
5858   elseif bufnr(a:dirname) > 0
5859    let bn= bufnr(a:dirname)
5860"    call Decho("bd bufnr(".a:dirname.")=".bn)
5861    exe "silent bd ".bn
5862   endif
5863
5864  elseif g:netrw_fastbrowse <= 1
5865"   call Decho("medium-speed mode: refresh local buffers only")
5866   call s:LocalBrowseShellCmdRefresh()
5867  endif
5868"  call Dret("s:NetrwRefreshDir")
5869endfun
5870
5871" ---------------------------------------------------------------------
5872" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
5873"          What this function does is to compute a priority for the patterns
5874"          in the g:netrw_sort_sequence.  It applies a substitute to any
5875"          "files" that satisfy each pattern, putting the priority / in
5876"          front.  An "*" pattern handles the default priority.
5877fun! s:NetrwSetSort()
5878"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
5879  if w:netrw_liststyle == s:LONGLIST
5880   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
5881  else
5882   let seqlist  = g:netrw_sort_sequence
5883  endif
5884  " sanity check -- insure that * appears somewhere
5885  if seqlist == ""
5886   let seqlist= '*'
5887  elseif seqlist !~ '\*'
5888   let seqlist= seqlist.',*'
5889  endif
5890  let priority = 1
5891  while seqlist != ""
5892   if seqlist =~ ','
5893    let seq     = substitute(seqlist,',.*$','','e')
5894    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
5895   else
5896    let seq     = seqlist
5897    let seqlist = ""
5898   endif
5899   if priority < 10
5900    let spriority= "00".priority.g:netrw_sepchr
5901   elseif priority < 100
5902    let spriority= "0".priority.g:netrw_sepchr
5903   else
5904    let spriority= priority.g:netrw_sepchr
5905   endif
5906"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">")
5907
5908   " sanity check
5909   if w:netrw_bannercnt > line("$")
5910    " apparently no files were left after a Hiding pattern was used
5911"    call Dret("SetSort : no files left after hiding")
5912    return
5913   endif
5914   if seq == '*'
5915    let starpriority= spriority
5916   else
5917    exe 'sil keepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
5918    call histdel("/",-1)
5919    " sometimes multiple sorting patterns will match the same file or directory.
5920    " The following substitute is intended to remove the excess matches.
5921    exe 'sil keepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
5922    call histdel("/",-1)
5923   endif
5924   let priority = priority + 1
5925  endwhile
5926  if exists("starpriority")
5927   exe 'sil keepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/'
5928   call histdel("/",-1)
5929  endif
5930
5931  " Following line associated with priority -- items that satisfy a priority
5932  " pattern get prefixed by ###/ which permits easy sorting by priority.
5933  " Sometimes files can satisfy multiple priority patterns -- only the latest
5934  " priority pattern needs to be retained.  So, at this point, these excess
5935  " priority prefixes need to be removed, but not directories that happen to
5936  " be just digits themselves.
5937  exe 'sil keepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
5938  call histdel("/",-1)
5939
5940"  call Dret("SetSort")
5941endfun
5942
5943" =====================================================================
5944" s:NetrwSortStyle: change sorting style (name - time - size) and refresh display {{{2
5945fun! s:NetrwSortStyle(islocal)
5946"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
5947  call s:NetrwSaveWordPosn()
5948  let svpos= netrw#NetrwSavePosn()
5949
5950  let g:netrw_sort_by= (g:netrw_sort_by =~ 'n')? 'time' : (g:netrw_sort_by =~ 't')? 'size' : 'name'
5951  keepj norm! 0
5952  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5953  call netrw#NetrwRestorePosn(svpos)
5954
5955"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
5956endfun
5957
5958" ---------------------------------------------------------------------
5959" s:NetrwSplit: mode {{{2
5960"           =0 : net   and o
5961"           =1 : net   and t
5962"           =2 : net   and v
5963"           =3 : local and o
5964"           =4 : local and t
5965"           =5 : local and v
5966fun! s:NetrwSplit(mode)
5967"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
5968
5969  call s:SaveWinVars()
5970
5971  if a:mode == 0
5972   " remote and o
5973"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s")
5974   exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
5975   let s:didsplit= 1
5976   call s:RestoreWinVars()
5977   call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5978   unlet s:didsplit
5979
5980  elseif a:mode == 1
5981   " remote and t
5982   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
5983"   call Decho("tabnew")
5984   tabnew
5985   let s:didsplit= 1
5986   call s:RestoreWinVars()
5987   call s:NetrwBrowse(0,newdir)
5988   unlet s:didsplit
5989
5990  elseif a:mode == 2
5991   " remote and v
5992"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v")
5993   exe (g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v"
5994   let s:didsplit= 1
5995   call s:RestoreWinVars()
5996   call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5997   unlet s:didsplit
5998
5999  elseif a:mode == 3
6000   " local and o
6001"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s")
6002   exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
6003   let s:didsplit= 1
6004   call s:RestoreWinVars()
6005   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
6006   unlet s:didsplit
6007
6008  elseif a:mode == 4
6009   " local and t
6010   let cursorword  = s:NetrwGetWord()
6011   let netrw_curdir= s:NetrwTreeDir()
6012"   call Decho("tabnew")
6013   tabnew
6014   let b:netrw_curdir= netrw_curdir
6015   let s:didsplit= 1
6016   call s:RestoreWinVars()
6017   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
6018   unlet s:didsplit
6019
6020  elseif a:mode == 5
6021   " local and v
6022"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v")
6023   exe (g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v"
6024   let s:didsplit= 1
6025   call s:RestoreWinVars()
6026   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
6027   unlet s:didsplit
6028
6029  else
6030   call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
6031  endif
6032
6033"  call Dret("s:NetrwSplit")
6034endfun
6035
6036" ---------------------------------------------------------------------
6037" NetrwStatusLine: {{{2
6038fun! NetrwStatusLine()
6039
6040" vvv NetrwStatusLine() debugging vvv
6041"  let g:stlmsg=""
6042"  if !exists("w:netrw_explore_bufnr")
6043"   let g:stlmsg="!X<explore_bufnr>"
6044"  elseif w:netrw_explore_bufnr != bufnr("%")
6045"   let g:stlmsg="explore_bufnr!=".bufnr("%")
6046"  endif
6047"  if !exists("w:netrw_explore_line")
6048"   let g:stlmsg=" !X<explore_line>"
6049"  elseif w:netrw_explore_line != line(".")
6050"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
6051"  endif
6052"  if !exists("w:netrw_explore_list")
6053"   let g:stlmsg=" !X<explore_list>"
6054"  endif
6055" ^^^ NetrwStatusLine() debugging ^^^
6056
6057  if !exists("w:netrw_explore_bufnr") || w:netrw_explore_bufnr != bufnr("%") || !exists("w:netrw_explore_line") || w:netrw_explore_line != line(".") || !exists("w:netrw_explore_list")
6058   " restore user's status line
6059   let &stl        = s:netrw_users_stl
6060   let &laststatus = s:netrw_users_ls
6061   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
6062   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
6063   return ""
6064  else
6065   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
6066  endif
6067endfun
6068
6069" ---------------------------------------------------------------------
6070" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
6071" (full path directory with trailing slash returned)
6072fun! s:NetrwTreeDir()
6073"  call Dfunc("NetrwTreeDir() curline#".line(".")."<".getline('.')."> b:netrw_curdir<".b:netrw_curdir."> tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">")
6074
6075  let treedir= b:netrw_curdir
6076"  call Decho("set initial treedir<".treedir.">")
6077  let s:treecurpos= netrw#NetrwSavePosn()
6078
6079  if w:netrw_liststyle == s:TREELIST
6080"   call Decho("w:netrrw_liststyle is TREELIST:")
6081"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">")
6082
6083   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
6084   if getline('.') =~ '/$'
6085    let treedir= substitute(getline('.'),'^\%(| \)*\([^|].\{-}\)$','\1','e')
6086   else
6087    let treedir= ""
6088   endif
6089"   call Decho("treedir<".treedir.">")
6090
6091   " detect user attempting to close treeroot
6092   if getline('.') !~ '|' && getline('.') != '..'
6093"    call Decho("user attempted to close treeroot")
6094    " now force a refresh
6095"    call Decho("clear buffer<".expand("%")."> with :%d")
6096    keepj %d
6097"    call Dret("NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">")
6098    return b:netrw_curdir
6099   endif
6100
6101   " elide all non-depth information
6102   let depth = substitute(getline('.'),'^\(\%(| \)*\)[^|].\{-}$','\1','e')
6103"   call Decho("depth<".depth."> 1st subst (non-depth info removed)")
6104
6105   " elide first depth
6106   let depth = substitute(depth,'^| ','','')
6107"   call Decho("depth<".depth."> 2nd subst (first depth removed)")
6108
6109   " construct treedir by searching backwards at correct depth
6110"   call Decho("constructing treedir<".treedir."> depth<".depth.">")
6111   while depth != "" && search('^'.depth.'[^|].\{-}/$','bW')
6112    let dirname= substitute(getline('.'),'^\(| \)*','','e')
6113    let treedir= dirname.treedir
6114    let depth  = substitute(depth,'^| ','','')
6115"    call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">")
6116   endwhile
6117   if w:netrw_treetop =~ '/$'
6118    let treedir= w:netrw_treetop.treedir
6119   else
6120    let treedir= w:netrw_treetop.'/'.treedir
6121   endif
6122"   call Decho("bufnr(.)=".bufnr("%")." line($)=".line("$")." line(.)=".line("."))
6123  endif
6124  let treedir= substitute(treedir,'//$','/','')
6125
6126"  call Dret("NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">")
6127  return treedir
6128endfun
6129
6130" ---------------------------------------------------------------------
6131" s:NetrwTreeDisplay: recursive tree display {{{2
6132fun! s:NetrwTreeDisplay(dir,depth)
6133"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
6134
6135  " insure that there are no folds
6136  setlocal nofen
6137
6138  " install ../ and shortdir
6139  if a:depth == ""
6140   call setline(line("$")+1,'../')
6141"   call Decho("setline#".line("$")." ../ (depth is zero)")
6142  endif
6143  if a:dir =~ '^\a\+://'
6144   if a:dir == w:netrw_treetop
6145    let shortdir= a:dir
6146   else
6147    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
6148   endif
6149   call setline(line("$")+1,a:depth.shortdir)
6150  else
6151   let shortdir= substitute(a:dir,'^.*/','','e')
6152   call setline(line("$")+1,a:depth.shortdir.'/')
6153  endif
6154"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">")
6155
6156  " append a / to dir if its missing one
6157  let dir= a:dir
6158  if dir !~ '/$'
6159   let dir= dir.'/'
6160  endif
6161
6162  " display subtrees (if any)
6163  let depth= "| ".a:depth
6164
6165"  call Decho("display subtrees with depth<".depth."> and current leaves")
6166  for entry in w:netrw_treedict[a:dir]
6167   let direntry= substitute(dir.entry,'/$','','e')
6168"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">")
6169   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
6170"    call Decho("<".direntry."> is a key in treedict - display subtree for it")
6171    call s:NetrwTreeDisplay(direntry,depth)
6172   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
6173"    call Decho("<".direntry."/> is a key in treedict - display subtree for it")
6174    call s:NetrwTreeDisplay(direntry.'/',depth)
6175   else
6176"    call Decho("<".entry."> is not a key in treedict (no subtree)")
6177    keepj call setline(line("$")+1,depth.entry)
6178   endif
6179  endfor
6180"  call Dret("NetrwTreeDisplay")
6181endfun
6182
6183" ---------------------------------------------------------------------
6184" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
6185fun! s:NetrwTreeListing(dirname)
6186  if w:netrw_liststyle == s:TREELIST
6187"   call Dfunc("NetrwTreeListing() bufname<".expand("%").">")
6188"   call Decho("curdir<".a:dirname.">")
6189"   call Decho("win#".winnr().": w:netrw_treetop ".(exists("w:netrw_treetop")? "exists" : "doesn't exit")." w:netrw_treedict ".(exists("w:netrw_treedict")? "exists" : "doesn't exit"))
6190
6191   " update the treetop
6192"   call Decho("update the treetop")
6193   if !exists("w:netrw_treetop")
6194    let w:netrw_treetop= a:dirname
6195"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)")
6196   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
6197    let w:netrw_treetop= a:dirname
6198"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)")
6199   endif
6200
6201   " insure that we have at least an empty treedict
6202   if !exists("w:netrw_treedict")
6203    let w:netrw_treedict= {}
6204   endif
6205
6206   " update the directory listing for the current directory
6207"   call Decho("updating dictionary with ".a:dirname.":[..directory listing..]")
6208"   call Decho("bannercnt=".w:netrw_bannercnt." line($)=".line("$"))
6209   exe "silent! keepjumps ".w:netrw_bannercnt.',$g@^\.\.\=/$@d'
6210   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
6211"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]))
6212   exe "silent! keepjumps ".w:netrw_bannercnt.",$d"
6213
6214   " if past banner, record word
6215   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
6216    let fname= expand("<cword>")
6217   else
6218    let fname= ""
6219   endif
6220"   call Decho("fname<".fname.">")
6221
6222   " display from treetop on down
6223   call s:NetrwTreeDisplay(w:netrw_treetop,"")
6224
6225"   call Dret("NetrwTreeListing : bufname<".expand("%").">")
6226  endif
6227endfun
6228
6229" ---------------------------------------------------------------------
6230" s:NetrwWideListing: {{{2
6231fun! s:NetrwWideListing()
6232
6233  if w:netrw_liststyle == s:WIDELIST
6234"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
6235   " look for longest filename (cpf=characters per filename)
6236   " cpf: characters per filename
6237   " fpl: filenames per line
6238   " fpc: filenames per column
6239   setlocal ma noro
6240"   call Decho("setlocal ma noro")
6241   let b:netrw_cpf= 0
6242   if line("$") >= w:netrw_bannercnt
6243    exe 'sil keepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
6244    call histdel("/",-1)
6245   else
6246"    call Dret("NetrwWideListing")
6247    return
6248   endif
6249   let b:netrw_cpf= b:netrw_cpf + 2
6250"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf)
6251
6252   " determine qty files per line (fpl)
6253   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
6254   if w:netrw_fpl <= 0
6255    let w:netrw_fpl= 1
6256   endif
6257"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl)
6258
6259   " make wide display
6260   exe 'sil keepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'s",submatch(0)),"\\")/'
6261   call histdel("/",-1)
6262   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
6263   let newcolstart = w:netrw_bannercnt + fpc
6264   let newcolend   = newcolstart + fpc - 1
6265"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]")
6266   silent! let keepregstar = @*
6267   while line("$") >= newcolstart
6268    if newcolend > line("$") | let newcolend= line("$") | endif
6269    let newcolqty= newcolend - newcolstart
6270    exe newcolstart
6271    if newcolqty == 0
6272     exe "sil keepj norm! 0\<c-v>$hx".w:netrw_bannercnt."G$p"
6273    else
6274     exe "sil keepj norm! 0\<c-v>".newcolqty.'j$hx'.w:netrw_bannercnt.'G$p'
6275    endif
6276    exe "sil keepj ".newcolstart.','.newcolend.'d'
6277    exe 'sil keepj '.w:netrw_bannercnt
6278   endwhile
6279   silent! let @*= keepregstar
6280   exe "sil keepj ".w:netrw_bannercnt.',$s/\s\+$//e'
6281   call histdel("/",-1)
6282   setlocal noma nomod ro
6283"   call Dret("NetrwWideListing")
6284  endif
6285
6286endfun
6287
6288" ---------------------------------------------------------------------
6289" s:PerformListing: {{{2
6290fun! s:PerformListing(islocal)
6291"  call Dfunc("s:PerformListing(islocal=".a:islocal.") bufnr(%)=".bufnr("%")."<".bufname("%").">")
6292
6293  call s:NetrwSafeOptions()
6294  setlocal noro ma
6295"  call Decho("setlocal noro ma")
6296
6297"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
6298"   call Decho("(netrw) Processing your browsing request...")
6299"  endif								" Decho
6300
6301"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'))
6302  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6303   " force a refresh for tree listings
6304"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d")
6305   keepj %d
6306  endif
6307
6308  " save current directory on directory history list
6309  call s:NetrwBookHistHandler(3,b:netrw_curdir)
6310
6311  " Set up the banner {{{3
6312  if g:netrw_banner
6313"   call Decho("set up banner")
6314   keepj put ='\" ============================================================================'
6315   keepj put ='\" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')'
6316   keepj put ='\"   '.b:netrw_curdir
6317   keepj 1d
6318   let w:netrw_bannercnt= 3
6319   exe "keepj ".w:netrw_bannercnt
6320  else
6321   keepj 1
6322   let w:netrw_bannercnt= 1
6323  endif
6324
6325  let sortby= g:netrw_sort_by
6326  if g:netrw_sort_direction =~ "^r"
6327   let sortby= sortby." reversed"
6328  endif
6329
6330  " Sorted by... {{{3
6331  if g:netrw_banner
6332"   call Decho("handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">")
6333   if g:netrw_sort_by =~ "^n"
6334"   call Decho("directories will be sorted by name")
6335    " sorted by name
6336    keepj put ='\"   Sorted by      '.sortby
6337    keepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
6338    let w:netrw_bannercnt= w:netrw_bannercnt + 2
6339   else
6340"   call Decho("directories will be sorted by size or time")
6341    " sorted by size or date
6342    keepj put ='\"   Sorted by '.sortby
6343    let w:netrw_bannercnt= w:netrw_bannercnt + 1
6344   endif
6345   exe "keepj ".w:netrw_bannercnt
6346  endif
6347
6348  " show copy/move target, if any
6349  if g:netrw_banner
6350   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
6351"    call Decho("show copy/move target<".s:netrwmftgt.">")
6352    keepj put =''
6353    if s:netrwmftgt_islocal
6354     keepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
6355    else
6356     keepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
6357    endif
6358    let w:netrw_bannercnt= w:netrw_bannercnt + 1
6359   else
6360"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt")
6361   endif
6362   exe "keepj ".w:netrw_bannercnt
6363  endif
6364
6365  " Hiding...  -or-  Showing... {{{3
6366  if g:netrw_banner
6367"   call Decho("handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)")
6368   if g:netrw_list_hide != "" && g:netrw_hide
6369    if g:netrw_hide == 1
6370     keepj put ='\"   Hiding:        '.g:netrw_list_hide
6371    else
6372     keepj put ='\"   Showing:       '.g:netrw_list_hide
6373    endif
6374    let w:netrw_bannercnt= w:netrw_bannercnt + 1
6375   endif
6376   exe "keepjumps ".w:netrw_bannercnt
6377   keepj put ='\"   Quick Help: <F1>:help  -:go up dir  D:delete  R:rename  s:sort-by  x:exec'
6378   keepj put ='\" ============================================================================'
6379   let w:netrw_bannercnt= w:netrw_bannercnt + 2
6380  endif
6381
6382  " bannercnt should index the line just after the banner
6383  if g:netrw_banner
6384   let w:netrw_bannercnt= w:netrw_bannercnt + 1
6385   exe "keepj ".w:netrw_bannercnt
6386"   call Decho("bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"))
6387  endif
6388
6389  " set up syntax highlighting {{{3
6390"  call Decho("set up syntax highlighting")
6391  if has("syntax")
6392   setlocal ft=netrw
6393   if !exists("g:syntax_on") || !g:syntax_on
6394    setlocal ft=
6395   endif
6396  endif
6397
6398  " get list of files
6399"  call Decho("Get list of files - islocal=".a:islocal)
6400  if a:islocal
6401   call s:LocalListing()
6402  else " remote
6403   call s:NetrwRemoteListing()
6404  endif
6405"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)")
6406
6407  " manipulate the directory listing (hide, sort) {{{3
6408  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
6409"   call Decho("manipulate directory listing (hide)")
6410"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
6411   if g:netrw_hide && g:netrw_list_hide != ""
6412    call s:NetrwListHide()
6413   endif
6414   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
6415"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">")
6416
6417    if g:netrw_sort_by =~ "^n"
6418     " sort by name
6419     call s:NetrwSetSort()
6420
6421     if !g:netrw_banner || w:netrw_bannercnt < line("$")
6422"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")")
6423      if g:netrw_sort_direction =~ 'n'
6424       " normal direction sorting
6425       exe 'sil keepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
6426      else
6427       " reverse direction sorting
6428       exe 'sil keepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
6429      endif
6430     endif
6431     " remove priority pattern prefix
6432"     call Decho("remove priority pattern prefix")
6433     exe 'sil keepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
6434     call histdel("/",-1)
6435
6436    elseif a:islocal
6437     if !g:netrw_banner || w:netrw_bannercnt < line("$")
6438"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction)
6439      if g:netrw_sort_direction =~ 'n'
6440"       call Decho('exe silent keepjumps '.w:netrw_bannercnt.',$sort')
6441       exe 'sil keepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
6442      else
6443"       call Decho('exe silent keepjumps '.w:netrw_bannercnt.',$sort!')
6444       exe 'sil keepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
6445      endif
6446     exe 'sil keepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
6447     call histdel("/",-1)
6448     endif
6449    endif
6450
6451   elseif g:netrw_sort_direction =~ 'r'
6452"    call Decho('reverse the sorted listing')
6453    if !g:netrw_banner || w:netrw_bannercnt < line('$')
6454     exe 'sil keepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
6455     call histdel("/",-1)
6456    endif
6457   endif
6458  endif
6459
6460  " convert to wide/tree listing {{{3
6461"  call Decho("modify display if wide/tree listing style")
6462  call s:NetrwWideListing()
6463  call s:NetrwTreeListing(b:netrw_curdir)
6464
6465  if exists("w:netrw_bannercnt") && (line("$") > w:netrw_bannercnt || !g:netrw_banner)
6466   " place cursor on the top-left corner of the file listing
6467"   call Decho("place cursor on top-left corner of file listing")
6468   exe 'sil keepj '.w:netrw_bannercnt
6469   keepj norm! 0
6470  endif
6471
6472  " record previous current directory
6473  let w:netrw_prvdir= b:netrw_curdir
6474"  call Decho("record netrw_prvdir<".w:netrw_prvdir.">")
6475
6476  " save certain window-oriented variables into buffer-oriented variables {{{3
6477  call s:SetBufWinVars()
6478  call s:NetrwOptionRestore("w:")
6479
6480  " set display to netrw display settings
6481"  call Decho("set display to netrw display settings (noma nomod etc)")
6482  setlocal noma nomod nonu nobl nowrap ro
6483  if exists("s:treecurpos")
6484
6485   call netrw#NetrwRestorePosn(s:treecurpos)
6486   unlet s:treecurpos
6487  endif
6488
6489"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
6490endfun
6491
6492" ---------------------------------------------------------------------
6493" s:SetupNetrwStatusLine: {{{2
6494fun! s:SetupNetrwStatusLine(statline)
6495"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
6496
6497  if !exists("s:netrw_setup_statline")
6498   let s:netrw_setup_statline= 1
6499"   call Decho("do first-time status line setup")
6500
6501   if !exists("s:netrw_users_stl")
6502    let s:netrw_users_stl= &stl
6503   endif
6504   if !exists("s:netrw_users_ls")
6505    let s:netrw_users_ls= &laststatus
6506   endif
6507
6508   " set up User9 highlighting as needed
6509   let keepa= @a
6510   redir @a
6511   try
6512    hi User9
6513   catch /^Vim\%((\a\+)\)\=:E411/
6514    if &bg == "dark"
6515     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
6516    else
6517     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
6518    endif
6519   endtry
6520   redir END
6521   let @a= keepa
6522  endif
6523
6524  " set up status line (may use User9 highlighting)
6525  " insure that windows have a statusline
6526  " make sure statusline is displayed
6527  let &stl=a:statline
6528  setlocal laststatus=2
6529"  call Decho("stl=".&stl)
6530  redraw
6531
6532"  call Dret("SetupNetrwStatusLine : stl=".&stl)
6533endfun
6534
6535" ---------------------------------------------------------------------
6536"  Remote Directory Browsing Support:    {{{1
6537" ===========================================
6538
6539" ---------------------------------------------------------------------
6540" s:NetrwRemoteListing: {{{2
6541fun! s:NetrwRemoteListing()
6542"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">)")
6543
6544  call s:RemotePathAnalysis(b:netrw_curdir)
6545
6546  " sanity check:
6547  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
6548"   call Decho("b:netrw_method=".b:netrw_method)
6549   if !executable("ftp")
6550    if !exists("g:netrw_quiet")
6551     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
6552    endif
6553    call s:NetrwOptionRestore("w:")
6554"    call Dret("s:NetrwRemoteListing")
6555    return
6556   endif
6557
6558  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
6559   if !exists("g:netrw_quiet")
6560    if g:netrw_list_cmd == ""
6561     call netrw#ErrorMsg(s:ERROR,g:netrw_ssh_cmd." is not executable on your system",47)
6562    else
6563     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
6564    endif
6565   endif
6566
6567   call s:NetrwOptionRestore("w:")
6568"   call Dret("s:NetrwRemoteListing")
6569   return
6570  endif  " (remote handling sanity check)
6571
6572  if exists("b:netrw_method")
6573"   call Decho("setting w:netrw_method<".b:netrw_method.">")
6574   let w:netrw_method= b:netrw_method
6575  endif
6576
6577  if s:method == "ftp"
6578   " use ftp to get remote file listing
6579"   call Decho("use ftp to get remote file listing")
6580   let s:method  = "ftp"
6581   let listcmd = g:netrw_ftp_list_cmd
6582   if g:netrw_sort_by =~ '^t'
6583    let listcmd= g:netrw_ftp_timelist_cmd
6584   elseif g:netrw_sort_by =~ '^s'
6585    let listcmd= g:netrw_ftp_sizelist_cmd
6586   endif
6587"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)")
6588   call s:NetrwRemoteFtpCmd(s:path,listcmd)
6589"   exe "keepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."))'
6590
6591   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST
6592    " shorten the listing
6593"    call Decho("generate short listing")
6594    exe "keepj ".w:netrw_bannercnt
6595
6596    " cleanup
6597    if g:netrw_ftp_browse_reject != ""
6598     exe "sil! keepj g/".g:netrw_ftp_browse_reject."/keepj d"
6599     call histdel("/",-1)
6600    endif
6601    sil! keepj %s/\r$//e
6602    call histdel("/",-1)
6603
6604    " if there's no ../ listed, then put ./ and ../ in
6605    let line1= line(".")
6606    exe "keepj ".w:netrw_bannercnt
6607    let line2= search('^\.\.\/\%(\s\|$\)','cnW')
6608    if line2 == 0
6609"     call Decho("netrw is putting ./ and ../ into listing")
6610     keepj put='../'
6611     keepj put='./'
6612    endif
6613    exe "keepj ".line1
6614    keepjumps norm! 0
6615
6616"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."))
6617    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
6618"     call Decho("M$ ftp cleanup")
6619     exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
6620     call histdel("/",-1)
6621    else " normal ftp cleanup
6622"     call Decho("normal ftp cleanup")
6623     exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
6624     exe "sil! keepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
6625     exe "sil! keepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
6626     call histdel("/",-1)
6627     call histdel("/",-1)
6628     call histdel("/",-1)
6629    endif
6630   endif
6631
6632  else
6633   " use ssh to get remote file listing {{{3
6634"   call Decho("use ssh to get remote file listing: s:path<".s:path.">")
6635   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
6636"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)")
6637   if g:netrw_scp_cmd =~ '^pscp'
6638"    call Decho("1: exe silent r! ".shellescape(listcmd.s:path, 1))
6639    exe "silent r! ".listcmd.shellescape(s:path, 1)
6640    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
6641    keepj g/^Listing directory/keepj d
6642    keepj g/^d[-rwx][-rwx][-rwx]/keepj s+$+/+e
6643    sil keepj g/^l[-rwx][-rwx][-rwx]/keepj s+$+@+e
6644    call histdel("/",-1)
6645    call histdel("/",-1)
6646    call histdel("/",-1)
6647    if g:netrw_liststyle != s:LONGLIST
6648     keepj g/^[dlsp-][-rwx][-rwx][-rwx]/keepj s/^.*\s\(\S\+\)$/\1/e
6649     call histdel("/",-1)
6650    endif
6651   else
6652    if s:path == ""
6653"     call Decho("2: exe silent r! ".listcmd)
6654     exe "sil r! ".listcmd
6655    else
6656"     call Decho("3: exe silent r! ".listcmd.' '.shellescape(s:path,1))
6657     exe "sil r! ".listcmd.' '.shellescape(s:path,1)
6658"     call Decho("listcmd<".listcmd."> path<".s:path.">")
6659    endif
6660   endif
6661
6662   " cleanup
6663   if g:netrw_ftp_browse_reject != ""
6664"    call Decho("(cleanup) exe silent! g/".g:netrw_ssh_browse_reject."/keepjumps d")
6665    exe "sil! g/".g:netrw_ssh_browse_reject."/keepjumps d"
6666    call histdel("/",-1)
6667   endif
6668  endif
6669
6670  if w:netrw_liststyle == s:LONGLIST
6671   " do a long listing; these substitutions need to be done prior to sorting {{{3
6672"   call Decho("fix long listing:")
6673
6674   if s:method == "ftp"
6675    " cleanup
6676    exe "keepj ".w:netrw_bannercnt
6677    while getline('.') =~ g:netrw_ftp_browse_reject
6678     keepj d
6679    endwhile
6680    " if there's no ../ listed, then put ./ and ../ in
6681    let line1= line(".")
6682    keepj 1
6683    sil keepj call search('^\.\.\/\%(\s\|$\)','W')
6684    let line2= line(".")
6685    if line2 == 0
6686     exe 'keepj '.w:netrw_bannercnt."put='./'"
6687     if b:netrw_curdir != '/'
6688      exe 'keepj '.w:netrw_bannercnt."put='../'"
6689     endif
6690    endif
6691   exe "keepj ".line1
6692   keepjumps norm! 0
6693   endif
6694
6695   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
6696"    call Decho("M$ ftp site listing cleanup")
6697    exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\(\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+\)\(\w.*\)$/\2\t\1/'
6698   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
6699"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"))
6700    exe 'sil keepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
6701    exe 'sil keepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2\t\1/e'
6702    exe 'sil keepj '.w:netrw_bannercnt
6703    call histdel("/",-1)
6704    call histdel("/",-1)
6705    call histdel("/",-1)
6706   endif
6707  endif
6708
6709"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
6710"   exe "keepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."))'
6711"  endif " Decho
6712"  call Dret("s:NetrwRemoteListing")
6713endfun
6714
6715" ---------------------------------------------------------------------
6716" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
6717fun! s:NetrwRemoteRm(usrhost,path) range
6718"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
6719"  call Decho("firstline=".a:firstline." lastline=".a:lastline)
6720  let svpos= netrw#NetrwSavePosn()
6721
6722  let all= 0
6723  if exists("s:netrwmarkfilelist_{bufnr('%')}")
6724   " remove all marked files
6725"   call Decho("remove all marked files with bufnr#".bufnr("%"))
6726   for fname in s:netrwmarkfilelist_{bufnr("%")}
6727    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
6728    if ok =~ 'q\%[uit]'
6729     break
6730    elseif ok =~ 'a\%[ll]'
6731     let all= 1
6732    endif
6733   endfor
6734   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
6735
6736  else
6737   " remove files specified by range
6738"   call Decho("remove files specified by range")
6739
6740   " preparation for removing multiple files/directories
6741   let ctr= a:firstline
6742
6743   " remove multiple files and directories
6744   while ctr <= a:lastline
6745    exe ctr
6746    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
6747    if ok =~ 'q\%[uit]'
6748     break
6749    elseif ok =~ 'a\%[ll]'
6750     let all= 1
6751    endif
6752    let ctr= ctr + 1
6753   endwhile
6754  endif
6755
6756  " refresh the (remote) directory listing
6757"  call Decho("refresh remote directory listing")
6758  call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6759  call netrw#NetrwRestorePosn(svpos)
6760
6761"  call Dret("s:NetrwRemoteRm")
6762endfun
6763
6764" ---------------------------------------------------------------------
6765" s:NetrwRemoteRmFile: {{{2
6766fun! s:NetrwRemoteRmFile(path,rmfile,all)
6767"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
6768
6769  let all= a:all
6770  let ok = ""
6771
6772  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
6773   " attempt to remove file
6774"    call Decho("attempt to remove file (all=".all.")")
6775   if !all
6776    echohl Statement
6777"    call Decho("case all=0:")
6778    call inputsave()
6779    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
6780    call inputrestore()
6781    echohl NONE
6782    if ok == ""
6783     let ok="no"
6784    endif
6785    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
6786    if ok =~ 'a\%[ll]'
6787     let all= 1
6788    endif
6789   endif
6790
6791   if all || ok =~ 'y\%[es]' || ok == ""
6792"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""))
6793    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
6794"     call Decho("case ftp:")
6795     let path= a:path
6796     if path =~ '^\a\+://'
6797      let path= substitute(path,'^\a\+://[^/]\+/','','')
6798     endif
6799     silent! keepjumps .,$d
6800     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
6801    else
6802"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">")
6803     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
6804"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">")
6805     if !exists("b:netrw_curdir")
6806      call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
6807      let ok="q"
6808     else
6809      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
6810"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">")
6811"      call Decho("remotedir<".remotedir.">")
6812"      call Decho("rmfile<".a:rmfile.">")
6813      if remotedir != ""
6814       let netrw_rm_cmd= netrw_rm_cmd." ".shellescape(fnameescape(remotedir.a:rmfile))
6815      else
6816       let netrw_rm_cmd= netrw_rm_cmd." ".shellescape(fnameescape(a:rmfile))
6817      endif
6818"      call Decho("call system(".netrw_rm_cmd.")")
6819      let ret= system(netrw_rm_cmd)
6820      if ret != 0
6821       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
6822      endif
6823"      call Decho("returned=".ret." errcode=".v:shell_error)
6824     endif
6825    endif
6826   elseif ok =~ 'q\%[uit]'
6827"    call Decho("ok==".ok)
6828    break
6829   endif
6830
6831  else
6832   " attempt to remove directory
6833"    call Decho("attempt to remove directory")
6834   if !all
6835    call inputsave()
6836    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
6837    call inputrestore()
6838    if ok == ""
6839     let ok="no"
6840    endif
6841    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
6842    if ok =~ 'a\%[ll]'
6843     let all= 1
6844    endif
6845   endif
6846
6847   if all || ok =~ 'y\%[es]' || ok == ""
6848    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
6849     call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
6850    else
6851     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
6852     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.shellescape(netrw#WinPath(rmfile))
6853"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")")
6854     let ret= system(netrw_rmdir_cmd)
6855"      call Decho("returned=".ret." errcode=".v:shell_error)
6856
6857     if v:shell_error != 0
6858"      call Decho("v:shell_error not 0")
6859      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.shellescape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
6860"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")")
6861      let ret= system(netrw_rmf_cmd)
6862"      call Decho("returned=".ret." errcode=".v:shell_error)
6863
6864      if v:shell_error != 0 && !exists("g:netrw_quiet")
6865      	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
6866      endif
6867     endif
6868    endif
6869
6870   elseif ok =~ 'q\%[uit]'
6871    break
6872   endif
6873  endif
6874
6875"  call Dret("s:NetrwRemoteRmFile ".ok)
6876  return ok
6877endfun
6878
6879" ---------------------------------------------------------------------
6880" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
6881"  This function assumes that a long listing will be received.  Size, time,
6882"  and reverse sorts will be requested of the server but not otherwise
6883"  enforced here.
6884fun! s:NetrwRemoteFtpCmd(path,listcmd)
6885"  call Dfunc("NetrwRemoteFtpCmd(path<".a:path."> listcmd<".a:listcmd.">) netrw_method=".w:netrw_method)
6886"  call Decho("line($)=".line("$")." bannercnt=".w:netrw_bannercnt)
6887
6888  " because WinXX ftp uses unix style input
6889  let ffkeep= &ff
6890  setlocal ma ff=unix noro
6891"  call Decho("setlocal ma ff=unix noro")
6892
6893  " clear off any older non-banner lines
6894  " note that w:netrw_bannercnt indexes the line after the banner
6895"  call Decho('exe silent! keepjumps '.w:netrw_bannercnt.",$d  (clear off old non-banner lines)")
6896  exe "silent! keepjumps ".w:netrw_bannercnt.",$d"
6897
6898  ".........................................
6899  if w:netrw_method == 2 || w:netrw_method == 5
6900   " ftp + <.netrc>:  Method #2
6901   if a:path != ""
6902    keepj put ='cd \"'.a:path.'\"'
6903   endif
6904   if exists("g:netrw_ftpextracmd")
6905    keepj put =g:netrw_ftpextracmd
6906"    call Decho("filter input: ".getline('.'))
6907   endif
6908   call setline(line("$")+1,a:listcmd)
6909"   exe "keepjumps ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."))'
6910   if exists("g:netrw_port") && g:netrw_port != ""
6911"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1))
6912    exe s:netrw_silentxfer." keepjumps ".w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1)
6913   else
6914"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
6915    exe s:netrw_silentxfer." keepjumps ".w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
6916   endif
6917
6918   ".........................................
6919  elseif w:netrw_method == 3
6920   " ftp + machine,id,passwd,filename:  Method #3
6921    setlocal ff=unix
6922    if exists("g:netrw_port") && g:netrw_port != ""
6923     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
6924    else
6925     keepj put ='open '.g:netrw_machine
6926    endif
6927
6928    if exists("g:netrw_ftp") && g:netrw_ftp == 1
6929     keepj put =g:netrw_uid
6930     keepj put ='\"'.s:netrw_passwd.'\"'
6931    else
6932     keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
6933    endif
6934
6935   if a:path != ""
6936    keepj put ='cd \"'.a:path.'\"'
6937   endif
6938   if exists("g:netrw_ftpextracmd")
6939    keepj put =g:netrw_ftpextracmd
6940"    call Decho("filter input: ".getline('.'))
6941   endif
6942   keepj call setline(line("$")+1,a:listcmd)
6943
6944    " perform ftp:
6945    " -i       : turns off interactive prompting from ftp
6946    " -n  unix : DON'T use <.netrc>, even though it exists
6947    " -n  win32: quit being obnoxious about password
6948"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."))'
6949"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i -n")
6950    exe s:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i -n"
6951
6952   ".........................................
6953  else
6954   call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",23)
6955  endif
6956
6957  " cleanup for Windows
6958  if has("win32") || has("win95") || has("win64") || has("win16")
6959   sil! keepj %s/\r$//e
6960   call histdel("/",-1)
6961  endif
6962  if a:listcmd == "dir"
6963   " infer directory/link based on the file permission string
6964   sil! keepj g/d\%([-r][-w][-x]\)\{3}/keepj s@$@/@
6965   sil! keepj g/l\%([-r][-w][-x]\)\{3}/keepj s/$/@/
6966   call histdel("/",-1)
6967   call histdel("/",-1)
6968   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST
6969    exe "sil! keepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
6970    call histdel("/",-1)
6971   endif
6972  endif
6973
6974  " ftp's listing doesn't seem to include ./ or ../
6975  if !search('^\.\/$\|\s\.\/$','wn')
6976   exe 'keepj '.w:netrw_bannercnt
6977   keepj put ='./'
6978  endif
6979  if !search('^\.\.\/$\|\s\.\.\/$','wn')
6980   exe 'keepj '.w:netrw_bannercnt
6981   keepj put ='../'
6982  endif
6983
6984  " restore settings
6985  let &ff= ffkeep
6986"  call Dret("NetrwRemoteFtpCmd")
6987endfun
6988
6989" ---------------------------------------------------------------------
6990" s:NetrwRemoteRename: rename a remote file or directory {{{2
6991fun! s:NetrwRemoteRename(usrhost,path) range
6992"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
6993
6994  " preparation for removing multiple files/directories
6995  let svpos      = netrw#NetrwSavePosn()
6996  let ctr        = a:firstline
6997  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
6998
6999  " rename files given by the markfilelist
7000  if exists("s:netrwmarkfilelist_{bufnr('%')}")
7001   for oldname in s:netrwmarkfilelist_{bufnr("%")}
7002"    call Decho("oldname<".oldname.">")
7003    if exists("subfrom")
7004     let newname= substitute(oldname,subfrom,subto,'')
7005"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">")
7006    else
7007     call inputsave()
7008     let newname= input("Moving ".oldname." to : ",oldname)
7009     call inputrestore()
7010     if newname =~ '^s/'
7011      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
7012      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
7013      let newname = substitute(oldname,subfrom,subto,'')
7014"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">")
7015     endif
7016    endif
7017
7018    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
7019     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
7020    else
7021     let oldname= shellescape(a:path.oldname)
7022     let newname= shellescape(a:path.newname)
7023"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")")
7024     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
7025    endif
7026
7027   endfor
7028   call s:NetrwUnMarkFile(1)
7029
7030  else
7031
7032  " attempt to rename files/directories
7033   while ctr <= a:lastline
7034    exe "keepj ".ctr
7035
7036    let oldname= s:NetrwGetWord()
7037"   call Decho("oldname<".oldname.">")
7038
7039    call inputsave()
7040    let newname= input("Moving ".oldname." to : ",oldname)
7041    call inputrestore()
7042
7043    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
7044     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
7045    else
7046     let oldname= shellescape(a:path.oldname)
7047     let newname= shellescape(a:path.newname)
7048"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")")
7049     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
7050    endif
7051
7052    let ctr= ctr + 1
7053   endwhile
7054  endif
7055
7056  " refresh the directory
7057  call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
7058  call netrw#NetrwRestorePosn(svpos)
7059
7060"  call Dret("NetrwRemoteRename")
7061endfun
7062
7063" ---------------------------------------------------------------------
7064"  Local Directory Browsing Support:    {{{1
7065" ==========================================
7066
7067" ---------------------------------------------------------------------
7068" netrw#LocalBrowseCheck: {{{2
7069fun! netrw#LocalBrowseCheck(dirname)
7070  " unfortunate interaction -- split window debugging can't be
7071  " used here, must use D-echoRemOn or D-echoTabOn -- the BufEnter
7072  " event triggers another call to LocalBrowseCheck() when attempts
7073  " to write to the DBG buffer are made.
7074  " The &ft == "netrw" test was installed because the BufEnter event
7075  " would hit when re-entering netrw windows, creating unexpected
7076  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
7077"  call Decho("netrw#LocalBrowseCheck: isdir<".a:dirname.">=".isdirectory(a:dirname).((exists("s:treeforceredraw")? " treeforceredraw" : "")))
7078  if isdirectory(a:dirname)
7079"   call Decho(" ft<".&ft."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : " doesn't exist")."> dirname<".a:dirname.">"." line($)=".line("$"))
7080   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname)
7081    silent! call s:NetrwBrowse(1,a:dirname)
7082   elseif &ft == "netrw" && line("$") == 1
7083    silent! call s:NetrwBrowse(1,a:dirname)
7084   elseif exists("s:treeforceredraw")
7085    unlet s:treeforceredraw
7086    silent! call s:NetrwBrowse(1,a:dirname)
7087   endif
7088  endif
7089  " not a directory, ignore it
7090endfun
7091
7092" ---------------------------------------------------------------------
7093"  s:LocalListing: does the job of "ls" for local directories {{{2
7094fun! s:LocalListing()
7095"  call Dfunc("s:LocalListing()")
7096"  call Decho("&ma=".&ma)
7097"  call Decho("&mod=".&mod)
7098"  call Decho("&ro=".&ro)
7099"  call Decho("bufname(%)<".bufname("%").">")
7100
7101"  if exists("b:netrw_curdir") |call Decho('b:netrw_curdir<'.b:netrw_curdir.">")  |else|call Decho("b:netrw_curdir doesn't exist") |endif
7102"  if exists("g:netrw_sort_by")|call Decho('g:netrw_sort_by<'.g:netrw_sort_by.">")|else|call Decho("g:netrw_sort_by doesn't exist")|endif
7103
7104  " get the list of files contained in the current directory
7105  let dirname    = escape(b:netrw_curdir,g:netrw_glob_escape)
7106  let dirnamelen = s:Strlen(b:netrw_curdir)
7107  let filelist   = glob(s:ComposePath(dirname,"*"))
7108"  call Decho("glob(dirname<".dirname."/*>)=".filelist)
7109  if filelist != ""
7110   let filelist= filelist."\n"
7111  endif
7112  let filelist= filelist.glob(s:ComposePath(dirname,".*"))
7113"  call Decho("glob(dirname<".dirname."/.*>)=".filelist)
7114
7115  " Coding choice: either   elide   ./ if present
7116  "                or       include ./ if not present
7117  if filelist =~ '[\\/]\.[\\/]\=\(\n\|$\)'
7118   " elide /path/. from glob() entries if present
7119"   call Decho("elide /path/. from glob entries if present")
7120   let filelist = substitute(filelist,'\n','\t','g')
7121   let filelist = substitute(filelist,'^[^\t]\+[/\\]\.\t','','')
7122   let filelist = substitute(filelist,'[^\t]\+[/\\]\.$','','')
7123   let filelist = substitute(filelist,'\t\zs[^\t]\+[/\\]\.\t','','')
7124   let filelist = substitute(filelist,'\t','\n','g')
7125  endif
7126"  call Decho("filelist<".filelist.">")
7127  if filelist !~ '[\\/]\.\.[\\/]\=\(\n\|$\)'
7128    " include ../ in the glob() entry if its missing
7129"   call Decho("forcibly tacking on ..")
7130   let filelist= filelist."\n".s:ComposePath(b:netrw_curdir,"../")
7131"   call Decho("filelist<".filelist.">")
7132  endif
7133  if b:netrw_curdir == '/'
7134   " remove .. from filelist when current directory is root directory
7135"   call Decho("remove .. from filelist")
7136   let filelist= substitute(filelist,'/\.\.\n','','')
7137  endif
7138  " remove multiple contiguous newlines
7139  let filelist= substitute(filelist,'\n\{2,}','\n','ge')
7140  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7141   " change all \s to /s
7142"   call Decho('change all \s to /s')
7143   let filelist= substitute(filelist,'\','/','g')
7144  else
7145   " escape all \s to \\
7146"   call Decho('escape all \s to \\')
7147   let filelist= substitute(filelist,'\','\\','g')
7148  endif
7149
7150"  call Decho("(before while) dirname<".dirname.">")
7151"  call Decho("(before while) dirnamelen<".dirnamelen.">")
7152"  call Decho("(before while) filelist<".filelist.">")
7153
7154  while filelist != ""
7155   if filelist =~ '\n'
7156    let filename = substitute(filelist,'\n.*$','','e')
7157    let filelist = substitute(filelist,'^.\{-}\n\(.*\)$','\1','e')
7158   else
7159    let filename = filelist
7160    let filelist = ""
7161   endif
7162"   call Decho(" ")
7163"   call Decho("(while) filelist<".filelist.">")
7164"   call Decho("(while) filename<".filename.">")
7165
7166   if getftype(filename) == "link"
7167    " indicate a symbolic link
7168"    call Decho("indicate <".filename."> is a symbolic link with trailing @")
7169    let pfile= filename."@"
7170
7171   elseif getftype(filename) == "socket"
7172    " indicate a socket
7173"    call Decho("indicate <".filename."> is a socket with trailing =")
7174    let pfile= filename."="
7175
7176   elseif getftype(filename) == "fifo"
7177    " indicate a fifo
7178"    call Decho("indicate <".filename."> is a fifo with trailing |")
7179    let pfile= filename."|"
7180
7181   elseif isdirectory(filename)
7182    " indicate a directory
7183"    call Decho("indicate <".filename."> is a directory with trailing /")
7184    let pfile= filename."/"
7185
7186   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(filename)
7187    if (has("win32") || has("win95") || has("win64") || has("win16"))
7188     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
7189      " indicate an executable
7190"      call Decho("indicate <".filename."> is executable with trailing *")
7191      let pfile= filename."*"
7192     else
7193      " normal file
7194      let pfile= filename
7195     endif
7196    elseif executable(filename)
7197     " indicate an executable
7198"     call Decho("indicate <".filename."> is executable with trailing *")
7199     let pfile= filename."*"
7200    else
7201     " normal file
7202     let pfile= filename
7203    endif
7204
7205   else
7206    " normal file
7207    let pfile= filename
7208   endif
7209"   call Decho("pfile<".pfile."> (after *@/ appending)")
7210
7211   if pfile =~ '//$'
7212    let pfile= substitute(pfile,'//$','/','e')
7213"    call Decho("change // to /: pfile<".pfile.">")
7214   endif
7215   let pfile= strpart(pfile,dirnamelen)
7216   let pfile= substitute(pfile,'^[/\\]','','e')
7217"   call Decho("filename<".filename.">")
7218"   call Decho("pfile   <".pfile.">")
7219
7220   if w:netrw_liststyle == s:LONGLIST
7221    let sz   = getfsize(filename)
7222    let fsz  = strpart("               ",1,15-strlen(sz)).sz
7223    let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
7224"    call Decho("sz=".sz." fsz=".fsz)
7225   endif
7226
7227   if     g:netrw_sort_by =~ "^t"
7228    " sort by time (handles time up to 1 quintillion seconds, US)
7229"    call Decho("getftime(".filename.")=".getftime(filename))
7230    let t  = getftime(filename)
7231    let ft = strpart("000000000000000000",1,18-strlen(t)).t
7232"    call Decho("exe keepjumps put ='".ft.'/'.filename."'")
7233    let ftpfile= ft.'/'.pfile
7234    sil! keepj put=ftpfile
7235
7236   elseif g:netrw_sort_by =~ "^s"
7237    " sort by size (handles file sizes up to 1 quintillion bytes, US)
7238"    call Decho("getfsize(".filename.")=".getfsize(filename))
7239    let sz   = getfsize(filename)
7240    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
7241"    call Decho("exe keepjumps put ='".fsz.'/'.filename."'")
7242    let fszpfile= fsz.'/'.pfile
7243    sil! keepj put =fszpfile
7244
7245   else
7246    " sort by name
7247"    call Decho("exe keepjumps put ='".pfile."'")
7248    sil! keepj put=pfile
7249   endif
7250  endwhile
7251
7252  " cleanup any windows mess at end-of-line
7253  sil! keepj g/^$/d
7254  sil! keepj %s/\r$//e
7255  call histdel("/",-1)
7256  exe "setlocal ts=".g:netrw_maxfilenamelen
7257"  call Decho("setlocal ts=".g:netrw_maxfilenamelen)
7258
7259"  call Dret("s:LocalListing")
7260endfun
7261
7262" ---------------------------------------------------------------------
7263" s:LocalBrowseShellCmdRefresh: this function is called after a user has {{{2
7264" performed any shell command.  The idea is to cause all local-browsing
7265" buffers to be refreshed after a user has executed some shell command,
7266" on the chance that s/he removed/created a file/directory with it.
7267fun! s:LocalBrowseShellCmdRefresh()
7268"  call Dfunc("LocalBrowseShellCmdRefresh() browselist=".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "empty")." ".tabpagenr("$")." tabs")
7269  " determine which buffers currently reside in a tab
7270  if !exists("s:netrw_browselist")
7271"   call Dret("LocalBrowseShellCmdRefresh : browselist is empty")
7272   return
7273  endif
7274  if !exists("w:netrw_bannercnt")
7275"   call Dret("LocalBrowseShellCmdRefresh : don't refresh when focus not on netrw window")
7276   return
7277  endif
7278  if exists("s:locbrowseshellcmd")
7279   if s:locbrowseshellcmd
7280    let s:locbrowseshellcmd= 0
7281"    call Dret("LocalBrowseShellCmdRefresh : NetrwBrowse itself caused the refresh")
7282    return
7283   endif
7284   let s:locbrowseshellcmd= 0
7285  endif
7286  let itab       = 1
7287  let buftablist = []
7288  while itab <= tabpagenr("$")
7289   let buftablist = buftablist + tabpagebuflist()
7290   let itab       = itab + 1
7291   tabn
7292  endwhile
7293"  call Decho("buftablist".string(buftablist))
7294"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">")
7295  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
7296  "   | refresh any netrw window
7297  "   | wipe out any non-displaying netrw buffer
7298  let curwin = winnr()
7299  let ibl    = 0
7300  for ibuf in s:netrw_browselist
7301"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf))
7302   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
7303    " wipe out any non-displaying netrw buffer
7304"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">")
7305    exe "sil! bd ".fnameescape(ibuf)
7306    call remove(s:netrw_browselist,ibl)
7307"    call Decho("browselist=".string(s:netrw_browselist))
7308    continue
7309   elseif index(tabpagebuflist(),ibuf) != -1
7310    " refresh any netrw buffer
7311"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf))
7312    exe bufwinnr(ibuf)."wincmd w"
7313    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
7314   endif
7315   let ibl= ibl + 1
7316  endfor
7317  exe curwin."wincmd w"
7318
7319"  call Dret("LocalBrowseShellCmdRefresh")
7320endfun
7321
7322" ---------------------------------------------------------------------
7323" s:NetrwLocalRm: {{{2
7324fun! s:NetrwLocalRm(path) range
7325"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
7326"  call Decho("firstline=".a:firstline." lastline=".a:lastline)
7327
7328  " preparation for removing multiple files/directories
7329  let ret   = 0
7330  let all   = 0
7331  let svpos = netrw#NetrwSavePosn()
7332
7333  if exists("s:netrwmarkfilelist_{bufnr('%')}")
7334   " remove all marked files
7335"   call Decho("remove all marked files")
7336   for fname in s:netrwmarkfilelist_{bufnr("%")}
7337    let ok= s:NetrwLocalRmFile(a:path,fname,all)
7338    if ok =~ 'q\%[uit]' || ok == "no"
7339     break
7340    elseif ok =~ 'a\%[ll]'
7341     let all= 1
7342    endif
7343   endfor
7344   call s:NetrwUnMarkFile(1)
7345
7346  else
7347  " remove (multiple) files and directories
7348"   call Decho("remove files in range [".a:firstline.",".a:lastline."]")
7349
7350   let ctr = a:firstline
7351   while ctr <= a:lastline
7352    exe "keepj ".ctr
7353
7354    " sanity checks
7355    if line(".") < w:netrw_bannercnt
7356     let ctr= ctr + 1
7357     continue
7358    endif
7359    let curword= s:NetrwGetWord()
7360    if curword == "./" || curword == "../"
7361     let ctr= ctr + 1
7362     continue
7363    endif
7364    let ok= s:NetrwLocalRmFile(a:path,curword,all)
7365    if ok =~ 'q\%[uit]' || ok == "no"
7366     break
7367    elseif ok =~ 'a\%[ll]'
7368     let all= 1
7369    endif
7370    let ctr= ctr + 1
7371   endwhile
7372  endif
7373
7374  " refresh the directory
7375"  call Decho("bufname<".bufname("%").">")
7376  if bufname("%") != "NetrwMessage"
7377   call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
7378   call netrw#NetrwRestorePosn(svpos)
7379  endif
7380
7381"  call Dret("s:NetrwLocalRm")
7382endfun
7383
7384" ---------------------------------------------------------------------
7385" s:NetrwLocalRmFile: remove file fname given the path {{{2
7386"                     Give confirmation prompt unless all==1
7387fun! s:NetrwLocalRmFile(path,fname,all)
7388"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
7389
7390  let all= a:all
7391  let ok = ""
7392  keepj norm! 0
7393  let rmfile= s:ComposePath(a:path,a:fname)
7394"  call Decho("rmfile<".rmfile.">")
7395
7396  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
7397   " attempt to remove file
7398"   call Decho("attempt to remove file<".rmfile.">")
7399   if !all
7400    echohl Statement
7401    call inputsave()
7402    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
7403    call inputrestore()
7404    echohl NONE
7405    if ok == ""
7406     let ok="no"
7407    endif
7408"    call Decho("response: ok<".ok.">")
7409    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
7410"    call Decho("response: ok<".ok."> (after sub)")
7411    if ok =~ 'a\%[ll]'
7412     let all= 1
7413    endif
7414   endif
7415
7416   if all || ok =~ 'y\%[es]' || ok == ""
7417    let ret= s:NetrwDelete(rmfile)
7418"    call Decho("errcode=".v:shell_error." ret=".ret)
7419   endif
7420
7421  else
7422   " attempt to remove directory
7423   if !all
7424    echohl Statement
7425    call inputsave()
7426    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
7427    call inputrestore()
7428    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
7429    if ok == ""
7430     let ok="no"
7431    endif
7432    if ok =~ 'a\%[ll]'
7433     let all= 1
7434    endif
7435   endif
7436   let rmfile= substitute(rmfile,'[\/]$','','e')
7437
7438   if all || ok =~ 'y\%[es]' || ok == ""
7439"    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_local_rmdir.') '.shellescape(rmfile).')')
7440    call system(netrw#WinPath(g:netrw_local_rmdir).' '.shellescape(rmfile))
7441"    call Decho("v:shell_error=".v:shell_error)
7442
7443    if v:shell_error != 0
7444"     call Decho("2nd attempt to remove directory<".rmfile.">")
7445     let errcode= s:NetrwDelete(rmfile)
7446"     call Decho("errcode=".errcode)
7447
7448     if errcode != 0
7449      if has("unix")
7450"       call Decho("3rd attempt to remove directory<".rmfile.">")
7451       call system("rm ".shellescape(rmfile))
7452       if v:shell_error != 0 && !exists("g:netrw_quiet")
7453        call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
7454	let ok="no"
7455       endif
7456      elseif !exists("g:netrw_quiet")
7457       call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
7458       let ok="no"
7459      endif
7460     endif
7461    endif
7462   endif
7463  endif
7464
7465"  call Dret("s:NetrwLocalRmFile ".ok)
7466  return ok
7467endfun
7468
7469" ---------------------------------------------------------------------
7470" s:NetrwLocalRename: rename a remote file or directory {{{2
7471fun! s:NetrwLocalRename(path) range
7472"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
7473
7474  " preparation for removing multiple files/directories
7475  let ctr  = a:firstline
7476  let svpos= netrw#NetrwSavePosn()
7477
7478  " rename files given by the markfilelist
7479  if exists("s:netrwmarkfilelist_{bufnr('%')}")
7480   for oldname in s:netrwmarkfilelist_{bufnr("%")}
7481"    call Decho("oldname<".oldname.">")
7482    if exists("subfrom")
7483     let newname= substitute(oldname,subfrom,subto,'')
7484"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">")
7485    else
7486     call inputsave()
7487     let newname= input("Moving ".oldname." to : ",oldname)
7488     call inputrestore()
7489     if newname =~ '^s/'
7490      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
7491      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
7492"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">")
7493      let newname = substitute(oldname,subfrom,subto,'')
7494     endif
7495    endif
7496    call rename(oldname,newname)
7497   endfor
7498   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
7499
7500  else
7501
7502   " attempt to rename files/directories
7503   while ctr <= a:lastline
7504    exe "keepj ".ctr
7505
7506    " sanity checks
7507    if line(".") < w:netrw_bannercnt
7508     let ctr= ctr + 1
7509     continue
7510    endif
7511    let curword= s:NetrwGetWord()
7512    if curword == "./" || curword == "../"
7513     let ctr= ctr + 1
7514     continue
7515    endif
7516
7517    keepj norm! 0
7518    let oldname= s:ComposePath(a:path,curword)
7519"   call Decho("oldname<".oldname.">")
7520
7521    call inputsave()
7522    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
7523    call inputrestore()
7524
7525    call rename(oldname,newname)
7526"   call Decho("renaming <".oldname."> to <".newname.">")
7527
7528    let ctr= ctr + 1
7529   endwhile
7530  endif
7531
7532  " refresh the directory
7533"  call Decho("refresh the directory listing")
7534  call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
7535  call netrw#NetrwRestorePosn(svpos)
7536
7537"  call Dret("NetrwLocalRename")
7538endfun
7539
7540" ---------------------------------------------------------------------
7541" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
7542"
7543"     g:netrw_    Directory Is
7544"     fastbrowse  Local  Remote
7545"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
7546"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
7547"  fast   2         H      H
7548"
7549"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
7550"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
7551"           (re-using a buffer may not be as accurate)
7552fun! s:LocalFastBrowser()
7553"  call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
7554
7555  " initialize browselist, a list of buffer numbers that the local browser has used
7556  if !exists("s:netrw_browselist")
7557"   call Decho("initialize s:netrw_browselist")
7558   let s:netrw_browselist= []
7559  endif
7560
7561  " append current buffer to fastbrowse list
7562  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
7563"   call Decho("appendng current buffer to browselist")
7564   call add(s:netrw_browselist,bufnr("%"))
7565"   call Decho("browselist=".string(s:netrw_browselist))
7566  endif
7567
7568  " enable autocmd events to handle refreshing/removing local browser buffers
7569  "    If local browse buffer is currently showing: refresh it
7570  "    If local browse buffer is currently hidden : wipe it
7571  if !exists("s:netrw_browser_shellcmd") && g:netrw_fastbrowse <= 1
7572"   call Decho("setting up local-browser shell command refresh")
7573   let s:netrw_browser_shellcmd= 1
7574   augroup AuNetrwShellCmd
7575    au!
7576    if (has("win32") || has("win95") || has("win64") || has("win16"))
7577"     call Decho("autocmd: ShellCmdPost * call s:LocalBrowseShellCmdRefresh()")
7578     au ShellCmdPost			*	call s:LocalBrowseShellCmdRefresh()
7579    else
7580     au ShellCmdPost,FocusGained	*	call s:LocalBrowseShellCmdRefresh()
7581"     call Decho("autocmd: ShellCmdPost,FocusGained * call s:LocalBrowseShellCmdRefresh()")
7582    endif
7583   augroup END
7584  endif
7585
7586  " user must have changed fastbrowse to its fast setting, so remove
7587  " the associated autocmd events
7588  if g:netrw_fastbrowse > 1 && exists("s:netrw_browser_shellcmd")
7589"   call Decho("remove AuNetrwShellCmd autcmd group")
7590   unlet s:netrw_browser_shellcmd
7591   augroup AuNetrwShellCmd
7592    au!
7593   augroup END
7594   augroup! AuNetrwShellCmd
7595  endif
7596
7597"  call Dret("LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
7598endfun
7599
7600" ---------------------------------------------------------------------
7601" Support Functions: {{{1
7602
7603" ---------------------------------------------------------------------
7604" netrw#ErrorMsg: {{{2
7605"   0=note     = s:NOTE
7606"   1=warning  = s:WARNING
7607"   2=error    = s:ERROR
7608"  Dec 03, 2009 : max errnum currently is 76
7609fun! netrw#ErrorMsg(level,msg,errnum)
7610"  call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
7611
7612  if a:level == 1
7613   let level= "**warning** (netrw) "
7614  elseif a:level == 2
7615   let level= "**error** (netrw) "
7616  else
7617   let level= "**note** (netrw) "
7618  endif
7619"  call Decho("level=".level)
7620
7621  if g:netrw_use_errorwindow
7622   " (default) netrw creates a one-line window to show error/warning
7623   " messages (reliably displayed)
7624
7625   " record current window number for NetrwRestorePosn()'s benefit
7626   let s:winBeforeErr= winnr()
7627"   call Decho("s:winBeforeErr=".s:winBeforeErr)
7628
7629   " getting messages out reliably is just plain difficult!
7630   " This attempt splits the current window, creating a one line window.
7631   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
7632"    call Decho("write to NetrwMessage buffer")
7633    exe bufwinnr("NetrwMessage")."wincmd w"
7634"    call Decho("setlocal ma noro")
7635    setlocal ma noro
7636    call setline(line("$")+1,level.a:msg)
7637    keepj $
7638   else
7639"    call Decho("create a NetrwMessage buffer window")
7640    bo 1split
7641    call s:NetrwEnew()
7642    call s:NetrwSafeOptions()
7643    setlocal bt=nofile
7644    file NetrwMessage
7645"    call Decho("setlocal ma noro")
7646    setlocal ma noro
7647    call setline(line("$"),level.a:msg)
7648   endif
7649"   call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr())
7650   if &fo !~ '[ta]'
7651    syn clear
7652    syn match netrwMesgNote	"^\*\*note\*\*"
7653    syn match netrwMesgWarning	"^\*\*warning\*\*"
7654    syn match netrwMesgError	"^\*\*error\*\*"
7655    hi link netrwMesgWarning WarningMsg
7656    hi link netrwMesgError   Error
7657   endif
7658   setlocal noma ro bh=wipe
7659
7660  else
7661   " (optional) netrw will show messages using echomsg.  Even if the
7662   " message doesn't appear, at least it'll be recallable via :messages
7663"   redraw!
7664   if a:level == s:WARNING
7665    echohl WarningMsg
7666   elseif a:level == s:ERROR
7667    echohl Error
7668   endif
7669   echomsg level.a:msg
7670"   call Decho("echomsg ***netrw*** ".a:msg)
7671   echohl None
7672  endif
7673
7674"  call Dret("netrw#ErrorMsg")
7675endfun
7676
7677" ---------------------------------------------------------------------
7678" netrw#NetrwRestorePosn: restores the cursor and file position as saved by NetrwSavePosn() {{{2
7679fun! netrw#NetrwRestorePosn(...)
7680"  call Dfunc("netrw#NetrwRestorePosn() a:0=".a:0." winnr=".(exists("w:netrw_winnr")? w:netrw_winnr : -1)." line=".(exists("w:netrw_line")? w:netrw_line : -1)." col=".(exists("w:netrw_col")? w:netrw_col : -1)." hline=".(exists("w:netrw_hline")? w:netrw_hline : -1))
7681  let eikeep= &ei
7682  set ei=all
7683  if expand("%") == "NetrwMessage"
7684   exe s:winBeforeErr."wincmd w"
7685  endif
7686
7687  if a:0 > 0
7688   exe a:1
7689  endif
7690
7691  " restore window
7692  if exists("w:netrw_winnr")
7693"   call Decho("restore window: exe silent! ".w:netrw_winnr."wincmd w")
7694   exe "sil! ".w:netrw_winnr."wincmd w"
7695  endif
7696  if v:shell_error == 0
7697   " as suggested by Bram M: redraw on no error
7698   " allows protocol error messages to remain visible
7699"   redraw!
7700  endif
7701
7702  " restore top-of-screen line
7703  if exists("w:netrw_hline")
7704"   call Decho("restore topofscreen: exe norm! ".w:netrw_hline."G0z")
7705   exe "keepj norm! ".w:netrw_hline."G0z\<CR>"
7706  endif
7707
7708  " restore position
7709  if exists("w:netrw_line") && exists("w:netrw_col")
7710"   call Decho("restore posn: exe norm! ".w:netrw_line."G0".w:netrw_col."|")
7711   exe "keepj norm! ".w:netrw_line."G0".w:netrw_col."\<bar>"
7712  endif
7713
7714  let &ei= eikeep
7715"  call Dret("netrw#NetrwRestorePosn")
7716endfun
7717
7718" ---------------------------------------------------------------------
7719" netrw#NetrwSavePosn: saves position of cursor on screen {{{2
7720fun! netrw#NetrwSavePosn()
7721"  call Dfunc("netrw#NetrwSavePosn()")
7722  " Save current line and column
7723  let w:netrw_winnr= winnr()
7724  let w:netrw_line = line(".")
7725  let w:netrw_col  = virtcol(".")
7726"  call Decho("currently, win#".w:netrw_winnr." line#".w:netrw_line." col#".w:netrw_col)
7727
7728  " Save top-of-screen line
7729  keepj norm! H0
7730  let w:netrw_hline= line(".")
7731
7732  " set up string holding position parameters
7733  let ret          = "let w:netrw_winnr=".w:netrw_winnr."|let w:netrw_line=".w:netrw_line."|let w:netrw_col=".w:netrw_col."|let w:netrw_hline=".w:netrw_hline
7734
7735  call netrw#NetrwRestorePosn()
7736"  call Dret("netrw#NetrwSavePosn : winnr=".w:netrw_winnr." line=".w:netrw_line." col=".w:netrw_col." hline=".w:netrw_hline)
7737  return ret
7738endfun
7739
7740" ------------------------------------------------------------------------
7741"  netrw#RFC2396: converts %xx into characters {{{2
7742fun! netrw#RFC2396(fname)
7743"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
7744  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
7745"  call Dret("netrw#RFC2396 ".fname)
7746  return fname
7747endfun
7748
7749" ---------------------------------------------------------------------
7750"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
7751fun! s:ComposePath(base,subdir)
7752"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
7753
7754  if(has("amiga"))
7755"   call Decho("amiga")
7756   let ec = a:base[s:Strlen(a:base)-1]
7757   if ec != '/' && ec != ':'
7758    let ret = a:base . "/" . a:subdir
7759   else
7760    let ret = a:base . a:subdir
7761   endif
7762
7763  elseif a:subdir =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
7764"   call Decho("windows")
7765   let ret= a:subdir
7766
7767  elseif a:base =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
7768"   call Decho("windows")
7769   if a:base =~ '[/\\]$'
7770    let ret= a:base.a:subdir
7771   else
7772    let ret= a:base."/".a:subdir
7773   endif
7774
7775  elseif a:base =~ '^\a\+://'
7776"   call Decho("remote linux/macos")
7777   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
7778   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
7779   if a:subdir == '../'
7780    if curpath =~ '[^/]/[^/]\+/$'
7781     let curpath= substitute(curpath,'[^/]\+/$','','')
7782    else
7783     let curpath=""
7784    endif
7785    let ret= urlbase.curpath
7786   else
7787    let ret= urlbase.curpath.a:subdir
7788   endif
7789"   call Decho("urlbase<".urlbase.">")
7790"   call Decho("curpath<".curpath.">")
7791"   call Decho("ret<".ret.">")
7792
7793  else
7794"   call Decho("local linux/macos")
7795   let ret = substitute(a:base."/".a:subdir,"//","/","g")
7796   if a:base =~ '^//'
7797    " keeping initial '//' for the benefit of network share listing support
7798    let ret= '/'.ret
7799   endif
7800   let ret= simplify(ret)
7801  endif
7802
7803"  call Dret("s:ComposePath ".ret)
7804  return ret
7805endfun
7806
7807" ---------------------------------------------------------------------
7808" s:FileReadable: o/s independent filereadable {{{2
7809fun! s:FileReadable(fname)
7810"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
7811
7812  if g:netrw_cygwin
7813   let ret= filereadable(substitute(a:fname,'/cygdrive/\(.\)','\1:/',''))
7814  else
7815   let ret= filereadable(a:fname)
7816  endif
7817
7818"  call Dret("s:FileReadable ".ret)
7819  return ret
7820endfun
7821
7822" ---------------------------------------------------------------------
7823"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
7824"                 Places correct suffix on end of temporary filename,
7825"                 using the suffix provided with fname
7826fun! s:GetTempfile(fname)
7827"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
7828
7829  if !exists("b:netrw_tmpfile")
7830   " get a brand new temporary filename
7831   let tmpfile= tempname()
7832"   call Decho("tmpfile<".tmpfile."> : from tempname()")
7833
7834   let tmpfile= substitute(tmpfile,'\','/','ge')
7835"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /")
7836
7837   " sanity check -- does the temporary file's directory exist?
7838   if !isdirectory(substitute(tmpfile,'[^/]\+$','','e'))
7839"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
7840    call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
7841"    call Dret("s:GetTempfile getcwd<".getcwd().">")
7842    return ""
7843   endif
7844
7845   " let netrw#NetSource() know about the tmpfile
7846   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#NetrwBrowseX()
7847"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">")
7848
7849   " o/s dependencies
7850   if g:netrw_cygwin != 0
7851    let tmpfile = substitute(tmpfile,'^\(\a\):','/cygdrive/\1','e')
7852   elseif has("win32") || has("win95") || has("win64") || has("win16")
7853    if !exists("+shellslash") || !&ssl
7854     let tmpfile = substitute(tmpfile,'/','\','g')
7855    endif
7856   else
7857    let tmpfile = tmpfile
7858   endif
7859   let b:netrw_tmpfile= tmpfile
7860"   call Decho("o/s dependent fixed tempname<".tmpfile.">")
7861  else
7862   " re-use temporary filename
7863   let tmpfile= b:netrw_tmpfile
7864"   call Decho("tmpfile<".tmpfile."> re-using")
7865  endif
7866
7867  " use fname's suffix for the temporary file
7868  if a:fname != ""
7869   if a:fname =~ '\.[^./]\+$'
7870"    call Decho("using fname<".a:fname.">'s suffix")
7871    if a:fname =~ '.tar.gz' || a:fname =~ '.tar.bz2'
7872     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
7873    else
7874     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
7875    endif
7876"    call Decho("suffix<".suffix.">")
7877    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
7878"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)")
7879    let tmpfile .= suffix
7880"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">")
7881    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
7882   endif
7883  endif
7884
7885"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
7886"  call Dret("s:GetTempfile <".tmpfile.">")
7887  return tmpfile
7888endfun
7889
7890" ---------------------------------------------------------------------
7891" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
7892"               a correct command for use with a system() call
7893fun! s:MakeSshCmd(sshcmd)
7894"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
7895  let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user.s:machine,'')
7896  if exists("g:netrw_port") && g:netrw_port != ""
7897   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
7898  elseif exists("s:port") && s:port != ""
7899   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
7900  else
7901   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
7902  endif
7903"  call Dret("s:MakeSshCmd <".sshcmd.">")
7904  return sshcmd
7905endfun
7906
7907" ---------------------------------------------------------------------
7908" s:NetrwBMShow: {{{2
7909fun! s:NetrwBMShow()
7910"  call Dfunc("s:NetrwBMShow()")
7911  redir => bmshowraw
7912   menu
7913  redir END
7914  let bmshowlist = split(bmshowraw,'\n')
7915  if bmshowlist != []
7916   let bmshowfuncs= filter(bmshowlist,'v:val =~ "<SNR>\\d\\+_BMShow()"')
7917   if bmshowfuncs != []
7918    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
7919    if bmshowfunc =~ '^call.*BMShow()'
7920     exe "sil! ".bmshowfunc
7921    endif
7922   endif
7923  endif
7924"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
7925endfun
7926
7927" ---------------------------------------------------------------------
7928" s:NetrwCursorline: {{{2
7929fun! s:NetrwCursorline()
7930  if !exists("w:netrw_liststyle")
7931   let w:netrw_liststyle= g:netrw_liststyle
7932  endif
7933"  call Dfunc("s:NetrwCursorline() liststyle=".w:netrw_liststyle." g:netrw_cursorline=".g:netrw_cursorline." s:netrw_usercuc=".s:netrw_usercuc." s:netrw_usercul=".s:netrw_usercul)
7934  "
7935  if w:netrw_liststyle != s:WIDELIST
7936   " thin-long-tree listings
7937   if g:netrw_cursorline == 2
7938    setlocal cursorline
7939    let &l:cursorcolumn= s:netrw_usercuc
7940"    call Decho("setlocal cursorline  (cursorcolumn is ".((s:netrw_usercuc)? "on" : "off").")")
7941   elseif g:netrw_cursorline
7942    setlocal cursorline
7943"    call Decho("setlocal cursorline")
7944   endif
7945
7946  else
7947   " wide listings
7948   if g:netrw_cursorline == 2
7949    setlocal cursorline cursorcolumn
7950"    call Decho("setlocal cursorline cursorcolumn")
7951   elseif g:netrw_cursorline
7952    let &l:cursorline= s:netrw_usercul
7953"    call Decho("cursorline is ".((s:netrw_usercul)? "on" : "off").")")
7954   endif
7955  endif
7956"  call Dret("s:NetrwCursorline : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
7957endfun
7958
7959" ---------------------------------------------------------------------
7960" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
7961fun! s:RestoreCursorline()
7962"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
7963  let &l:cursorline   = s:netrw_usercul
7964  let &l:cursorcolumn = s:netrw_usercuc
7965"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
7966endfun
7967
7968" ---------------------------------------------------------------------
7969" s:NetrwDelete: Deletes a file. {{{2
7970"           Uses Steve Hall's idea to insure that Windows paths stay
7971"           acceptable.  No effect on Unix paths.
7972"  Examples of use:  let result= s:NetrwDelete(path)
7973fun! s:NetrwDelete(path)
7974"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
7975
7976  let path = netrw#WinPath(a:path)
7977  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7978   if exists("+shellslash")
7979    let sskeep= &shellslash
7980    setlocal noshellslash
7981    let result      = delete(path)
7982    let &shellslash = sskeep
7983   else
7984"    call Decho("exe let result= ".a:cmd."('".path."')")
7985    let result= delete(path)
7986   endif
7987  else
7988"   call Decho("let result= delete(".path.")")
7989   let result= delete(path)
7990  endif
7991  if result < 0
7992   call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
7993  endif
7994
7995"  call Dret("s:NetrwDelete ".result)
7996  return result
7997endfun
7998
7999" ---------------------------------------------------------------------
8000" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
8001fun! s:NetrwEnew(...)
8002"  call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$"))
8003"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">")
8004
8005  " grab a function-local-variable copy of buffer variables
8006"  call Decho("make function-local copy of netrw variables")
8007  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
8008  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
8009  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
8010  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
8011  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
8012  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
8013  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
8014  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
8015  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
8016  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
8017  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
8018  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
8019  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
8020  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
8021  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
8022  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
8023
8024  call s:NetrwOptionRestore("w:")
8025"  call Decho("generate a buffer with keepjumps keepalt enew!")
8026  keepj keepalt enew!
8027"  call Decho("bufnr($)=".bufnr("$"))
8028  call s:NetrwOptionSave("w:")
8029
8030  " copy function-local-variables to buffer variable equivalents
8031"  call Decho("copy function-local variables back to buffer netrw variables")
8032  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
8033  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
8034  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
8035  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
8036  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
8037  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
8038  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
8039  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
8040  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
8041  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
8042  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
8043  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
8044  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
8045  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
8046  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
8047  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
8048
8049  if a:0 > 0
8050   let b:netrw_curdir= a:1
8051   if b:netrw_curdir =~ '/$'
8052    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8053     file NetrwTreeListing
8054     set bt=nowrite noswf
8055     nno <silent> <buffer> [	:silent call <SID>TreeListMove('[')<cr>
8056     nno <silent> <buffer> ]	:silent call <SID>TreeListMove(']')<cr>
8057    else
8058     exe "sil! keepalt file ".fnameescape(b:netrw_curdir)
8059    endif
8060   endif
8061  endif
8062
8063"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#").">")
8064endfun
8065
8066" ------------------------------------------------------------------------
8067" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
8068" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
8069fun! s:NetrwSaveWordPosn()
8070"  call Dfunc("NetrwSaveWordPosn()")
8071  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
8072"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
8073endfun
8074
8075" ---------------------------------------------------------------------
8076" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
8077"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
8078fun! s:NetrwRestoreWordPosn()
8079"  call Dfunc("NetrwRestoreWordPosn()")
8080  silent! call search(s:netrw_saveword,'w')
8081"  call Dret("NetrwRestoreWordPosn")
8082endfun
8083
8084" ---------------------------------------------------------------------
8085" s:RestoreBufVars: {{{2
8086fun! s:RestoreBufVars()
8087"  call Dfunc("s:RestoreBufVars()")
8088
8089  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
8090  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
8091  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
8092  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
8093  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
8094  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
8095
8096"  call Dret("s:RestoreBufVars")
8097endfun
8098
8099" ---------------------------------------------------------------------
8100" s:RemotePathAnalysis: {{{2
8101fun! s:RemotePathAnalysis(dirname)
8102"  call Dfunc("s:RemotePathAnalysis()")
8103
8104  let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
8105  let s:method  = substitute(a:dirname,dirpat,'\1','')
8106  let s:user    = substitute(a:dirname,dirpat,'\2','')
8107  let s:machine = substitute(a:dirname,dirpat,'\3','')
8108  let s:port    = substitute(a:dirname,dirpat,'\4','')
8109  let s:path    = substitute(a:dirname,dirpat,'\5','')
8110  let s:fname   = substitute(a:dirname,'^.*/\ze.','','')
8111
8112"  call Decho("set up s:method <".s:method .">")
8113"  call Decho("set up s:user   <".s:user   .">")
8114"  call Decho("set up s:machine<".s:machine.">")
8115"  call Decho("set up s:port   <".s:port.">")
8116"  call Decho("set up s:path   <".s:path   .">")
8117"  call Decho("set up s:fname  <".s:fname  .">")
8118
8119"  call Dret("s:RemotePathAnalysis")
8120endfun
8121
8122" ---------------------------------------------------------------------
8123" s:RemoteSystem: runs a command on a remote host using ssh {{{2
8124"                 Returns status
8125" Runs system() on
8126"    [cd REMOTEDIRPATH;] a:cmd
8127" Note that it doesn't do shellescape(a:cmd)!
8128fun! s:RemoteSystem(cmd)
8129"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
8130  if !executable(g:netrw_ssh_cmd)
8131   call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
8132  elseif !exists("b:netrw_curdir")
8133   call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
8134  else
8135   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
8136   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
8137   if remotedir != ""
8138    let cmd= cmd.' cd '.shellescape(remotedir).";"
8139   else
8140    let cmd= cmd.' '
8141   endif
8142   let cmd= cmd.a:cmd
8143"   call Decho("call system(".cmd.")")
8144   let ret= system(cmd)
8145  endif
8146"  call Dret("s:RemoteSystem ".ret)
8147  return ret
8148endfun
8149
8150" ---------------------------------------------------------------------
8151" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
8152fun! s:RestoreWinVars()
8153"  call Dfunc("s:RestoreWinVars()")
8154  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
8155  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
8156  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
8157  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
8158  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
8159  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
8160  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
8161  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
8162  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
8163  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
8164  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
8165  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
8166  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
8167  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
8168  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
8169  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
8170  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
8171  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
8172"  call Dret("s:RestoreWinVars")
8173endfun
8174
8175" ---------------------------------------------------------------------
8176" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
8177"
8178"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
8179"             is true) and a command, :Rexplore, which call this function.
8180"
8181"             s:nbcd_curpos_{bufnr('%')} is set up by s:NetrwBrowseChgDir()
8182fun! s:NetrwRexplore(islocal,dirname)
8183"  call Dfunc("s:NetrwRexplore(islocal=".a:islocal." dirname<".a:dirname.">)")
8184  if a:islocal
8185   call netrw#LocalBrowseCheck(a:dirname)
8186  else
8187   call s:NetrwBrowse(0,a:dirname)
8188  endif
8189  if exists("s:nbcd_curpos_{bufnr('%')}")
8190   call netrw#NetrwRestorePosn(s:nbcd_curpos_{bufnr('%')})
8191   unlet s:nbcd_curpos_{bufnr('%')}
8192  endif
8193  if exists("s:explore_match")
8194   exe "2match netrwMarkFile /".s:explore_match."/"
8195  endif
8196"  call Dret("s:NetrwRexplore")
8197endfun
8198
8199" ---------------------------------------------------------------------
8200" s:SaveBufVars: {{{2
8201fun! s:SaveBufVars()
8202"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
8203
8204  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
8205  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
8206  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
8207  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
8208  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
8209  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
8210
8211"  call Dret("s:SaveBufVars")
8212endfun
8213
8214" ---------------------------------------------------------------------
8215" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
8216fun! s:SaveWinVars()
8217"  call Dfunc("s:SaveWinVars() win#".winnr())
8218  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
8219  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
8220  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
8221  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
8222  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
8223  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
8224  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
8225  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
8226  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
8227  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
8228  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
8229  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
8230  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
8231  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
8232  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
8233  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
8234  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
8235  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
8236"  call Dret("s:SaveWinVars")
8237endfun
8238
8239" ---------------------------------------------------------------------
8240" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
8241"   To allow separate windows to have their own activities, such as
8242"   Explore **/pattern, several variables have been made window-oriented.
8243"   However, when the user splits a browser window (ex: ctrl-w s), these
8244"   variables are not inherited by the new window.  SetBufWinVars() and
8245"   UseBufWinVars() get around that.
8246fun! s:SetBufWinVars()
8247"  call Dfunc("s:SetBufWinVars() win#".winnr())
8248  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
8249  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
8250  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
8251  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
8252  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
8253  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
8254  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
8255  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
8256  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
8257  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
8258"  call Dret("s:SetBufWinVars")
8259endfun
8260
8261" ---------------------------------------------------------------------
8262" s:SetRexDir: set directory for :Rexplore {{{2
8263fun! s:SetRexDir(islocal,dirname)
8264"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">)")
8265  " set up Rex and leftmouse-double-click
8266  if a:islocal
8267   exe 'com! Rexplore call s:NetrwRexplore(1,"'.escape(a:dirname,'"\').'")'
8268   if g:netrw_retmap
8269    if !hasmapto("<Plug>NetrwReturn") && maparg("<2-leftmouse>","n") == ""
8270     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
8271    endif
8272    let dir = escape(a:dirname, s:netrw_map_escape)
8273    exe 'nnoremap <silent> <Plug>NetrwReturn :call <SID>NetrwRexplore(1,"'.dir.'")<cr>'
8274   endif
8275  else
8276   exe 'com! Rexplore call s:NetrwRexplore(0,"'.escape(a:dirname,'"\').'")'
8277   if g:netrw_retmap
8278    if !hasmapto("<Plug>NetrwReturn") && maparg("<2-leftmouse>","n") == ""
8279     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
8280    endif
8281    let dir = escape(a:dirname, s:netrw_map_escape)
8282    exe 'nnoremap <silent> <Plug>NetrwReturn :call <SID>NetrwRexplore(0,"'.dir.'")<cr>'
8283   endif
8284  endif
8285"  call Dret("s:SetRexDir")
8286endfun
8287
8288" ---------------------------------------------------------------------
8289" s:Strlen: this function returns the length of a string, even if its {{{2
8290"           using two-byte etc characters.
8291"           Solution from Nicolai Weibull, vim docs (:help strlen()), Tony Mechelynck,
8292"           and a bit from me.
8293"           if g:netrw_xstrlen is zero (default), then the builtin strlen() function is used.
8294fun! s:Strlen(x)
8295"  call Dfunc("s:Strlen(x<".a:x.">")
8296  if g:netrw_xstrlen == 1
8297   " number of codepoints (Latin a + combining circumflex is two codepoints)
8298   " (comment from TM, solution from NW)
8299   let ret= strlen(substitute(a:x,'.','c','g'))
8300
8301  elseif g:netrw_xstrlen == 2
8302   " number of spacing codepoints (Latin a + combining circumflex is one spacing
8303   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
8304   " (comment from TM, solution from TM)
8305   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
8306
8307  elseif g:netrw_xstrlen == 3
8308   " virtual length (counting, for instance, tabs as anything between 1 and
8309   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
8310   " preceded by lam, one otherwise, etc.)
8311   " (comment from TM, solution from me)
8312   let modkeep= &mod
8313   exe "keepj norm! o\<esc>"
8314   call setline(line("."),a:x)
8315   let ret= virtcol("$") - 1
8316   keepj d
8317   let &mod= modkeep
8318
8319  else
8320   " at least give a decent default
8321   let ret= strlen(a:x)
8322  endif
8323"  call Dret("s:Strlen ".ret)
8324  return ret
8325endfun
8326
8327" ---------------------------------------------------------------------
8328" s:TreeListMove: {{{2
8329fun! s:TreeListMove(dir)
8330"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
8331  let curline  = getline('.')
8332  let prvline  = (line(".") > 1)?         getline(line(".")-1) : ''
8333  let nxtline  = (line(".") < line("$"))? getline(line(".")+1) : ''
8334  let curindent= substitute(curline,'^\([| ]*\).\{-}$','\1','')
8335  let indentm1 = substitute(curindent,'^| ','','')
8336"  call Decho("prvline  <".prvline."> #".line(".")-1)
8337"  call Decho("curline  <".curline."> #".line("."))
8338"  call Decho("nxtline  <".nxtline."> #".line(".")+1)
8339"  call Decho("curindent<".curindent.">")
8340"  call Decho("indentm1 <".indentm1.">")
8341
8342  if curline !~ '/$'
8343"   call Decho('regfile')
8344   if     a:dir == '[' && prvline != ''
8345    keepj norm! 0
8346    let nl = search('^'.indentm1.'[^|]','bWe')    " search backwards from regular file
8347"    call Decho("regfile srch back: ".nl)
8348   elseif a:dir == ']' && nxtline != ''
8349    keepj norm! $
8350    let nl = search('^'.indentm1.'[^|]','We')     " search forwards from regular file
8351"    call Decho("regfile srch fwd: ".nl)
8352   endif
8353
8354  elseif a:dir == '[' && prvline != ''
8355   keepj norm! 0
8356   let curline= line(".")
8357   let nl     = search('^'.curindent.'[^|]','bWe') " search backwards From directory, same indentation
8358"   call Decho("dir srch back ind: ".nl)
8359   if nl != 0
8360    if line(".") == curline-1
8361     let nl= search('^'.indentm1.'[^|]','bWe')     " search backwards from directory, indentation - 1
8362"     call Decho("dir srch back ind-1: ".nl)
8363    endif
8364   endif
8365
8366  elseif a:dir == ']' && nxtline != ''
8367   keepj norm! $
8368   let curline = line(".")
8369   let nl      = search('^'.curindent.'[^|]','We') " search forwards from directory, same indentation
8370"   call Decho("dir srch fwd ind: ".nl)
8371   if nl != 0
8372    if line(".") == curline+1
8373     let nl= search('^'.indentm1.'[^|]','We')         " search forwards from directory, indentation - 1
8374"     call Decho("dir srch fwd ind-1: ".nl)
8375    endif
8376   endif
8377
8378  endif
8379
8380"  call Dret("s:TreeListMove")
8381endfun
8382
8383" ---------------------------------------------------------------------
8384" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
8385"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
8386"                      can't be called except via emenu.  But due to locale, that menu line may not be called
8387"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
8388fun! s:UpdateBuffersMenu()
8389"  call Dfunc("s:UpdateBuffersMenu()")
8390  if has("gui") && has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
8391   try
8392    silent emenu Buffers.Refresh\ menu
8393   catch /^Vim\%((\a\+)\)\=:E/
8394    let v:errmsg= ""
8395    silent call s:NetrwBMShow()
8396   endtry
8397  endif
8398"  call Dret("s:UpdateBuffersMenu")
8399endfun
8400
8401" ---------------------------------------------------------------------
8402" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
8403"              Matching function to BufferWinVars()
8404fun! s:UseBufWinVars()
8405"  call Dfunc("s:UseBufWinVars()")
8406  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
8407  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
8408  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
8409  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
8410  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
8411  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
8412  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
8413  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
8414  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
8415  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
8416"  call Dret("s:UseBufWinVars")
8417endfun
8418
8419" ---------------------------------------------------------------------
8420" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
8421fun! netrw#WinPath(path)
8422"  call Dfunc("netrw#WinPath(path<".a:path.">)")
8423  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
8424   " remove cygdrive prefix, if present
8425   let path = substitute(a:path,'/cygdrive/\(.\)','\1:','')
8426   " remove trailing slash (Win95)
8427   let path = substitute(path, '\(\\\|/\)$', '', 'g')
8428   " remove escaped spaces
8429   let path = substitute(path, '\ ', ' ', 'g')
8430   " convert slashes to backslashes
8431   let path = substitute(path, '/', '\', 'g')
8432  else
8433   let path= a:path
8434  endif
8435"  call Dret("netrw#WinPath <".path.">")
8436  return path
8437endfun
8438
8439" ---------------------------------------------------------------------
8440" Settings Restoration: {{{2
8441let &cpo= s:keepcpo
8442unlet s:keepcpo
8443
8444" ------------------------------------------------------------------------
8445" Modelines: {{{1
8446" vim:ts=8 fdm=marker
8447