xref: /vim-8.2.3635/runtime/autoload/netrw.vim (revision 2bf24176)
1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		Oct 23, 2015
4" Version:	154
5" Maintainer:	Charles E Campbell <[email protected]>
6" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
7" Copyright:    Copyright (C) 1999-2015 Charles E. Campbell {{{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(,'~'.expand("<slnum>"))
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
25" netrw requires vim having patch 213; netrw will benefit from vim's having patch#656, too
26if v:version < 704 || !has("patch213")
27 if !exists("s:needpatch213")
28  unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch 213"
29 endif
30 let s:needpatch213= 1
31 finish
32endif
33let g:loaded_netrw = "v154"
34if !exists("s:NOTE")
35 let s:NOTE    = 0
36 let s:WARNING = 1
37 let s:ERROR   = 2
38endif
39
40let s:keepcpo= &cpo
41setl cpo&vim
42"let g:dechofuncname= 1
43"DechoRemOn
44"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw,'~'.expand("<slnum>"))
45
46" ======================
47"  Netrw Variables: {{{1
48" ======================
49
50" ---------------------------------------------------------------------
51" netrw#ErrorMsg: {{{2
52"   0=note     = s:NOTE
53"   1=warning  = s:WARNING
54"   2=error    = s:ERROR
55"   Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number)
56"          netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number)
57"          (this function can optionally take a list of messages)
58"  Oct 09, 2015 : max errnum currently is 102
59fun! netrw#ErrorMsg(level,msg,errnum)
60"  call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
61
62  if a:level < g:netrw_errorlvl
63"   call Dret("netrw#ErrorMsg : suppressing level=".a:level." since g:netrw_errorlvl=".g:netrw_errorlvl)
64   return
65  endif
66
67  if a:level == 1
68   let level= "**warning** (netrw) "
69  elseif a:level == 2
70   let level= "**error** (netrw) "
71  else
72   let level= "**note** (netrw) "
73  endif
74"  call Decho("level=".level,'~'.expand("<slnum>"))
75
76  if g:netrw_use_errorwindow
77   " (default) netrw creates a one-line window to show error/warning
78   " messages (reliably displayed)
79
80   " record current window number for NetrwRestorePosn()'s benefit
81   let s:winBeforeErr= winnr()
82"   call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>"))
83
84   " getting messages out reliably is just plain difficult!
85   " This attempt splits the current window, creating a one line window.
86   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
87"    call Decho("write to NetrwMessage buffer",'~'.expand("<slnum>"))
88    exe bufwinnr("NetrwMessage")."wincmd w"
89"    call Decho("setl ma noro",'~'.expand("<slnum>"))
90    setl ma noro
91    if type(a:msg) == 3
92     for msg in a:msg
93      NetrwKeepj call setline(line("$")+1,level.msg)
94     endfor
95    else
96     NetrwKeepj call setline(line("$")+1,level.a:msg)
97    endif
98    NetrwKeepj $
99   else
100"    call Decho("create a NetrwMessage buffer window",'~'.expand("<slnum>"))
101    bo 1split
102    sil! call s:NetrwEnew()
103    sil! NetrwKeepj call s:NetrwSafeOptions()
104    setl bt=nofile
105    NetrwKeepj file NetrwMessage
106"    call Decho("setl ma noro",'~'.expand("<slnum>"))
107    setl ma noro
108    if type(a:msg) == 3
109     for msg in a:msg
110      NetrwKeepj call setline(line("$")+1,level.msg)
111     endfor
112    else
113     NetrwKeepj call setline(line("$"),level.a:msg)
114    endif
115    NetrwKeepj $
116   endif
117"   call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr(),'~'.expand("<slnum>"))
118   if &fo !~ '[ta]'
119    syn clear
120    syn match netrwMesgNote	"^\*\*note\*\*"
121    syn match netrwMesgWarning	"^\*\*warning\*\*"
122    syn match netrwMesgError	"^\*\*error\*\*"
123    hi link netrwMesgWarning WarningMsg
124    hi link netrwMesgError   Error
125   endif
126"   call Decho("setl noma ro bh=wipe",'~'.expand("<slnum>"))
127   setl ro nomod noma bh=wipe
128
129  else
130   " (optional) netrw will show messages using echomsg.  Even if the
131   " message doesn't appear, at least it'll be recallable via :messages
132"   redraw!
133   if a:level == s:WARNING
134    echohl WarningMsg
135   elseif a:level == s:ERROR
136    echohl Error
137   endif
138
139   if type(a:msg) == 3
140     for msg in a:msg
141      unsilent echomsg level.msg
142     endfor
143   else
144    unsilent echomsg level.a:msg
145   endif
146
147"   call Decho("echomsg ***netrw*** ".a:msg,'~'.expand("<slnum>"))
148   echohl None
149  endif
150
151"  call Dret("netrw#ErrorMsg")
152endfun
153
154" ---------------------------------------------------------------------
155" s:NetrwInit: initializes variables if they haven't been defined {{{2
156"            Loosely,  varname = value.
157fun s:NetrwInit(varname,value)
158" call Decho("varname<".a:varname."> value=".a:value,'~'.expand("<slnum>"))
159  if !exists(a:varname)
160   if type(a:value) == 0
161    exe "let ".a:varname."=".a:value
162   elseif type(a:value) == 1 && a:value =~ '^[{[]'
163    exe "let ".a:varname."=".a:value
164   elseif type(a:value) == 1
165    exe "let ".a:varname."="."'".a:value."'"
166   else
167    exe "let ".a:varname."=".a:value
168   endif
169  endif
170endfun
171
172" ---------------------------------------------------------------------
173"  Netrw Constants: {{{2
174call s:NetrwInit("g:netrw_dirhist_cnt",0)
175if !exists("s:LONGLIST")
176 call s:NetrwInit("s:THINLIST",0)
177 call s:NetrwInit("s:LONGLIST",1)
178 call s:NetrwInit("s:WIDELIST",2)
179 call s:NetrwInit("s:TREELIST",3)
180 call s:NetrwInit("s:MAXLIST" ,4)
181endif
182
183" ---------------------------------------------------------------------
184" Default values for netrw's global protocol variables {{{2
185call s:NetrwInit("g:netrw_use_errorwindow",1)
186
187if !exists("g:netrw_dav_cmd")
188 if executable("cadaver")
189  let g:netrw_dav_cmd	= "cadaver"
190 elseif executable("curl")
191  let g:netrw_dav_cmd	= "curl"
192 else
193  let g:netrw_dav_cmd   = ""
194 endif
195endif
196if !exists("g:netrw_fetch_cmd")
197 if executable("fetch")
198  let g:netrw_fetch_cmd	= "fetch -o"
199 else
200  let g:netrw_fetch_cmd	= ""
201 endif
202endif
203if !exists("g:netrw_file_cmd")
204 if executable("elinks")
205  call s:NetrwInit("g:netrw_file_cmd","elinks")
206 elseif executable("links")
207  call s:NetrwInit("g:netrw_file_cmd","links")
208 endif
209endif
210if !exists("g:netrw_ftp_cmd")
211  let g:netrw_ftp_cmd	= "ftp"
212endif
213let s:netrw_ftp_cmd= g:netrw_ftp_cmd
214if !exists("g:netrw_ftp_options")
215 let g:netrw_ftp_options= "-i -n"
216endif
217if !exists("g:netrw_http_cmd")
218 if executable("elinks")
219  let g:netrw_http_cmd = "elinks"
220  call s:NetrwInit("g:netrw_http_xcmd","-source >")
221 elseif executable("links")
222  let g:netrw_http_cmd = "links"
223  call s:NetrwInit("g:netrw_http_xcmd","-source >")
224 elseif executable("curl")
225  let g:netrw_http_cmd	= "curl"
226  call s:NetrwInit("g:netrw_http_xcmd","-o")
227 elseif executable("wget")
228  let g:netrw_http_cmd	= "wget"
229  call s:NetrwInit("g:netrw_http_xcmd","-q -O")
230 elseif executable("fetch")
231  let g:netrw_http_cmd	= "fetch"
232  call s:NetrwInit("g:netrw_http_xcmd","-o")
233 else
234  let g:netrw_http_cmd	= ""
235 endif
236endif
237call s:NetrwInit("g:netrw_http_put_cmd","curl -T")
238call s:NetrwInit("g:netrw_keepj","keepj")
239call s:NetrwInit("g:netrw_rcp_cmd"  , "rcp")
240call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
241if !exists("g:netrw_scp_cmd")
242 if executable("scp")
243  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
244 elseif executable("pscp")
245  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable('c:\private.ppk')
246   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -i c:\private.ppk')
247  else
248   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
249  endif
250 else
251  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
252 endif
253endif
254
255call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
256call s:NetrwInit("g:netrw_ssh_cmd"  , "ssh")
257
258if (has("win32") || has("win95") || has("win64") || has("win16"))
259  \ && exists("g:netrw_use_nt_rcp")
260  \ && g:netrw_use_nt_rcp
261  \ && executable( $SystemRoot .'/system32/rcp.exe')
262 let s:netrw_has_nt_rcp = 1
263 let s:netrw_rcpmode    = '-b'
264else
265 let s:netrw_has_nt_rcp = 0
266 let s:netrw_rcpmode    = ''
267endif
268
269" ---------------------------------------------------------------------
270" Default values for netrw's global variables {{{2
271" Cygwin Detection ------- {{{3
272if !exists("g:netrw_cygwin")
273 if has("win32") || has("win95") || has("win64") || has("win16")
274  if  has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
275   let g:netrw_cygwin= 1
276  else
277   let g:netrw_cygwin= 0
278  endif
279 else
280  let g:netrw_cygwin= 0
281 endif
282endif
283" Default values - a-c ---------- {{{3
284call s:NetrwInit("g:netrw_alto"        , &sb)
285call s:NetrwInit("g:netrw_altv"        , &spr)
286call s:NetrwInit("g:netrw_banner"      , 1)
287call s:NetrwInit("g:netrw_browse_split", 0)
288call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro nornu")
289call s:NetrwInit("g:netrw_chgwin"      , -1)
290call s:NetrwInit("g:netrw_compress"    , "gzip")
291call s:NetrwInit("g:netrw_ctags"       , "ctags")
292if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
293 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
294 let g:netrw_cursor= g:netrw_cursorline
295endif
296call s:NetrwInit("g:netrw_cursor"      , 2)
297let s:netrw_usercul = &cursorline
298let s:netrw_usercuc = &cursorcolumn
299call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
300" Default values - d-g ---------- {{{3
301call s:NetrwInit("s:didstarstar",0)
302call s:NetrwInit("g:netrw_dirhist_cnt"      , 0)
303call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }')
304call s:NetrwInit("g:netrw_dirhistmax"       , 10)
305call s:NetrwInit("g:netrw_errorlvl"  , s:NOTE)
306call s:NetrwInit("g:netrw_fastbrowse"       , 1)
307call 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$')
308if !exists("g:netrw_ftp_list_cmd")
309 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
310  let g:netrw_ftp_list_cmd     = "ls -lF"
311  let g:netrw_ftp_timelist_cmd = "ls -tlF"
312  let g:netrw_ftp_sizelist_cmd = "ls -slF"
313 else
314  let g:netrw_ftp_list_cmd     = "dir"
315  let g:netrw_ftp_timelist_cmd = "dir"
316  let g:netrw_ftp_sizelist_cmd = "dir"
317 endif
318endif
319call s:NetrwInit("g:netrw_ftpmode",'binary')
320" Default values - h-lh ---------- {{{3
321call s:NetrwInit("g:netrw_hide",1)
322if !exists("g:netrw_ignorenetrc")
323 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
324  let g:netrw_ignorenetrc= 1
325 else
326  let g:netrw_ignorenetrc= 0
327 endif
328endif
329call s:NetrwInit("g:netrw_keepdir",1)
330if !exists("g:netrw_list_cmd")
331 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
332  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
333   " provide a pscp-based listing command
334   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
335  endif
336  if exists("g:netrw_list_cmd_options")
337   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
338  else
339   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
340  endif
341 elseif executable(g:netrw_ssh_cmd)
342  " provide a scp-based default listing command
343  if exists("g:netrw_list_cmd_options")
344   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
345  else
346   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
347  endif
348 else
349"  call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
350  let g:netrw_list_cmd= ""
351 endif
352endif
353call s:NetrwInit("g:netrw_list_hide","")
354" Default values - lh-lz ---------- {{{3
355if exists("g:netrw_local_copycmd")
356 let g:netrw_localcopycmd= g:netrw_local_copycmd
357 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_copycmd is deprecated in favor of g:netrw_localcopycmd",84)
358endif
359if !exists("g:netrw_localcmdshell")
360 let g:netrw_localcmdshell= ""
361endif
362if !exists("g:netrw_localcopycmd")
363 if has("win32") || has("win95") || has("win64") || has("win16")
364  if g:netrw_cygwin
365   let g:netrw_localcopycmd= "cp"
366  else
367   let g:netrw_localcopycmd= expand("$COMSPEC")." /c copy"
368  endif
369 elseif has("unix") || has("macunix")
370  let g:netrw_localcopycmd= "cp"
371 else
372  let g:netrw_localcopycmd= ""
373 endif
374endif
375if !exists("g:netrw_localcopydircmd")
376 if has("win32") || has("win95") || has("win64") || has("win16")
377  if g:netrw_cygwin
378   let g:netrw_localcopydircmd= "cp -R"
379  else
380   let g:netrw_localcopycmd= expand("$COMSPEC")." /c xcopy /e /c /h /i /k"
381  endif
382 elseif has("unix") || has("macunix")
383  let g:netrw_localcopydircmd= "cp -R"
384 else
385  let g:netrw_localcopycmd= ""
386 endif
387endif
388if exists("g:netrw_local_mkdir")
389 let g:netrw_localmkdir= g:netrw_local_mkdir
390 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
391endif
392if has("win32") || has("win95") || has("win64") || has("win16")
393  if g:netrw_cygwin
394   call s:NetrwInit("g:netrw_localmkdir","mkdir")
395  else
396   let g:netrw_localmkdir= expand("$COMSPEC")." /c mkdir"
397  endif
398else
399 call s:NetrwInit("g:netrw_localmkdir","mkdir")
400endif
401call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
402if exists("g:netrw_local_movecmd")
403 let g:netrw_localmovecmd= g:netrw_local_movecmd
404 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
405endif
406if !exists("g:netrw_localmovecmd")
407 if has("win32") || has("win95") || has("win64") || has("win16")
408  if g:netrw_cygwin
409   let g:netrw_localmovecmd= "mv"
410  else
411   let g:netrw_localmovecmd= expand("$COMSPEC")." /c move"
412  endif
413 elseif has("unix") || has("macunix")
414  let g:netrw_localmovecmd= "mv"
415 else
416  let g:netrw_localmovecmd= ""
417 endif
418endif
419if exists("g:netrw_local_rmdir")
420 let g:netrw_localrmdir= g:netrw_local_rmdir
421 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_rmdir is deprecated in favor of g:netrw_localrmdir",86)
422endif
423if has("win32") || has("win95") || has("win64") || has("win16")
424  if g:netrw_cygwin
425   call s:NetrwInit("g:netrw_localrmdir","rmdir")
426  else
427   let g:netrw_localrmdir= expand("$COMSPEC")." /c rmdir"
428  endif
429else
430 call s:NetrwInit("g:netrw_localrmdir","rmdir")
431endif
432call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
433" sanity checks
434if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
435 let g:netrw_liststyle= s:THINLIST
436endif
437if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
438 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
439endif
440" Default values - m-r ---------- {{{3
441call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
442call s:NetrwInit("g:netrw_maxfilenamelen", 32)
443call s:NetrwInit("g:netrw_menu"          , 1)
444call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
445call s:NetrwInit("g:netrw_mousemaps"     , (exists("+mouse") && &mouse =~ '[anh]'))
446call s:NetrwInit("g:netrw_retmap"        , 0)
447if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
448 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
449elseif has("win32") || has("win95") || has("win64") || has("win16")
450 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
451else
452 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
453endif
454call s:NetrwInit("g:netrw_preview"       , 0)
455call s:NetrwInit("g:netrw_scpport"       , "-P")
456call s:NetrwInit("g:netrw_servername"    , "NETRWSERVER")
457call s:NetrwInit("g:netrw_sshport"       , "-p")
458call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
459call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
460call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
461call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
462" Default values - q-s ---------- {{{3
463call s:NetrwInit("g:netrw_quickhelp",0)
464let s:QuickHelp= ["-:go up dir  D:delete  R:rename  s:sort-by  x:special",
465   \              "(create new)  %:file  d:directory",
466   \              "(windows split&open) o:horz  v:vert  p:preview",
467   \              "i:style  qf:file info  O:obtain  r:reverse",
468   \              "(marks)  mf:mark file  mt:set target  mm:move  mc:copy",
469   \              "(bookmarks)  mb:make  mB:delete  qb:list  gb:go to",
470   \              "(history)  qb:list  u:go up  U:go down",
471   \              "(targets)  mt:target Tb:use bookmark  Th:use history"]
472" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
473call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
474if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
475 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
476else
477 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
478endif
479call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
480call s:NetrwInit("g:netrw_sort_options"  , "")
481call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
482if !exists("g:netrw_sort_sequence")
483 if has("unix")
484  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
485 else
486  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
487 endif
488endif
489call s:NetrwInit("g:netrw_special_syntax"   , 0)
490call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
491call s:NetrwInit("g:netrw_use_noswf"        , 1)
492" Default values - t-w ---------- {{{3
493call s:NetrwInit("g:netrw_timefmt","%c")
494if !exists("g:netrw_xstrlen")
495 if exists("g:Align_xstrlen")
496  let g:netrw_xstrlen= g:Align_xstrlen
497 elseif exists("g:drawit_xstrlen")
498  let g:netrw_xstrlen= g:drawit_xstrlen
499 elseif &enc == "latin1" || !has("multi_byte")
500  let g:netrw_xstrlen= 0
501 else
502  let g:netrw_xstrlen= 1
503 endif
504endif
505call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
506call s:NetrwInit("g:netrw_win95ftp",1)
507call s:NetrwInit("g:netrw_winsize",50)
508call s:NetrwInit("g:netrw_wiw",1)
509if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
510" ---------------------------------------------------------------------
511" Default values for netrw's script variables: {{{2
512call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
513if has("win32") || has("win95") || has("win64") || has("win16")
514 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
515else
516 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
517endif
518call s:NetrwInit("g:netrw_menu_escape",'.&? \')
519call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
520call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
521if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
522 let s:treedepthstring= "│ "
523else
524 let s:treedepthstring= "| "
525endif
526
527" BufEnter event ignored by decho when following variable is true
528"  Has a side effect that doau BufReadPost doesn't work, so
529"  files read by network transfer aren't appropriately highlighted.
530"let g:decho_bufenter = 1	"Decho
531
532" ======================
533"  Netrw Initialization: {{{1
534" ======================
535if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
536" call Decho("installed beval events",'~'.expand("<slnum>"))
537 let &l:bexpr = "netrw#BalloonHelp()"
538 au FileType netrw	setl beval
539 au WinLeave *		if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
540 au VimEnter * 		let s:initbeval= &beval
541"else " Decho
542" if v:version < 700           | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>"))     | endif
543" if !has("balloon_eval")      | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>"))        | endif
544" if exists("s:initbeval")     | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>"))                | endif
545" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>"))            | endif
546" if !has("syntax")            | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
547" if exists("g:syntax_on")     | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>"))                | endif
548endif
549au WinEnter *	if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
550
551if g:netrw_keepj =~ "keepj"
552 com! -nargs=*	NetrwKeepj	keepj <args>
553else
554 let g:netrw_keepj= ""
555 com! -nargs=*	NetrwKeepj	<args>
556endif
557
558" ==============================
559"  Netrw Utility Functions: {{{1
560" ==============================
561
562" ---------------------------------------------------------------------
563" netrw#BalloonHelp: {{{2
564if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
565" call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
566 fun! netrw#BalloonHelp()
567   if &ft != "netrw"
568    return ""
569   endif
570   if !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
571    let mesg= ""
572   elseif     v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
573    let mesg = "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
574   elseif     getline(v:beval_lnum) =~ '^"\s*/'
575    let mesg = "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
576   elseif     v:beval_text == "Sorted" || v:beval_text == "by"
577    let mesg = 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
578   elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
579    let mesg = "S: edit sorting sequence"
580   elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
581    let mesg = "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
582   elseif v:beval_text == "Quick" || v:beval_text == "Help"
583    let mesg = "Help: press <F1>"
584   elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
585    let mesg = "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
586   else
587    let mesg= ""
588   endif
589   return mesg
590 endfun
591"else " Decho
592" if v:version < 700            |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
593" if !has("balloon_eval")       |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>"))       |endif
594" if !has("syntax")             |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>"))                  |endif
595" if !exists("g:syntax_on")     |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>"))                  |endif
596" if  exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>"))           |endif
597endif
598
599" ------------------------------------------------------------------------
600" netrw#Explore: launch the local browser in the directory of the current file {{{2
601"          indx:  == -1: Nexplore
602"                 == -2: Pexplore
603"                 ==  +: this is overloaded:
604"                      * If Nexplore/Pexplore is in use, then this refers to the
605"                        indx'th item in the w:netrw_explore_list[] of items which
606"                        matched the */pattern **/pattern *//pattern **//pattern
607"                      * If Hexplore or Vexplore, then this will override
608"                        g:netrw_winsize to specify the qty of rows or columns the
609"                        newly split window should have.
610"          dosplit==0: the window will be split iff the current file has been modified and hidden not set
611"          dosplit==1: the window will be split before running the local browser
612"          style == 0: Explore     style == 1: Explore!
613"                == 2: Hexplore    style == 3: Hexplore!
614"                == 4: Vexplore    style == 5: Vexplore!
615"                == 6: Texplore
616fun! netrw#Explore(indx,dosplit,style,...)
617"  call Dfunc("netrw#Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.",a:1<".a:1.">) &modified=".&modified." modifiable=".&modifiable." a:0=".a:0." win#".winnr()." buf#".bufnr("%"))
618"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
619  if !exists("b:netrw_curdir")
620   let b:netrw_curdir= getcwd()
621"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
622  endif
623
624  " record current file for Rexplore's benefit
625  if &ft != "netrw"
626   let w:netrw_rexfile= expand("%:p")
627  endif
628
629  " record current directory
630  let curdir     = simplify(b:netrw_curdir)
631  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
632  if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
633   let curdir= substitute(curdir,'\','/','g')
634  endif
635"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">",'~'.expand("<slnum>"))
636
637  " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
638  " will end up with backslashes here.  Solution: strip off backslashes that precede white space and
639  " try Explore again.
640  if a:0 > 0
641"   call Decho('considering retry: a:1<'.a:1.'>: '.
642     \ ((a:1 =~ "\\\s")?                   'has backslash whitespace' : 'does not have backslash whitespace').', '.
643     \ ((filereadable(s:NetrwFile(a:1)))?  'is readable'              : 'is not readable').', '.
644     \ ((isdirectory(s:NetrwFile(a:1))))?  'is a directory'           : 'is not a directory',
645     \ '~'.expand("<slnum>"))
646   if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
647"    call Decho("re-trying Explore with <".substitute(a:1,'\\\(\s\)','\1','g').">",'~'.expand("<slnum>"))
648    call netrw#Explore(a:indx,a:dosplit,a:style,substitute(a:1,'\\\(\s\)','\1','g'))
649"    call Dret("netrw#Explore : returning from retry")
650    return
651"   else " Decho
652"    call Decho("retry not needed",'~'.expand("<slnum>"))
653   endif
654  endif
655
656  " save registers
657  if has("clipboard")
658   sil! let keepregstar = @*
659   sil! let keepregplus = @+
660  endif
661  sil! let keepregslash= @/
662
663  " if   dosplit
664  " -or- file has been modified AND file not hidden when abandoned
665  " -or- Texplore used
666  if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
667"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified",'~'.expand("<slnum>"))
668   call s:SaveWinVars()
669   let winsz= g:netrw_winsize
670   if a:indx > 0
671    let winsz= a:indx
672   endif
673
674   if a:style == 0      " Explore, Sexplore
675"    call Decho("style=0: Explore or Sexplore",'~'.expand("<slnum>"))
676    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
677    if winsz == 0|let winsz= ""|endif
678    exe "noswapfile ".winsz."wincmd s"
679"    call Decho("exe noswapfile ".winsz."wincmd s",'~'.expand("<slnum>"))
680
681   elseif a:style == 1  "Explore!, Sexplore!
682"    call Decho("style=1: Explore! or Sexplore!",'~'.expand("<slnum>"))
683    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
684    if winsz == 0|let winsz= ""|endif
685    exe "keepalt noswapfile ".winsz."wincmd v"
686"    call Decho("exe keepalt noswapfile ".winsz."wincmd v",'~'.expand("<slnum>"))
687
688   elseif a:style == 2  " Hexplore
689"    call Decho("style=2: Hexplore",'~'.expand("<slnum>"))
690    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
691    if winsz == 0|let winsz= ""|endif
692    exe "keepalt noswapfile bel ".winsz."wincmd s"
693"    call Decho("exe keepalt noswapfile bel ".winsz."wincmd s",'~'.expand("<slnum>"))
694
695   elseif a:style == 3  " Hexplore!
696"    call Decho("style=3: Hexplore!",'~'.expand("<slnum>"))
697    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
698    if winsz == 0|let winsz= ""|endif
699    exe "keepalt noswapfile abo ".winsz."wincmd s"
700"    call Decho("exe keepalt noswapfile abo ".winsz."wincmd s",'~'.expand("<slnum>"))
701
702   elseif a:style == 4  " Vexplore
703"    call Decho("style=4: Vexplore",'~'.expand("<slnum>"))
704    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
705    if winsz == 0|let winsz= ""|endif
706    exe "keepalt noswapfile lefta ".winsz."wincmd v"
707"    call Decho("exe keepalt noswapfile lefta ".winsz."wincmd v",'~'.expand("<slnum>"))
708
709   elseif a:style == 5  " Vexplore!
710"    call Decho("style=5: Vexplore!",'~'.expand("<slnum>"))
711    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
712    if winsz == 0|let winsz= ""|endif
713    exe "keepalt noswapfile rightb ".winsz."wincmd v"
714"    call Decho("exe keepalt noswapfile rightb ".winsz."wincmd v",'~'.expand("<slnum>"))
715
716   elseif a:style == 6  " Texplore
717    call s:SaveBufVars()
718"    call Decho("style  = 6: Texplore",'~'.expand("<slnum>"))
719    exe "keepalt tabnew ".fnameescape(curdir)
720"    call Decho("exe keepalt tabnew ".fnameescape(curdir),'~'.expand("<slnum>"))
721    call s:RestoreBufVars()
722   endif
723   call s:RestoreWinVars()
724"  else " Decho
725"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6",'~'.expand("<slnum>"))
726  endif
727  NetrwKeepj norm! 0
728
729  if a:0 > 0
730"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">",'~'.expand("<slnum>"))
731   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
732"    call Decho("..case a:1<".a:1.">: starts with ~ and unix or cygwin",'~'.expand("<slnum>"))
733    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
734"    call Decho("..using dirname<".dirname.">  (case: ~ && unix||cygwin)",'~'.expand("<slnum>"))
735   elseif a:1 == '.'
736"    call Decho("..case a:1<".a:1.">: matches .",'~'.expand("<slnum>"))
737    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
738    if dirname !~ '/$'
739     let dirname= dirname."/"
740    endif
741"    call Decho("..using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")",'~'.expand("<slnum>"))
742   elseif a:1 =~ '\$'
743"    call Decho("..case a:1<".a:1.">: matches ending $",'~'.expand("<slnum>"))
744    let dirname= simplify(expand(a:1))
745"    call Decho("..using user-specified dirname<".dirname."> with $env-var",'~'.expand("<slnum>"))
746   elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
747"    call Decho("..case a:1<".a:1.">: other, not pattern or filepattern",'~'.expand("<slnum>"))
748    let dirname= simplify(a:1)
749"    call Decho("..using user-specified dirname<".dirname.">",'~'.expand("<slnum>"))
750   else
751"    call Decho("..case a:1: pattern or filepattern",'~'.expand("<slnum>"))
752    let dirname= a:1
753   endif
754  else
755   " clear explore
756"   call Decho("case a:0=".a:0.": clearing Explore list",'~'.expand("<slnum>"))
757   call s:NetrwClearExplore()
758"   call Dret("netrw#Explore : cleared list")
759   return
760  endif
761
762"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
763  if dirname =~ '\.\./\=$'
764   let dirname= simplify(fnamemodify(dirname,':p:h'))
765  elseif dirname =~ '\.\.' || dirname == '.'
766   let dirname= simplify(fnamemodify(dirname,':p'))
767  endif
768"  call Decho("dirname<".dirname.">  (after simplify)",'~'.expand("<slnum>"))
769
770  if dirname =~ '^\*//'
771   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
772"   call Decho("case starpat=1: Explore *//pattern",'~'.expand("<slnum>"))
773   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
774   let starpat= 1
775"   call Decho("..Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
776   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
777
778  elseif dirname =~ '^\*\*//'
779   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
780"   call Decho("case starpat=2: Explore **//pattern",'~'.expand("<slnum>"))
781   let pattern= substitute(dirname,'^\*\*//','','')
782   let starpat= 2
783"   call Decho("..Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
784
785  elseif dirname =~ '/\*\*/'
786   " handle .../**/.../filepat
787"   call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
788   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
789   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
790    let b:netrw_curdir = prefixdir
791   else
792    let b:netrw_curdir= getcwd().'/'.prefixdir
793   endif
794   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
795   let starpat= 4
796"   call Decho("..pwd<".getcwd()."> dirname<".dirname.">",'~'.expand("<slnum>"))
797"   call Decho("..case Explore ../**/../filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
798
799  elseif dirname =~ '^\*/'
800   " case starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
801   let starpat= 3
802"   call Decho("case starpat=3: Explore */filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
803
804  elseif dirname=~ '^\*\*/'
805   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
806   let starpat= 4
807"   call Decho("case starpat=4: Explore **/filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
808
809  else
810   let starpat= 0
811"   call Decho("case starpat=0: default",'~'.expand("<slnum>"))
812  endif
813
814  if starpat == 0 && a:indx >= 0
815   " [Explore Hexplore Vexplore Sexplore] [dirname]
816"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname.">, handles Explore Hexplore Vexplore Sexplore",'~'.expand("<slnum>"))
817   if dirname == ""
818    let dirname= curfiledir
819"    call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>"))
820   endif
821   if dirname =~ '^scp://' || dirname =~ '^ftp://'
822    call netrw#Nread(2,dirname)
823   else
824    if dirname == ""
825     let dirname= getcwd()
826    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
827     " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
828     " depending on whether backslashes have been converted to forward slashes by earlier code).
829     if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
830      let dirname= b:netrw_curdir."/".dirname
831     endif
832    elseif dirname !~ '^/'
833     let dirname= b:netrw_curdir."/".dirname
834    endif
835"    call Decho("..calling LocalBrowseCheck(dirname<".dirname.">)",'~'.expand("<slnum>"))
836    call netrw#LocalBrowseCheck(dirname)
837"    call Decho(" modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
838"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
839   endif
840   if exists("w:netrw_bannercnt")
841    " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
842    " If one wants to return the same place in the netrw window, use :Rex instead.
843    exe w:netrw_bannercnt
844   endif
845
846"   call Decho("curdir<".curdir.">",'~'.expand("<slnum>"))
847   " ---------------------------------------------------------------------
848   " Jan 24, 2013: not sure why the following was present.  See P08-Ingelrest
849"   if has("win32") || has("win95") || has("win64") || has("win16")
850"    NetrwKeepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
851"   else
852"    NetrwKeepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
853"   endif
854   " ---------------------------------------------------------------------
855
856  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
857  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
858  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
859  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
860  elseif a:indx <= 0
861   " Nexplore, Pexplore, Explore: handle starpat
862"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx,'~'.expand("<slnum>"))
863   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
864"    call Decho("..set up <s-up> and <s-down> maps",'~'.expand("<slnum>"))
865    let s:didstarstar= 1
866    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
867    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
868   endif
869
870   if has("path_extra")
871"    call Decho("..starpat=".starpat.": has +path_extra",'~'.expand("<slnum>"))
872    if !exists("w:netrw_explore_indx")
873     let w:netrw_explore_indx= 0
874    endif
875
876    let indx = a:indx
877"    call Decho("..starpat=".starpat.": set indx= [a:indx=".indx."]",'~'.expand("<slnum>"))
878
879    if indx == -1
880     " Nexplore
881"     call Decho("..case Nexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
882     if !exists("w:netrw_explore_list") " sanity check
883      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
884      if has("clipboard")
885       sil! let @* = keepregstar
886       sil! let @+ = keepregstar
887      endif
888      sil! let @/ = keepregslash
889"      call Dret("netrw#Explore")
890      return
891     endif
892     let indx= w:netrw_explore_indx
893     if indx < 0                        | let indx= 0                           | endif
894     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
895     let curfile= w:netrw_explore_list[indx]
896"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
897     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
898      let indx= indx + 1
899"      call Decho("....indx=".indx." (Nexplore while loop)",'~'.expand("<slnum>"))
900     endwhile
901     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
902"     call Decho("....Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
903
904    elseif indx == -2
905     " Pexplore
906"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
907     if !exists("w:netrw_explore_list") " sanity check
908      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
909      if has("clipboard")
910       sil! let @* = keepregstar
911       sil! let @+ = keepregstar
912      endif
913      sil! let @/ = keepregslash
914"      call Dret("netrw#Explore")
915      return
916     endif
917     let indx= w:netrw_explore_indx
918     if indx < 0                        | let indx= 0                           | endif
919     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
920     let curfile= w:netrw_explore_list[indx]
921"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
922     while indx >= 0 && curfile == w:netrw_explore_list[indx]
923      let indx= indx - 1
924"      call Decho("....indx=".indx." (Pexplore while loop)",'~'.expand("<slnum>"))
925     endwhile
926     if indx < 0                        | let indx= 0                           | endif
927"     call Decho("....Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
928
929    else
930     " Explore -- initialize
931     " build list of files to Explore with Nexplore/Pexplore
932"     call Decho("..starpat=".starpat.": case Explore: initialize (indx=".indx.")",'~'.expand("<slnum>"))
933     NetrwKeepj keepalt call s:NetrwClearExplore()
934     let w:netrw_explore_indx= 0
935     if !exists("b:netrw_curdir")
936      let b:netrw_curdir= getcwd()
937     endif
938"     call Decho("....starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
939
940     " switch on starpat to build the w:netrw_explore_list of files
941     if starpat == 1
942      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
943"      call Decho("..case starpat=".starpat.": build *//pattern list  (curdir-only srch for files containing pattern)  &hls=".&hls,'~'.expand("<slnum>"))
944"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
945      try
946       exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
947      catch /^Vim\%((\a\+)\)\=:E480/
948       keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
949"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
950       return
951      endtry
952      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
953      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
954
955     elseif starpat == 2
956      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
957"      call Decho("..case starpat=".starpat.": build **//pattern list  (recursive descent files containing pattern)",'~'.expand("<slnum>"))
958"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
959      try
960       exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
961      catch /^Vim\%((\a\+)\)\=:E480/
962       keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
963       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
964       if has("clipboard")
965        sil! let @* = keepregstar
966        sil! let @+ = keepregstar
967       endif
968       sil! let @/ = keepregslash
969"       call Dret("netrw#Explore : no files matched pattern")
970       return
971      endtry
972      let s:netrw_curdir       = b:netrw_curdir
973      let w:netrw_explore_list = getqflist()
974      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
975      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
976
977     elseif starpat == 3
978      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
979"      call Decho("..case starpat=".starpat.": build */filepat list  (curdir-only srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
980      let filepat= substitute(dirname,'^\*/','','')
981      let filepat= substitute(filepat,'^[%#<]','\\&','')
982"      call Decho("....b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
983"      call Decho("....filepat<".filepat.">",'~'.expand("<slnum>"))
984      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
985      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
986
987     elseif starpat == 4
988      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
989"      call Decho("..case starpat=".starpat.": build **/filepat list  (recursive descent srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
990      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
991      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
992     endif " switch on starpat to build w:netrw_explore_list
993
994     let w:netrw_explore_listlen = len(w:netrw_explore_list)
995"     call Decho("....w:netrw_explore_list<".string(w:netrw_explore_list).">",'~'.expand("<slnum>"))
996"     call Decho("....w:netrw_explore_listlen=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
997
998     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
999      keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1000      if has("clipboard")
1001       sil! let @* = keepregstar
1002       sil! let @+ = keepregstar
1003      endif
1004      sil! let @/ = keepregslash
1005"      call Dret("netrw#Explore : no files matched")
1006      return
1007     endif
1008    endif  " if indx ... endif
1009
1010    " NetrwStatusLine support - for exploring support
1011    let w:netrw_explore_indx= indx
1012"    call Decho("....w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1013
1014    " wrap the indx around, but issue a note
1015    if indx >= w:netrw_explore_listlen || indx < 0
1016"     call Decho("....wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")",'~'.expand("<slnum>"))
1017     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1018     let w:netrw_explore_indx= indx
1019     keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
1020    endif
1021
1022    exe "let dirfile= w:netrw_explore_list[".indx."]"
1023"    call Decho("....dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">",'~'.expand("<slnum>"))
1024    let newdir= substitute(dirfile,'/[^/]*$','','e')
1025"    call Decho("....newdir<".newdir.">",'~'.expand("<slnum>"))
1026
1027"    call Decho("....calling LocalBrowseCheck(newdir<".newdir.">)",'~'.expand("<slnum>"))
1028    call netrw#LocalBrowseCheck(newdir)
1029    if !exists("w:netrw_liststyle")
1030     let w:netrw_liststyle= g:netrw_liststyle
1031    endif
1032    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1033     keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1034    else
1035     keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1036    endif
1037    let w:netrw_explore_mtchcnt = indx + 1
1038    let w:netrw_explore_bufnr   = bufnr("%")
1039    let w:netrw_explore_line    = line(".")
1040    keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
1041"    call Decho("....explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line,'~'.expand("<slnum>"))
1042
1043   else
1044"    call Decho("..your vim does not have +path_extra",'~'.expand("<slnum>"))
1045    if !exists("g:netrw_quiet")
1046     keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1047    endif
1048    if has("clipboard")
1049     sil! let @* = keepregstar
1050     sil! let @+ = keepregstar
1051    endif
1052    sil! let @/ = keepregslash
1053"    call Dret("netrw#Explore : missing +path_extra")
1054    return
1055   endif
1056
1057  else
1058"   call Decho("..default case: Explore newdir<".dirname.">",'~'.expand("<slnum>"))
1059   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1060    sil! unlet w:netrw_treedict
1061    sil! unlet w:netrw_treetop
1062   endif
1063   let newdir= dirname
1064   if !exists("b:netrw_curdir")
1065    NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1066   else
1067    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
1068   endif
1069  endif
1070
1071  " visual display of **/ **// */ Exploration files
1072"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"),'~'.expand("<slnum>"))
1073"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">",'~'.expand("<slnum>"))
1074  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
1075"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"),'~'.expand("<slnum>"))
1076   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1077    " only update match list when current directory isn't the same as before
1078"    call Decho("only update match list when current directory not the same as before",'~'.expand("<slnum>"))
1079    let s:explore_prvdir = b:netrw_curdir
1080    let s:explore_match  = ""
1081    let dirlen           = strlen(b:netrw_curdir)
1082    if b:netrw_curdir !~ '/$'
1083     let dirlen= dirlen + 1
1084    endif
1085    let prvfname= ""
1086    for fname in w:netrw_explore_list
1087"     call Decho("fname<".fname.">",'~'.expand("<slnum>"))
1088     if fname =~ '^'.b:netrw_curdir
1089      if s:explore_match == ""
1090       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1091      else
1092       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1093      endif
1094     elseif fname !~ '^/' && fname != prvfname
1095      if s:explore_match == ""
1096       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1097      else
1098       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1099      endif
1100     endif
1101     let prvfname= fname
1102    endfor
1103"    call Decho("explore_match<".s:explore_match.">",'~'.expand("<slnum>"))
1104    exe "2match netrwMarkFile /".s:explore_match."/"
1105   endif
1106   echo "<s-up>==Pexplore  <s-down>==Nexplore"
1107  else
1108   2match none
1109   if exists("s:explore_match")  | unlet s:explore_match  | endif
1110   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
1111   echo " "
1112"   call Decho("cleared explore match list",'~'.expand("<slnum>"))
1113  endif
1114
1115  " since Explore may be used to initialize netrw's browser,
1116  " there's no danger of a late FocusGained event on initialization.
1117  " Consequently, set s:netrw_events to 2.
1118  let s:netrw_events= 2
1119  if has("clipboard")
1120   sil! let @* = keepregstar
1121   sil! let @+ = keepregstar
1122  endif
1123  sil! let @/ = keepregslash
1124"  call Dret("netrw#Explore : @/<".@/.">")
1125endfun
1126
1127" ---------------------------------------------------------------------
1128" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
1129fun! netrw#Lexplore(count,rightside,...)
1130"  call Dfunc("netrw#Lexplore(count=".a:count."rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
1131  let curwin= winnr()
1132
1133  if a:0 > 0 && a:1 != ""
1134   " if a netrw window is already on the left-side of the tab
1135   " and a directory has been specified, explore with that
1136   " directory.
1137   let a1 = expand(a:1)
1138"   call Decho("a:1<".a:1.">  curwin#".curwin,'~'.expand("<slnum>"))
1139   exe "1wincmd w"
1140   if &ft == "netrw"
1141"    call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
1142    exe "Explore ".fnameescape(a1)
1143    exe curwin."wincmd w"
1144    if exists("t:netrw_lexposn")
1145"     call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
1146     unlet t:netrw_lexposn
1147    endif
1148"    call Dret("netrw#Lexplore")
1149    return
1150   endif
1151   exe curwin."wincmd w"
1152  else
1153   let a1= ""
1154  endif
1155
1156  if exists("t:netrw_lexbufnr")
1157   " check if t:netrw_lexbufnr refers to a netrw window
1158   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1159  else
1160   let lexwinnr= 0
1161  endif
1162
1163  if lexwinnr > 0
1164   " close down netrw explorer window
1165"  call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
1166   exe lexwinnr."wincmd w"
1167   let g:netrw_winsize = -winwidth(0)
1168   let t:netrw_lexposn = netrw#SavePosn()
1169"   call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
1170   close
1171   if lexwinnr < curwin
1172    let curwin= curwin - 1
1173   endif
1174   exe curwin."wincmd w"
1175   unlet t:netrw_lexbufnr
1176
1177  else
1178   " open netrw explorer window
1179"   call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
1180   exe "1wincmd w"
1181   let keep_altv    = g:netrw_altv
1182   let g:netrw_altv = 0
1183   if a:count != 0
1184    let netrw_winsize   = g:netrw_winsize
1185    let g:netrw_winsize = a:count
1186   endif
1187   let curfile= expand("%")
1188"   call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
1189   exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1190   if a:0 > 0 && a1 != ""
1191"    call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
1192    exe "Explore ".fnameescape(a1)
1193   elseif curfile =~ '^\a\{3,}://'
1194"    call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
1195    exe "Explore ".substitute(curfile,'[^/\\]*$','','')
1196   else
1197"    call Decho("case 3: Explore .",'~'.expand("<slnum>"))
1198    Explore .
1199   endif
1200   if a:count != 0
1201    let g:netrw_winsize = netrw_winsize
1202   endif
1203   setlocal winfixwidth
1204   let g:netrw_altv     = keep_altv
1205   let t:netrw_lexbufnr = bufnr("%")
1206   if exists("t:netrw_lexposn")
1207"    call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1208    call netrw#RestorePosn(t:netrw_lexposn)
1209    unlet t:netrw_lexposn
1210   endif
1211  endif
1212
1213  " set up default window for editing via <cr>
1214  if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
1215   if a:rightside
1216    let g:netrw_chgwin= 1
1217   else
1218    let g:netrw_chgwin= 2
1219   endif
1220  endif
1221
1222"  call Dret("netrw#Lexplore")
1223endfun
1224
1225" ---------------------------------------------------------------------
1226" netrw#Clean: remove netrw {{{2
1227" supports :NetrwClean  -- remove netrw from first directory on runtimepath
1228"          :NetrwClean! -- remove netrw from all directories on runtimepath
1229fun! netrw#Clean(sys)
1230"  call Dfunc("netrw#Clean(sys=".a:sys.")")
1231
1232  if a:sys
1233   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
1234  else
1235   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
1236  endif
1237"  call Decho("choice=".choice,'~'.expand("<slnum>"))
1238  let diddel= 0
1239  let diddir= ""
1240
1241  if choice == 1
1242   for dir in split(&rtp,',')
1243    if filereadable(dir."/plugin/netrwPlugin.vim")
1244"     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1245     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
1246     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1247     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
1248     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
1249     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
1250     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
1251     let diddir= dir
1252     let diddel= diddel + 1
1253     if !a:sys|break|endif
1254    endif
1255   endfor
1256  endif
1257
1258   echohl WarningMsg
1259  if diddel == 0
1260   echomsg "netrw is either not installed or not removable"
1261  elseif diddel == 1
1262   echomsg "removed one copy of netrw from <".diddir.">"
1263  else
1264   echomsg "removed ".diddel." copies of netrw"
1265  endif
1266   echohl None
1267
1268"  call Dret("netrw#Clean")
1269endfun
1270
1271" ---------------------------------------------------------------------
1272" netrw#MakeTgt: make a target out of the directory name provided {{{2
1273fun! netrw#MakeTgt(dname)
1274"  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1275   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
1276  let svpos               = netrw#SavePosn()
1277  let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
1278"  call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
1279  if s:netrwmftgt_islocal
1280   let netrwmftgt= simplify(a:dname)
1281  else
1282   let netrwmftgt= a:dname
1283  endif
1284  if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
1285   " re-selected target, so just clear it
1286   unlet s:netrwmftgt s:netrwmftgt_islocal
1287  else
1288   let s:netrwmftgt= netrwmftgt
1289  endif
1290  if g:netrw_fastbrowse <= 1
1291   call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
1292  endif
1293  call netrw#RestorePosn(svpos)
1294"  call Dret("netrw#MakeTgt")
1295endfun
1296
1297" ---------------------------------------------------------------------
1298" netrw#Obtain: {{{2
1299"   netrw#Obtain(islocal,fname[,tgtdirectory])
1300"     islocal=0  obtain from remote source
1301"            =1  obtain from local source
1302"     fname  :   a filename or a list of filenames
1303"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
1304fun! netrw#Obtain(islocal,fname,...)
1305"  call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
1306  " NetrwStatusLine support - for obtaining support
1307
1308  if type(a:fname) == 1
1309   let fnamelist= [ a:fname ]
1310  elseif type(a:fname) == 3
1311   let fnamelist= a:fname
1312  else
1313   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1314"   call Dret("netrw#Obtain")
1315   return
1316  endif
1317"  call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
1318  if a:0 > 0
1319   let tgtdir= a:1
1320  else
1321   let tgtdir= getcwd()
1322  endif
1323"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
1324
1325  if exists("b:netrw_islocal") && b:netrw_islocal
1326   " obtain a file from local b:netrw_curdir to (local) tgtdir
1327"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1328   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1329    let topath= s:ComposePath(tgtdir,"")
1330    if (has("win32") || has("win95") || has("win64") || has("win16"))
1331     " transfer files one at time
1332"     call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1333     for fname in fnamelist
1334"      call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1335      call system(g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1336      if v:shell_error != 0
1337       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1338"       call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1339       return
1340      endif
1341     endfor
1342    else
1343     " transfer files with one command
1344"     call Decho("transfer files with one command",'~'.expand("<slnum>"))
1345     let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1346"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1347     call system(g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1348     if v:shell_error != 0
1349      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1350"      call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1351      return
1352     endif
1353    endif
1354   elseif !exists("b:netrw_curdir")
1355    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
1356   else
1357    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
1358   endif
1359
1360  else
1361   " obtain files from remote b:netrw_curdir to local tgtdir
1362"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1363   if type(a:fname) == 1
1364    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
1365   endif
1366   call s:NetrwMethod(b:netrw_curdir)
1367
1368   if b:netrw_method == 4
1369    " obtain file using scp
1370"    call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1371    if exists("g:netrw_port") && g:netrw_port != ""
1372     let useport= " ".g:netrw_scpport." ".g:netrw_port
1373    else
1374     let useport= ""
1375    endif
1376    if b:netrw_fname =~ '/'
1377     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1378    else
1379     let path= ""
1380    endif
1381    let filelist= join(map(deepcopy(fnamelist),'s:ShellEscape(g:netrw_machine.":".path.v:val,1)'))
1382    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
1383
1384   elseif b:netrw_method == 2
1385    " obtain file using ftp + .netrc
1386"     call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1387     call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1388     let tmpbufnr= bufnr("%")
1389     setl ff=unix
1390     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1391      NetrwKeepj put =g:netrw_ftpmode
1392"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1393     endif
1394
1395     if exists("b:netrw_fname") && b:netrw_fname != ""
1396      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1397"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1398     endif
1399
1400     if exists("g:netrw_ftpextracmd")
1401      NetrwKeepj put =g:netrw_ftpextracmd
1402"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1403     endif
1404     for fname in fnamelist
1405      call setline(line("$")+1,'get "'.fname.'"')
1406"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1407     endfor
1408     if exists("g:netrw_port") && g:netrw_port != ""
1409      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1410     else
1411      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1412     endif
1413     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1414     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1415      let debugkeep= &debug
1416      setl debug=msg
1417      call netrw#ErrorMsg(s:ERROR,getline(1),4)
1418      let &debug= debugkeep
1419     endif
1420
1421   elseif b:netrw_method == 3
1422    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1423"    call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1424    call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1425    let tmpbufnr= bufnr("%")
1426    setl ff=unix
1427
1428    if exists("g:netrw_port") && g:netrw_port != ""
1429     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1430"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1431    else
1432     NetrwKeepj put ='open '.g:netrw_machine
1433"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1434    endif
1435
1436    if exists("g:netrw_uid") && g:netrw_uid != ""
1437     if exists("g:netrw_ftp") && g:netrw_ftp == 1
1438      NetrwKeepj put =g:netrw_uid
1439"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1440      if exists("s:netrw_passwd") && s:netrw_passwd != ""
1441       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1442      endif
1443"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1444     elseif exists("s:netrw_passwd")
1445      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1446"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1447     endif
1448    endif
1449
1450    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1451     NetrwKeepj put =g:netrw_ftpmode
1452"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1453    endif
1454
1455    if exists("b:netrw_fname") && b:netrw_fname != ""
1456     NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1457"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1458    endif
1459
1460    if exists("g:netrw_ftpextracmd")
1461     NetrwKeepj put =g:netrw_ftpextracmd
1462"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1463    endif
1464
1465    if exists("g:netrw_ftpextracmd")
1466     NetrwKeepj put =g:netrw_ftpextracmd
1467"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1468    endif
1469    for fname in fnamelist
1470     NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1471    endfor
1472"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1473
1474    " perform ftp:
1475    " -i       : turns off interactive prompting from ftp
1476    " -n  unix : DON'T use <.netrc>, even though it exists
1477    " -n  win32: quit being obnoxious about password
1478    NetrwKeepj norm! 1Gdd
1479    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1480    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1481    if getline(1) !~ "^$"
1482"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1483     if !exists("g:netrw_quiet")
1484      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1485     endif
1486    endif
1487
1488   elseif b:netrw_method == 9
1489    " obtain file using sftp
1490"    call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1491    if a:fname =~ '/'
1492     let localfile= substitute(a:fname,'^.*/','','')
1493    else
1494     let localfile= a:fname
1495    endif
1496    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1).s:ShellEscape(localfile)." ".s:ShellEscape(tgtdir))
1497
1498   elseif !exists("b:netrw_method") || b:netrw_method < 0
1499    " probably a badly formed url; protocol not recognized
1500"    call Dret("netrw#Obtain : unsupported method")
1501    return
1502
1503   else
1504    " protocol recognized but not supported for Obtain (yet?)
1505    if !exists("g:netrw_quiet")
1506     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1507    endif
1508"    call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1509    return
1510   endif
1511
1512   " restore status line
1513   if type(a:fname) == 1 && exists("s:netrw_users_stl")
1514    NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
1515   endif
1516
1517  endif
1518
1519  " cleanup
1520  if exists("tmpbufnr")
1521   if bufnr("%") != tmpbufnr
1522    exe tmpbufnr."bw!"
1523   else
1524    q!
1525   endif
1526  endif
1527
1528"  call Dret("netrw#Obtain")
1529endfun
1530
1531" ---------------------------------------------------------------------
1532" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1533fun! netrw#Nread(mode,fname)
1534"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
1535  call netrw#SavePosn()
1536  call netrw#NetRead(a:mode,a:fname)
1537  call netrw#RestorePosn()
1538
1539  if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
1540   if exists("w:netrw_bannercnt")
1541    " start with cursor just after the banner
1542    exe w:netrw_bannercnt
1543   endif
1544  endif
1545"  call Dret("netrw#Nread")
1546endfun
1547
1548" ------------------------------------------------------------------------
1549" s:NetrwOptionRestore: restore options (based on prior s:NetrwOptionSave) {{{2
1550fun! s:NetrwOptionRestore(vt)
1551"  call Dfunc("s:NetrwOptionRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
1552"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>"))
1553  if !exists("{a:vt}netrw_optionsave")
1554   if exists("s:nbcd_curpos_{bufnr('%')}")
1555"    call Decho("restoring previous position  (s:nbcd_curpos_".bufnr('%')." exists)",'~'.expand("<slnum>"))
1556    NetrwKeepj call netrw#RestorePosn(s:nbcd_curpos_{bufnr('%')})
1557"    call Decho("win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
1558"    call Decho("unlet s:nbcd_curpos_".bufnr('%'),'~'.expand("<slnum>"))
1559    unlet s:nbcd_curpos_{bufnr('%')}
1560   else
1561"    call Decho("no previous position",'~'.expand("<slnum>"))
1562   endif
1563"   call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>"))
1564"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1565"   call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist")
1566   return
1567  endif
1568  unlet {a:vt}netrw_optionsave
1569
1570  if exists("+acd")
1571   if exists("{a:vt}netrw_acdkeep")
1572"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1573    let curdir = getcwd()
1574    let &l:acd = {a:vt}netrw_acdkeep
1575    unlet {a:vt}netrw_acdkeep
1576    if &l:acd
1577     call s:NetrwLcd(curdir)
1578    endif
1579   endif
1580  endif
1581  if exists("{a:vt}netrw_aikeep")   |let &l:ai     = {a:vt}netrw_aikeep      |unlet {a:vt}netrw_aikeep   |endif
1582  if exists("{a:vt}netrw_awkeep")   |let &l:aw     = {a:vt}netrw_awkeep      |unlet {a:vt}netrw_awkeep   |endif
1583  if exists("{a:vt}netrw_blkeep")   |let &l:bl     = {a:vt}netrw_blkeep      |unlet {a:vt}netrw_blkeep   |endif
1584  if exists("{a:vt}netrw_btkeep")   |let &l:bt     = {a:vt}netrw_btkeep      |unlet {a:vt}netrw_btkeep   |endif
1585  if exists("{a:vt}netrw_bombkeep") |let &l:bomb   = {a:vt}netrw_bombkeep    |unlet {a:vt}netrw_bombkeep |endif
1586  if exists("{a:vt}netrw_cedit")    |let &cedit    = {a:vt}netrw_cedit       |unlet {a:vt}netrw_cedit    |endif
1587  if exists("{a:vt}netrw_cikeep")   |let &l:ci     = {a:vt}netrw_cikeep      |unlet {a:vt}netrw_cikeep   |endif
1588  if exists("{a:vt}netrw_cinkeep")  |let &l:cin    = {a:vt}netrw_cinkeep     |unlet {a:vt}netrw_cinkeep  |endif
1589  if exists("{a:vt}netrw_cinokeep") |let &l:cino   = {a:vt}netrw_cinokeep    |unlet {a:vt}netrw_cinokeep |endif
1590  if exists("{a:vt}netrw_comkeep")  |let &l:com    = {a:vt}netrw_comkeep     |unlet {a:vt}netrw_comkeep  |endif
1591  if exists("{a:vt}netrw_cpokeep")  |let &l:cpo    = {a:vt}netrw_cpokeep     |unlet {a:vt}netrw_cpokeep  |endif
1592  if exists("{a:vt}netrw_diffkeep") |let &l:diff   = {a:vt}netrw_diffkeep    |unlet {a:vt}netrw_diffkeep |endif
1593  if exists("{a:vt}netrw_fenkeep")  |let &l:fen    = {a:vt}netrw_fenkeep     |unlet {a:vt}netrw_fenkeep  |endif
1594  if exists("g:netrw_ffkep") && g:netrw_ffkeep
1595   if exists("{a:vt}netrw_ffkeep")   |let &l:ff     = {a:vt}netrw_ffkeep      |unlet {a:vt}netrw_ffkeep   |endif
1596  endif
1597  if exists("{a:vt}netrw_fokeep")   |let &l:fo     = {a:vt}netrw_fokeep      |unlet {a:vt}netrw_fokeep   |endif
1598  if exists("{a:vt}netrw_gdkeep")   |let &l:gd     = {a:vt}netrw_gdkeep      |unlet {a:vt}netrw_gdkeep   |endif
1599  if exists("{a:vt}netrw_hidkeep")  |let &l:hidden = {a:vt}netrw_hidkeep     |unlet {a:vt}netrw_hidkeep  |endif
1600  if exists("{a:vt}netrw_imkeep")   |let &l:im     = {a:vt}netrw_imkeep      |unlet {a:vt}netrw_imkeep   |endif
1601  if exists("{a:vt}netrw_iskkeep")  |let &l:isk    = {a:vt}netrw_iskkeep     |unlet {a:vt}netrw_iskkeep  |endif
1602  if exists("{a:vt}netrw_lskeep")   |let &l:ls     = {a:vt}netrw_lskeep      |unlet {a:vt}netrw_lskeep   |endif
1603  if exists("{a:vt}netrw_makeep")   |let &l:ma     = {a:vt}netrw_makeep      |unlet {a:vt}netrw_makeep   |endif
1604  if exists("{a:vt}netrw_magickeep")|let &l:magic  = {a:vt}netrw_magickeep   |unlet {a:vt}netrw_magickeep|endif
1605  if exists("{a:vt}netrw_modkeep")  |let &l:mod    = {a:vt}netrw_modkeep     |unlet {a:vt}netrw_modkeep  |endif
1606  if exists("{a:vt}netrw_nukeep")   |let &l:nu     = {a:vt}netrw_nukeep      |unlet {a:vt}netrw_nukeep   |endif
1607  if exists("{a:vt}netrw_rnukeep")  |let &l:rnu    = {a:vt}netrw_rnukeep     |unlet {a:vt}netrw_rnukeep  |endif
1608  if exists("{a:vt}netrw_repkeep")  |let &l:report = {a:vt}netrw_repkeep     |unlet {a:vt}netrw_repkeep  |endif
1609  if exists("{a:vt}netrw_rokeep")   |let &l:ro     = {a:vt}netrw_rokeep      |unlet {a:vt}netrw_rokeep   |endif
1610  if exists("{a:vt}netrw_selkeep")  |let &l:sel    = {a:vt}netrw_selkeep     |unlet {a:vt}netrw_selkeep  |endif
1611  if exists("{a:vt}netrw_spellkeep")|let &l:spell  = {a:vt}netrw_spellkeep   |unlet {a:vt}netrw_spellkeep|endif
1612  if has("clipboard")
1613   if exists("{a:vt}netrw_starkeep") |let @*        = {a:vt}netrw_starkeep    |unlet {a:vt}netrw_starkeep |endif
1614  endif
1615  " Problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1616"  if exists("{a:vt}netrw_tskeep")   |let &l:ts     = {a:vt}netrw_tskeep      |unlet {a:vt}netrw_tskeep   |endif
1617  if exists("{a:vt}netrw_twkeep")   |let &l:tw     = {a:vt}netrw_twkeep      |unlet {a:vt}netrw_twkeep   |endif
1618  if exists("{a:vt}netrw_wigkeep")  |let &l:wig    = {a:vt}netrw_wigkeep     |unlet {a:vt}netrw_wigkeep  |endif
1619  if exists("{a:vt}netrw_wrapkeep") |let &l:wrap   = {a:vt}netrw_wrapkeep    |unlet {a:vt}netrw_wrapkeep |endif
1620  if exists("{a:vt}netrw_writekeep")|let &l:write  = {a:vt}netrw_writekeep   |unlet {a:vt}netrw_writekeep|endif
1621  if exists("s:yykeep")             |let  @@       = s:yykeep                |unlet s:yykeep             |endif
1622  if exists("{a:vt}netrw_swfkeep")
1623   if &directory == ""
1624    " user hasn't specified a swapfile directory;
1625    " netrw will temporarily set the swapfile directory
1626    " to the current directory as returned by getcwd().
1627    let &l:directory= getcwd()
1628    sil! let &l:swf = {a:vt}netrw_swfkeep
1629    setl directory=
1630    unlet {a:vt}netrw_swfkeep
1631   elseif &l:swf != {a:vt}netrw_swfkeep
1632    " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1633    sil! let &l:swf= {a:vt}netrw_swfkeep
1634    unlet {a:vt}netrw_swfkeep
1635   endif
1636  endif
1637  if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
1638   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1639   if exists("{a:vt}netrw_dirkeep")
1640    call s:NetrwLcd(dirkeep)
1641    unlet {a:vt}netrw_dirkeep
1642   endif
1643  endif
1644  if has("clipboard")
1645   if exists("{a:vt}netrw_regstar") |sil! let @*= {a:vt}netrw_regstar |unlet {a:vt}netrw_regstar |endif
1646  endif
1647  if exists("{a:vt}netrw_regslash")|sil! let @/= {a:vt}netrw_regslash|unlet {a:vt}netrw_regslash|endif
1648  if exists("s:nbcd_curpos_{bufnr('%')}")
1649"   call Decho("restoring previous position  (s:nbcd_curpos_".bufnr('%')." exists)",'~'.expand("<slnum>"))
1650   NetrwKeepj call netrw#RestorePosn(s:nbcd_curpos_{bufnr('%')})
1651"   call Decho("unlet s:nbcd_curpos_".bufnr('%'),'~'.expand("<slnum>"))
1652   if exists("s:nbcd_curpos_".bufnr('%'))
1653    unlet s:nbcd_curpos_{bufnr('%')}
1654   endif
1655  else
1656"   call Decho("no previous position",'~'.expand("<slnum>"))
1657  endif
1658
1659"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1660"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
1661"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1662"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
1663"  call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
1664  " Moved the filetype detect here from NetrwGetFile() because remote files
1665  " were having their filetype detect-generated settings overwritten by
1666  " NetrwOptionRestore.
1667  if &ft != "netrw"
1668"   call Decho("filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1669   filetype detect
1670  endif
1671"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>"))
1672"  call Dret("s:NetrwOptionRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
1673endfun
1674
1675" ---------------------------------------------------------------------
1676" s:NetrwOptionSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1677"             Options get restored by s:NetrwOptionRestore()
1678"  06/08/07 : removed call to NetrwSafeOptions(), either placed
1679"             immediately after NetrwOptionSave() calls in NetRead
1680"             and NetWrite, or after the s:NetrwEnew() call in
1681"             NetrwBrowse.
1682"             vt: normally its "w:" or "s:" (a variable type)
1683fun! s:NetrwOptionSave(vt)
1684"  call Dfunc("s:NetrwOptionSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1685"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1686"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>"))
1687
1688  if !exists("{a:vt}netrw_optionsave")
1689   let {a:vt}netrw_optionsave= 1
1690  else
1691"   call Dret("s:NetrwOptionSave : options already saved")
1692   return
1693  endif
1694"  call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
1695
1696  " Save current settings and current directory
1697"  call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
1698  let s:yykeep          = @@
1699  if exists("&l:acd")|let {a:vt}netrw_acdkeep  = &l:acd|endif
1700  let {a:vt}netrw_aikeep    = &l:ai
1701  let {a:vt}netrw_awkeep    = &l:aw
1702  let {a:vt}netrw_bhkeep    = &l:bh
1703  let {a:vt}netrw_blkeep    = &l:bl
1704  let {a:vt}netrw_btkeep    = &l:bt
1705  let {a:vt}netrw_bombkeep  = &l:bomb
1706  let {a:vt}netrw_cedit     = &cedit
1707  let {a:vt}netrw_cikeep    = &l:ci
1708  let {a:vt}netrw_cinkeep   = &l:cin
1709  let {a:vt}netrw_cinokeep  = &l:cino
1710  let {a:vt}netrw_comkeep   = &l:com
1711  let {a:vt}netrw_cpokeep   = &l:cpo
1712  let {a:vt}netrw_diffkeep  = &l:diff
1713  let {a:vt}netrw_fenkeep   = &l:fen
1714  if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
1715   let {a:vt}netrw_ffkeep    = &l:ff
1716  endif
1717  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
1718  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
1719  let {a:vt}netrw_hidkeep   = &l:hidden
1720  let {a:vt}netrw_imkeep    = &l:im
1721  let {a:vt}netrw_iskkeep   = &l:isk
1722  let {a:vt}netrw_lskeep    = &l:ls
1723  let {a:vt}netrw_makeep    = &l:ma
1724  let {a:vt}netrw_magickeep = &l:magic
1725  let {a:vt}netrw_modkeep   = &l:mod
1726  let {a:vt}netrw_nukeep    = &l:nu
1727  let {a:vt}netrw_rnukeep   = &l:rnu
1728  let {a:vt}netrw_repkeep   = &l:report
1729  let {a:vt}netrw_rokeep    = &l:ro
1730  let {a:vt}netrw_selkeep   = &l:sel
1731  let {a:vt}netrw_spellkeep = &l:spell
1732  if g:netrw_use_noswf
1733   let {a:vt}netrw_swfkeep   = &l:swf
1734  endif
1735  if has("clipboard")
1736   let {a:vt}netrw_starkeep  = @*
1737  endif
1738  let {a:vt}netrw_tskeep    = &l:ts
1739  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
1740  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
1741  let {a:vt}netrw_wrapkeep  = &l:wrap
1742  let {a:vt}netrw_writekeep = &l:write
1743
1744  " save a few selected netrw-related variables
1745"  call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
1746  if g:netrw_keepdir
1747   let {a:vt}netrw_dirkeep  = getcwd()
1748  endif
1749  if has("clipboard")
1750   if &go =~# 'a' | sil! let {a:vt}netrw_regstar = @* | endif
1751  endif
1752  sil! let {a:vt}netrw_regslash= @/
1753
1754"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>"))
1755"  call Dret("s:NetrwOptionSave : tab#".tabpagenr()." win#".winnr())
1756endfun
1757
1758" ------------------------------------------------------------------------
1759" s:NetrwSafeOptions: sets options to help netrw do its job {{{2
1760"                     Use  s:NetrwSaveOptions() to save user settings
1761"                     Use  s:NetrwOptionRestore() to restore user settings
1762fun! s:NetrwSafeOptions()
1763"  call Dfunc("s:NetrwSafeOptions() win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1764"  call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1765"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
1766  if exists("+acd") | setl noacd | endif
1767  setl noai
1768  setl noaw
1769  setl nobl
1770  setl nobomb
1771  setl bt=nofile
1772  setl noci
1773  setl nocin
1774  setl bh=hide
1775  setl cino=
1776  setl com=
1777  setl cpo-=a
1778  setl cpo-=A
1779  setl fo=nroql2
1780  setl nohid
1781  setl noim
1782  setl isk+=@ isk+=* isk+=/
1783  setl magic
1784  if g:netrw_use_noswf
1785   setl noswf
1786  endif
1787  setl report=10000
1788  setl sel=inclusive
1789  setl nospell
1790  setl tw=0
1791  setl wig=
1792  setl cedit&
1793  call s:NetrwCursor()
1794
1795  " allow the user to override safe options
1796"  call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
1797  if &ft == "netrw"
1798"   call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1799   sil! keepalt NetrwKeepj doau FileType netrw
1800  endif
1801
1802"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1803"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
1804"  call Dret("s:NetrwSafeOptions")
1805endfun
1806
1807" ---------------------------------------------------------------------
1808" NetrwStatusLine: {{{2
1809fun! NetrwStatusLine()
1810
1811" vvv NetrwStatusLine() debugging vvv
1812"  let g:stlmsg=""
1813"  if !exists("w:netrw_explore_bufnr")
1814"   let g:stlmsg="!X<explore_bufnr>"
1815"  elseif w:netrw_explore_bufnr != bufnr("%")
1816"   let g:stlmsg="explore_bufnr!=".bufnr("%")
1817"  endif
1818"  if !exists("w:netrw_explore_line")
1819"   let g:stlmsg=" !X<explore_line>"
1820"  elseif w:netrw_explore_line != line(".")
1821"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1822"  endif
1823"  if !exists("w:netrw_explore_list")
1824"   let g:stlmsg=" !X<explore_list>"
1825"  endif
1826" ^^^ NetrwStatusLine() debugging ^^^
1827
1828  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")
1829   " restore user's status line
1830   let &stl        = s:netrw_users_stl
1831   let &laststatus = s:netrw_users_ls
1832   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1833   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1834   return ""
1835  else
1836   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
1837  endif
1838endfun
1839
1840" ---------------------------------------------------------------------
1841"  Netrw Transfer Functions: {{{1
1842" ===============================
1843
1844" ------------------------------------------------------------------------
1845" netrw#NetRead: responsible for reading a file over the net {{{2
1846"   mode: =0 read remote file and insert before current line
1847"         =1 read remote file and insert after current line
1848"         =2 replace with remote file
1849"         =3 obtain file, but leave in temporary format
1850fun! netrw#NetRead(mode,...)
1851"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
1852
1853  " NetRead: save options {{{3
1854  call s:NetrwOptionSave("w:")
1855  call s:NetrwSafeOptions()
1856  call s:RestoreCursorline()
1857  " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
1858  " However, this setting is not wanted for a remote editing session.  The buffer should be "nofile", still.
1859  setl bl
1860"  call Decho("(netrw#NetRead) buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
1861
1862  " NetRead: interpret mode into a readcmd {{{3
1863  if     a:mode == 0 " read remote file before current line
1864   let readcmd = "0r"
1865  elseif a:mode == 1 " read file after current line
1866   let readcmd = "r"
1867  elseif a:mode == 2 " replace with remote file
1868   let readcmd = "%r"
1869  elseif a:mode == 3 " skip read of file (leave as temporary)
1870   let readcmd = "t"
1871  else
1872   exe a:mode
1873   let readcmd = "r"
1874  endif
1875  let ichoice = (a:0 == 0)? 0 : 1
1876"  call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
1877
1878  " NetRead: get temporary filename {{{3
1879  let tmpfile= s:GetTempfile("")
1880  if tmpfile == ""
1881"   call Dret("netrw#NetRead : unable to get a tempfile!")
1882   return
1883  endif
1884
1885  while ichoice <= a:0
1886
1887   " attempt to repeat with previous host-file-etc
1888   if exists("b:netrw_lastfile") && a:0 == 0
1889"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
1890    let choice = b:netrw_lastfile
1891    let ichoice= ichoice + 1
1892
1893   else
1894    exe "let choice= a:" . ichoice
1895"    call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
1896
1897    if match(choice,"?") == 0
1898     " give help
1899     echomsg 'NetRead Usage:'
1900     echomsg ':Nread machine:path                         uses rcp'
1901     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
1902     echomsg ':Nread "machine id password path"           uses ftp'
1903     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
1904     echomsg ':Nread fetch://machine/path                 uses fetch'
1905     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
1906     echomsg ':Nread http://[user@]machine/path           uses http  wget'
1907     echomsg ':Nread file:///path           		  uses elinks'
1908     echomsg ':Nread https://[user@]machine/path          uses http  wget'
1909     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
1910     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
1911     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
1912     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
1913     sleep 4
1914     break
1915
1916    elseif match(choice,'^"') != -1
1917     " Reconstruct Choice if choice starts with '"'
1918"     call Decho("reconstructing choice",'~'.expand("<slnum>"))
1919     if match(choice,'"$') != -1
1920      " case "..."
1921      let choice= strpart(choice,1,strlen(choice)-2)
1922     else
1923       "  case "... ... ..."
1924      let choice      = strpart(choice,1,strlen(choice)-1)
1925      let wholechoice = ""
1926
1927      while match(choice,'"$') == -1
1928       let wholechoice = wholechoice . " " . choice
1929       let ichoice     = ichoice + 1
1930       if ichoice > a:0
1931       	if !exists("g:netrw_quiet")
1932	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
1933	endif
1934"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
1935        return
1936       endif
1937       let choice= a:{ichoice}
1938      endwhile
1939      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
1940     endif
1941    endif
1942   endif
1943
1944"   call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
1945   let ichoice= ichoice + 1
1946
1947   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
1948   call s:NetrwMethod(choice)
1949   if !exists("b:netrw_method") || b:netrw_method < 0
1950"    call Dfunc("netrw#NetRead : unsupported method")
1951    return
1952   endif
1953   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
1954
1955   " Check whether or not NetrwBrowse() should be handling this request
1956"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
1957   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
1958"    call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
1959    NetrwKeepj call s:NetrwBrowse(0,choice)
1960"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
1961    return
1962   endif
1963
1964   " ============
1965   " NetRead: Perform Protocol-Based Read {{{3
1966   " ===========================
1967   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
1968    echo "(netrw) Processing your read request..."
1969   endif
1970
1971   ".........................................
1972   " NetRead: (rcp)  NetRead Method #1 {{{3
1973   if  b:netrw_method == 1 " read with rcp
1974"    call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
1975   " ER: nothing done with g:netrw_uid yet?
1976   " ER: on Win2K" rcp machine[.user]:file tmpfile
1977   " ER: when machine contains '.' adding .user is required (use $USERNAME)
1978   " ER: the tmpfile is full path: rcp sees C:\... as host C
1979   if s:netrw_has_nt_rcp == 1
1980    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
1981     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
1982    else
1983     " Any way needed it machine contains a '.'
1984     let uid_machine = g:netrw_machine .'.'. $USERNAME
1985    endif
1986   else
1987    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
1988     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
1989    else
1990     let uid_machine = g:netrw_machine
1991    endif
1992   endif
1993   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".s:ShellEscape(uid_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
1994   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
1995   let b:netrw_lastfile = choice
1996
1997   ".........................................
1998   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
1999   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
2000"     call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2001     let netrw_fname= b:netrw_fname
2002     NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2003     let filtbuf= bufnr("%")
2004     setl ff=unix
2005     NetrwKeepj put =g:netrw_ftpmode
2006"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2007     if exists("g:netrw_ftpextracmd")
2008      NetrwKeepj put =g:netrw_ftpextracmd
2009"      call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2010     endif
2011     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2012"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2013     if exists("g:netrw_port") && g:netrw_port != ""
2014      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2015     else
2016      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2017     endif
2018     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2019     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2020      let debugkeep = &debug
2021      setl debug=msg
2022      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2023      let &debug    = debugkeep
2024     endif
2025     call s:SaveBufVars()
2026     keepj bd!
2027     if bufname("%") == "" && getline("$") == "" && line('$') == 1
2028      " needed when one sources a file in a nolbl setting window via ftp
2029      q!
2030     endif
2031     call s:RestoreBufVars()
2032     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2033     let b:netrw_lastfile = choice
2034
2035   ".........................................
2036   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
2037   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
2038    " Construct execution string (four lines) which will be passed through filter
2039"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2040    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2041    NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2042    let filtbuf= bufnr("%")
2043    setl ff=unix
2044    if exists("g:netrw_port") && g:netrw_port != ""
2045     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2046"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2047    else
2048     NetrwKeepj put ='open '.g:netrw_machine
2049"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2050    endif
2051
2052    if exists("g:netrw_uid") && g:netrw_uid != ""
2053     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2054      NetrwKeepj put =g:netrw_uid
2055"       call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2056      if exists("s:netrw_passwd")
2057       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2058      endif
2059"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2060     elseif exists("s:netrw_passwd")
2061      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2062"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2063     endif
2064    endif
2065
2066    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2067     NetrwKeepj put =g:netrw_ftpmode
2068"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2069    endif
2070    if exists("g:netrw_ftpextracmd")
2071     NetrwKeepj put =g:netrw_ftpextracmd
2072"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2073    endif
2074    NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2075"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2076
2077    " perform ftp:
2078    " -i       : turns off interactive prompting from ftp
2079    " -n  unix : DON'T use <.netrc>, even though it exists
2080    " -n  win32: quit being obnoxious about password
2081    NetrwKeepj norm! 1Gdd
2082    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2083    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2084    if getline(1) !~ "^$"
2085"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2086     if !exists("g:netrw_quiet")
2087      call netrw#ErrorMsg(s:ERROR,getline(1),5)
2088     endif
2089    endif
2090    call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2091    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2092    let b:netrw_lastfile = choice
2093
2094   ".........................................
2095   " NetRead: (scp) NetRead Method #4 {{{3
2096   elseif     b:netrw_method  == 4	" read with scp
2097"    call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2098    if exists("g:netrw_port") && g:netrw_port != ""
2099     let useport= " ".g:netrw_scpport." ".g:netrw_port
2100    else
2101     let useport= ""
2102    endif
2103    " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2104    " This is workaround to avoid mis-handle windows local-path:
2105    if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
2106      let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2107    else
2108      let tmpfile_get = tmpfile
2109    endif
2110    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile_get,1))
2111    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2112    let b:netrw_lastfile = choice
2113
2114   ".........................................
2115   " NetRead: (http) NetRead Method #5 (wget) {{{3
2116   elseif     b:netrw_method  == 5
2117"    call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2118    if g:netrw_http_cmd == ""
2119     if !exists("g:netrw_quiet")
2120      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2121     endif
2122"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2123     return
2124    endif
2125
2126    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2127     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2128"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2129     if exists("g:netrw_http_xcmd")
2130      call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_cmd." ".s:ShellEscape(b:netrw_http."://".g:netrw_machine.b:netrw_fname,1)." ".g:netrw_http_xcmd." ".s:ShellEscape(tmpfile,1))
2131     else
2132      call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(b:netrw_http."://".g:netrw_machine.b:netrw_fname,1))
2133     endif
2134     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2135
2136    else
2137     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2138"     call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2139     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2140     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2141"     call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2142"     call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2143     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(b:netrw_http."://".g:netrw_machine.netrw_html,1))
2144     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2145"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2146     exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2147    endif
2148    let b:netrw_lastfile = choice
2149"    call Decho("setl ro",'~'.expand("<slnum>"))
2150    setl ro nomod
2151
2152   ".........................................
2153   " NetRead: (dav) NetRead Method #6 {{{3
2154   elseif     b:netrw_method  == 6
2155"    call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2156
2157    if !executable(g:netrw_dav_cmd)
2158     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2159"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2160     return
2161    endif
2162    if g:netrw_dav_cmd =~ "curl"
2163     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2164    else
2165     " Construct execution string (four lines) which will be passed through filter
2166     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2167     new
2168     setl ff=unix
2169     if exists("g:netrw_port") && g:netrw_port != ""
2170      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2171     else
2172      NetrwKeepj put ='open '.g:netrw_machine
2173     endif
2174     if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2175      NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2176     endif
2177     NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2178     NetrwKeepj put ='quit'
2179
2180     " perform cadaver operation:
2181     NetrwKeepj norm! 1Gdd
2182     call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2183     keepj bd!
2184    endif
2185    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2186    let b:netrw_lastfile = choice
2187
2188   ".........................................
2189   " NetRead: (rsync) NetRead Method #7 {{{3
2190   elseif     b:netrw_method  == 7
2191"    call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2192    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2193    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2194    let b:netrw_lastfile = choice
2195
2196   ".........................................
2197   " NetRead: (fetch) NetRead Method #8 {{{3
2198   "    fetch://[user@]host[:http]/path
2199   elseif     b:netrw_method  == 8
2200"    call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2201    if g:netrw_fetch_cmd == ""
2202     if !exists("g:netrw_quiet")
2203      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2204     endif
2205"     call Dret("NetRead")
2206     return
2207    endif
2208    if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2209     let netrw_option= "http"
2210    else
2211     let netrw_option= "ftp"
2212    endif
2213"    call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2214
2215    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2216     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(netrw_option."://".g:netrw_uid.':'.s:netrw_passwd.'@'.g:netrw_machine."/".b:netrw_fname,1))
2217    else
2218     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(netrw_option."://".g:netrw_machine."/".b:netrw_fname,1))
2219    endif
2220
2221    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2222    let b:netrw_lastfile = choice
2223"    call Decho("setl ro",'~'.expand("<slnum>"))
2224    setl ro nomod
2225
2226   ".........................................
2227   " NetRead: (sftp) NetRead Method #9 {{{3
2228   elseif     b:netrw_method  == 9
2229"    call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2230    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2231    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2232    let b:netrw_lastfile = choice
2233
2234   ".........................................
2235   " NetRead: (file) NetRead Method #10 {{{3
2236  elseif      b:netrw_method == 10 && exists("g:netrw_file_cmd")
2237"   "    call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2238   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2239   let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2240   let b:netrw_lastfile = choice
2241
2242   ".........................................
2243   " NetRead: Complain {{{3
2244   else
2245    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
2246   endif
2247  endwhile
2248
2249  " NetRead: cleanup {{{3
2250  if exists("b:netrw_method")
2251"   call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2252   unlet b:netrw_method
2253   unlet b:netrw_fname
2254  endif
2255  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
2256"   call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2257   NetrwKeepj call s:NetrwDelete(tmpfile)
2258  endif
2259  NetrwKeepj call s:NetrwOptionRestore("w:")
2260
2261"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
2262endfun
2263
2264" ------------------------------------------------------------------------
2265" netrw#NetWrite: responsible for writing a file over the net {{{2
2266fun! netrw#NetWrite(...) range
2267"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
2268
2269  " NetWrite: option handling {{{3
2270  let mod= 0
2271  call s:NetrwOptionSave("w:")
2272  call s:NetrwSafeOptions()
2273
2274  " NetWrite: Get Temporary Filename {{{3
2275  let tmpfile= s:GetTempfile("")
2276  if tmpfile == ""
2277"   call Dret("netrw#NetWrite : unable to get a tempfile!")
2278   return
2279  endif
2280
2281  if a:0 == 0
2282   let ichoice = 0
2283  else
2284   let ichoice = 1
2285  endif
2286
2287  let curbufname= expand("%")
2288"  call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
2289  if &binary
2290   " For binary writes, always write entire file.
2291   " (line numbers don't really make sense for that).
2292   " Also supports the writing of tar and zip files.
2293"   call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2294   exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2295  elseif g:netrw_cygwin
2296   " write (selected portion of) file to temporary
2297   let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2298"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2299   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
2300  else
2301   " write (selected portion of) file to temporary
2302"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2303   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2304  endif
2305
2306  if curbufname == ""
2307   " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2308   " on the temporary file's name.  Deletion of the temporary file during
2309   " cleanup then causes an error message.
2310   0file!
2311  endif
2312
2313  " NetWrite: while choice loop: {{{3
2314  while ichoice <= a:0
2315
2316   " Process arguments: {{{4
2317   " attempt to repeat with previous host-file-etc
2318   if exists("b:netrw_lastfile") && a:0 == 0
2319"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2320    let choice = b:netrw_lastfile
2321    let ichoice= ichoice + 1
2322   else
2323    exe "let choice= a:" . ichoice
2324
2325    " Reconstruct Choice when choice starts with '"'
2326    if match(choice,"?") == 0
2327     echomsg 'NetWrite Usage:"'
2328     echomsg ':Nwrite machine:path                        uses rcp'
2329     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
2330     echomsg ':Nwrite "machine id password path"          uses ftp'
2331     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
2332     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
2333     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
2334     echomsg ':Nwrite rcp://machine/path                  uses rcp'
2335     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
2336     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2337     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
2338     sleep 4
2339     break
2340
2341    elseif match(choice,"^\"") != -1
2342     if match(choice,"\"$") != -1
2343       " case "..."
2344      let choice=strpart(choice,1,strlen(choice)-2)
2345     else
2346      "  case "... ... ..."
2347      let choice      = strpart(choice,1,strlen(choice)-1)
2348      let wholechoice = ""
2349
2350      while match(choice,"\"$") == -1
2351       let wholechoice= wholechoice . " " . choice
2352       let ichoice    = ichoice + 1
2353       if choice > a:0
2354       	if !exists("g:netrw_quiet")
2355	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2356	endif
2357"        call Dret("netrw#NetWrite")
2358        return
2359       endif
2360       let choice= a:{ichoice}
2361      endwhile
2362      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2363     endif
2364    endif
2365   endif
2366   let ichoice= ichoice + 1
2367"   call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
2368
2369   " Determine method of write (ftp, rcp, etc) {{{4
2370   NetrwKeepj call s:NetrwMethod(choice)
2371   if !exists("b:netrw_method") || b:netrw_method < 0
2372"    call Dfunc("netrw#NetWrite : unsupported method")
2373    return
2374   endif
2375
2376   " =============
2377   " NetWrite: Perform Protocol-Based Write {{{3
2378   " ============================
2379   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2380    echo "(netrw) Processing your write request..."
2381"    call Decho("(netrw) Processing your write request...",'~'.expand("<slnum>"))
2382   endif
2383
2384   ".........................................
2385   " NetWrite: (rcp) NetWrite Method #1 {{{3
2386   if  b:netrw_method == 1
2387"    call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2388    if s:netrw_has_nt_rcp == 1
2389     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2390      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2391     else
2392      let uid_machine = g:netrw_machine .'.'. $USERNAME
2393     endif
2394    else
2395     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2396      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2397     else
2398      let uid_machine = g:netrw_machine
2399     endif
2400    endif
2401    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(uid_machine.":".b:netrw_fname,1))
2402    let b:netrw_lastfile = choice
2403
2404   ".........................................
2405   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2406   elseif b:netrw_method == 2
2407"    call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2408    let netrw_fname = b:netrw_fname
2409
2410    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2411    let bhkeep      = &l:bh
2412    let curbuf      = bufnr("%")
2413    setl bh=hide
2414    keepj keepalt enew
2415
2416"    call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2417    setl ff=unix
2418    NetrwKeepj put =g:netrw_ftpmode
2419"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2420    if exists("g:netrw_ftpextracmd")
2421     NetrwKeepj put =g:netrw_ftpextracmd
2422"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2423    endif
2424    NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2425"    call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2426    if exists("g:netrw_port") && g:netrw_port != ""
2427     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2428    else
2429"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2430     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2431    endif
2432    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2433    if getline(1) !~ "^$"
2434     if !exists("g:netrw_quiet")
2435      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2436     endif
2437     let mod=1
2438    endif
2439
2440    " remove enew buffer (quietly)
2441    let filtbuf= bufnr("%")
2442    exe curbuf."b!"
2443    let &l:bh            = bhkeep
2444    exe filtbuf."bw!"
2445
2446    let b:netrw_lastfile = choice
2447
2448   ".........................................
2449   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2450   elseif b:netrw_method == 3
2451    " Construct execution string (three or more lines) which will be passed through filter
2452"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2453    let netrw_fname = b:netrw_fname
2454    let bhkeep      = &l:bh
2455
2456    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2457    let curbuf      = bufnr("%")
2458    setl bh=hide
2459    keepj keepalt enew
2460    setl ff=unix
2461
2462    if exists("g:netrw_port") && g:netrw_port != ""
2463     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2464"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2465    else
2466     NetrwKeepj put ='open '.g:netrw_machine
2467"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2468    endif
2469    if exists("g:netrw_uid") && g:netrw_uid != ""
2470     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2471      NetrwKeepj put =g:netrw_uid
2472"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2473      if exists("s:netrw_passwd") && s:netrw_passwd != ""
2474       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2475      endif
2476"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2477     elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2478      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2479"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2480     endif
2481    endif
2482    NetrwKeepj put =g:netrw_ftpmode
2483"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2484    if exists("g:netrw_ftpextracmd")
2485     NetrwKeepj put =g:netrw_ftpextracmd
2486"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2487    endif
2488    NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2489"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2490    " save choice/id/password for future use
2491    let b:netrw_lastfile = choice
2492
2493    " perform ftp:
2494    " -i       : turns off interactive prompting from ftp
2495    " -n  unix : DON'T use <.netrc>, even though it exists
2496    " -n  win32: quit being obnoxious about password
2497    NetrwKeepj norm! 1Gdd
2498    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2499    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2500    if getline(1) !~ "^$"
2501     if  !exists("g:netrw_quiet")
2502      call netrw#ErrorMsg(s:ERROR,getline(1),15)
2503     endif
2504     let mod=1
2505    endif
2506
2507    " remove enew buffer (quietly)
2508    let filtbuf= bufnr("%")
2509    exe curbuf."b!"
2510    let &l:bh= bhkeep
2511    exe filtbuf."bw!"
2512
2513   ".........................................
2514   " NetWrite: (scp) NetWrite Method #4 {{{3
2515   elseif     b:netrw_method == 4
2516"    call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2517    if exists("g:netrw_port") && g:netrw_port != ""
2518     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2519    else
2520     let useport= ""
2521    endif
2522    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2523    let b:netrw_lastfile = choice
2524
2525   ".........................................
2526   " NetWrite: (http) NetWrite Method #5 {{{3
2527   elseif     b:netrw_method == 5
2528"    call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2529    let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2530    if executable(curl)
2531     let url= g:netrw_choice
2532     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2533    elseif !exists("g:netrw_quiet")
2534     call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd".">".",16)
2535    endif
2536
2537   ".........................................
2538   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2539   elseif     b:netrw_method == 6
2540"    call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2541
2542    " Construct execution string (four lines) which will be passed through filter
2543    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2544    let bhkeep      = &l:bh
2545
2546    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2547    let curbuf      = bufnr("%")
2548    setl bh=hide
2549    keepj keepalt enew
2550
2551    setl ff=unix
2552    if exists("g:netrw_port") && g:netrw_port != ""
2553     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2554    else
2555     NetrwKeepj put ='open '.g:netrw_machine
2556    endif
2557    if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2558     NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2559    endif
2560    NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2561
2562    " perform cadaver operation:
2563    NetrwKeepj norm! 1Gdd
2564    call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2565
2566    " remove enew buffer (quietly)
2567    let filtbuf= bufnr("%")
2568    exe curbuf."b!"
2569    let &l:bh            = bhkeep
2570    exe filtbuf."bw!"
2571
2572    let b:netrw_lastfile = choice
2573
2574   ".........................................
2575   " NetWrite: (rsync) NetWrite Method #7 {{{3
2576   elseif     b:netrw_method == 7
2577"    call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2578    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2579    let b:netrw_lastfile = choice
2580
2581   ".........................................
2582   " NetWrite: (sftp) NetWrite Method #9 {{{3
2583   elseif     b:netrw_method == 9
2584"    call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2585    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2586    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2587     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2588    else
2589     let uid_machine = g:netrw_machine
2590    endif
2591
2592    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2593    let bhkeep = &l:bh
2594    let curbuf = bufnr("%")
2595    setl bh=hide
2596    keepj keepalt enew
2597
2598    setl ff=unix
2599    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2600"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2601    let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2602    call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2603    let filtbuf= bufnr("%")
2604    exe curbuf."b!"
2605    let &l:bh            = bhkeep
2606    exe filtbuf."bw!"
2607    let b:netrw_lastfile = choice
2608
2609   ".........................................
2610   " NetWrite: Complain {{{3
2611   else
2612    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2613    let leavemod= 1
2614   endif
2615  endwhile
2616
2617  " NetWrite: Cleanup: {{{3
2618"  call Decho("cleanup",'~'.expand("<slnum>"))
2619  if s:FileReadable(tmpfile)
2620"   call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2621   call s:NetrwDelete(tmpfile)
2622  endif
2623  call s:NetrwOptionRestore("w:")
2624
2625  if a:firstline == 1 && a:lastline == line("$")
2626   " restore modifiability; usually equivalent to set nomod
2627   let &mod= mod
2628"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2629  elseif !exists("leavemod")
2630   " indicate that the buffer has not been modified since last written
2631"   call Decho("set nomod",'~'.expand("<slnum>"))
2632   setl nomod
2633"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2634  endif
2635
2636"  call Dret("netrw#NetWrite")
2637endfun
2638
2639" ---------------------------------------------------------------------
2640" netrw#NetSource: source a remotely hosted vim script {{{2
2641" uses NetRead to get a copy of the file into a temporarily file,
2642"              then sources that file,
2643"              then removes that file.
2644fun! netrw#NetSource(...)
2645"  call Dfunc("netrw#NetSource() a:0=".a:0)
2646  if a:0 > 0 && a:1 == '?'
2647   " give help
2648   echomsg 'NetSource Usage:'
2649   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
2650   echomsg ':Nsource fetch://machine/path                 uses fetch'
2651   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2652   echomsg ':Nsource http[s]://[user@]machine/path        uses http  wget'
2653   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
2654   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
2655   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
2656   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2657   sleep 4
2658  else
2659   let i= 1
2660   while i <= a:0
2661    call netrw#NetRead(3,a:{i})
2662"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2663    if s:FileReadable(s:netrw_tmpfile)
2664"     call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2665     exe "so ".fnameescape(s:netrw_tmpfile)
2666"     call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2667     call delete(s:netrw_tmpfile)
2668     unlet s:netrw_tmpfile
2669    else
2670     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2671    endif
2672    let i= i + 1
2673   endwhile
2674  endif
2675"  call Dret("netrw#NetSource")
2676endfun
2677
2678" ---------------------------------------------------------------------
2679" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2680"                   (implements the :Ntree command)
2681fun! netrw#SetTreetop(...)
2682"  call Dfunc("netrw#SetTreetop(".((a:0 > 0)? a:1 : "").") a:0=".a:0)
2683
2684  " clear out the current tree
2685  if exists("w:netrw_treetop")
2686"   call Decho("clearing out current tree",'~'.expand("<slnum>"))
2687   let inittreetop= w:netrw_treetop
2688   unlet w:netrw_treetop
2689  endif
2690  if exists("w:netrw_treedict")
2691"   call Decho("freeing w:netrw_treedict",'~'.expand("<slnum>"))
2692   unlet w:netrw_treedict
2693  endif
2694
2695  if a:1 == "" && exists("inittreetop")
2696   let treedir= s:NetrwTreePath(inittreetop)
2697"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2698  else
2699   if isdirectory(s:NetrwFile(a:1))
2700"    call Decho("a:1<".a:1."> is a directory",'~'.expand("<slnum>"))
2701    let treedir= a:1
2702   elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2703    let treedir= b:netrw_curdir."/".a:1
2704"    call Decho("a:1<".a:1."> is NOT a directory, trying treedir<".treedir.">",'~'.expand("<slnum>"))
2705   else
2706    " normally the cursor is left in the message window.
2707    " However, here this results in the directory being listed in the message window, which is not wanted.
2708    let netrwbuf= bufnr("%")
2709    call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2710    exe bufwinnr(netrwbuf)."wincmd w"
2711    let treedir= "."
2712   endif
2713  endif
2714"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2715  let islocal= expand("%") !~ '^\a\{3,}://'
2716"  call Decho("islocal=".islocal,'~'.expand("<slnum>"))
2717  if islocal
2718   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir))
2719  else
2720   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir))
2721  endif
2722"  call Dret("netrw#SetTreetop")
2723endfun
2724
2725" ===========================================
2726" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
2727"    readcmd == %r : replace buffer with newly read file
2728"            == 0r : read file at top of buffer
2729"            == r  : read file after current line
2730"            == t  : leave file in temporary form (ie. don't read into buffer)
2731fun! s:NetrwGetFile(readcmd, tfile, method)
2732"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
2733
2734  " readcmd=='t': simply do nothing
2735  if a:readcmd == 't'
2736"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2737"   call Dret("NetrwGetFile : skip read of <".a:tfile.">")
2738   return
2739  endif
2740
2741  " get name of remote filename (ie. url and all)
2742  let rfile= bufname("%")
2743"  call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
2744
2745  if exists("*NetReadFixup")
2746   " for the use of NetReadFixup (not otherwise used internally)
2747   let line2= line("$")
2748  endif
2749
2750  if a:readcmd[0] == '%'
2751  " get file into buffer
2752"   call Decho("get file into buffer",'~'.expand("<slnum>"))
2753
2754   " rename the current buffer to the temp file (ie. tfile)
2755   if g:netrw_cygwin
2756    let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2757   else
2758    let tfile= a:tfile
2759   endif
2760"   call Decho("exe sil! keepalt file ".fnameescape(tfile),'~'.expand("<slnum>"))
2761   exe "sil! keepalt file ".fnameescape(tfile)
2762
2763   " edit temporary file (ie. read the temporary file in)
2764   if     rfile =~ '\.zip$'
2765"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2766    call zip#Browse(tfile)
2767   elseif rfile =~ '\.tar$'
2768"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2769    call tar#Browse(tfile)
2770   elseif rfile =~ '\.tar\.gz$'
2771"    call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2772    call tar#Browse(tfile)
2773   elseif rfile =~ '\.tar\.bz2$'
2774"    call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2775    call tar#Browse(tfile)
2776   elseif rfile =~ '\.tar\.xz$'
2777"    call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2778    call tar#Browse(tfile)
2779   elseif rfile =~ '\.txz$'
2780"    call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2781    call tar#Browse(tfile)
2782   else
2783"    call Decho("edit temporary file",'~'.expand("<slnum>"))
2784    NetrwKeepj e!
2785   endif
2786
2787   " rename buffer back to remote filename
2788"   call Decho("exe sil! keepalt file ".fnameescape(rfile),'~'.expand("<slnum>"))
2789   exe "sil! NetrwKeepj keepalt file ".fnameescape(rfile)
2790
2791   " Detect filetype of local version of remote file.
2792   " Note that isk must not include a "/" for scripts.vim
2793   " to process this detection correctly.
2794"   call Decho("detect filetype of local version of remote file",'~'.expand("<slnum>"))
2795   let iskkeep= &l:isk
2796   setl isk-=/
2797   let &l:isk= iskkeep
2798"   call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!")
2799   let line1 = 1
2800   let line2 = line("$")
2801
2802  elseif !&ma
2803   " attempting to read a file after the current line in the file, but the buffer is not modifiable
2804   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2805"   call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2806   return
2807
2808  elseif s:FileReadable(a:tfile)
2809   " read file after current line
2810"   call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2811   let curline = line(".")
2812   let lastline= line("$")
2813"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline,'~'.expand("<slnum>"))
2814   exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2815   let line1= curline + 1
2816   let line2= line("$") - lastline + 1
2817
2818  else
2819   " not readable
2820"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2821"   call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2822   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2823"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2824   return
2825  endif
2826
2827  " User-provided (ie. optional) fix-it-up command
2828  if exists("*NetReadFixup")
2829"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2830   NetrwKeepj call NetReadFixup(a:method, line1, line2)
2831"  else " Decho
2832"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2833  endif
2834
2835  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
2836   " update the Buffers menu
2837   NetrwKeepj call s:UpdateBuffersMenu()
2838  endif
2839
2840"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
2841
2842 " make sure file is being displayed
2843"  redraw!
2844
2845"  call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2846"  call Dret("NetrwGetFile")
2847endfun
2848
2849" ------------------------------------------------------------------------
2850" s:NetrwMethod:  determine method of transfer {{{2
2851" Input:
2852"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
2853" Output:
2854"  b:netrw_method= 1: rcp
2855"                  2: ftp + <.netrc>
2856"	           3: ftp + machine, id, password, and [path]filename
2857"	           4: scp
2858"	           5: http[s] (wget)
2859"	           6: dav
2860"	           7: rsync
2861"	           8: fetch
2862"	           9: sftp
2863"	          10: file
2864"  g:netrw_machine= hostname
2865"  b:netrw_fname  = filename
2866"  g:netrw_port   = optional port number (for ftp)
2867"  g:netrw_choice = copy of input url (choice)
2868fun! s:NetrwMethod(choice)
2869"   call Dfunc("NetrwMethod(a:choice<".a:choice.">)")
2870
2871   " sanity check: choice should have at least three slashes in it
2872   if strlen(substitute(a:choice,'[^/]','','g')) < 3
2873    call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
2874    let b:netrw_method = -1
2875"    call Dret("NetrwMethod : incorrect url format<".a:choice.">")
2876    return
2877   endif
2878
2879   " record current g:netrw_machine, if any
2880   " curmachine used if protocol == ftp and no .netrc
2881   if exists("g:netrw_machine")
2882    let curmachine= g:netrw_machine
2883"    call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
2884   else
2885    let curmachine= "N O T A HOST"
2886   endif
2887   if exists("g:netrw_port")
2888    let netrw_port= g:netrw_port
2889   endif
2890
2891   " insure that netrw_ftp_cmd starts off every method determination
2892   " with the current g:netrw_ftp_cmd
2893   let s:netrw_ftp_cmd= g:netrw_ftp_cmd
2894
2895  " initialization
2896  let b:netrw_method  = 0
2897  let g:netrw_machine = ""
2898  let b:netrw_fname   = ""
2899  let g:netrw_port    = ""
2900  let g:netrw_choice  = a:choice
2901
2902  " Patterns:
2903  " mipf     : a:machine a:id password filename	     Use ftp
2904  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
2905  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
2906  " rcpurm   : rcp://[user@]host/filename	     Use rcp
2907  " rcphf    : [user@]host:filename		     Use rcp
2908  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
2909  " httpurm  : http[s]://[user@]host/filename	     Use wget
2910  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
2911  " rsyncurm : rsync://host[:port]/path              Use rsync
2912  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
2913  " sftpurm  : sftp://[user@]host/filename  Use scp
2914  " fileurm  : file://[user@]host/filename	     Use elinks or links
2915  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
2916  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
2917  let ftpurm   = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
2918  let rcpurm   = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
2919  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
2920  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
2921  let httpurm  = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
2922  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
2923  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
2924  let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
2925  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
2926  let fileurm  = '^file\=://\(.*\)$'
2927
2928"  call Decho("determine method:",'~'.expand("<slnum>"))
2929  " Determine Method
2930  " Method#1: rcp://user@hostname/...path-to-file {{{3
2931  if match(a:choice,rcpurm) == 0
2932"   call Decho("rcp://...",'~'.expand("<slnum>"))
2933   let b:netrw_method  = 1
2934   let userid          = substitute(a:choice,rcpurm,'\1',"")
2935   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
2936   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
2937   if userid != ""
2938    let g:netrw_uid= userid
2939   endif
2940
2941  " Method#4: scp://user@hostname/...path-to-file {{{3
2942  elseif match(a:choice,scpurm) == 0
2943"   call Decho("scp://...",'~'.expand("<slnum>"))
2944   let b:netrw_method  = 4
2945   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
2946   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
2947   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
2948
2949  " Method#5: http[s]://user@hostname/...path-to-file {{{3
2950  elseif match(a:choice,httpurm) == 0
2951"   call Decho("http[s]://...",'~'.expand("<slnum>"))
2952   let b:netrw_method = 5
2953   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
2954   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
2955   let b:netrw_http   = (a:choice =~ '^https:')? "https" : "http"
2956
2957  " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
2958  elseif match(a:choice,davurm) == 0
2959"   call Decho("dav://...",'~'.expand("<slnum>"))
2960   let b:netrw_method= 6
2961   if a:choice =~ 'davs:'
2962    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
2963   else
2964    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
2965   endif
2966   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
2967
2968   " Method#7: rsync://user@hostname/...path-to-file {{{3
2969  elseif match(a:choice,rsyncurm) == 0
2970"   call Decho("rsync://...",'~'.expand("<slnum>"))
2971   let b:netrw_method = 7
2972   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
2973   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
2974
2975   " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
2976  elseif match(a:choice,ftpurm) == 0
2977"   call Decho("ftp://...",'~'.expand("<slnum>"))
2978   let userid	      = substitute(a:choice,ftpurm,'\2',"")
2979   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
2980   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
2981   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
2982"   call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
2983   if userid != ""
2984    let g:netrw_uid= userid
2985   endif
2986
2987   if curmachine != g:netrw_machine
2988    if exists("s:netwr_hup[".g:netrw_machine."]")
2989     call NetUserPass("ftp:".g:netrw_machine)
2990    elseif exists("s:netrw_passwd")
2991     " if there's a change in hostname, require password re-entry
2992     unlet s:netrw_passwd
2993    endif
2994    if exists("netrw_port")
2995     unlet netrw_port
2996    endif
2997   endif
2998
2999   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3000    let b:netrw_method = 3
3001   else
3002    let host= substitute(g:netrw_machine,'\..*$','','')
3003    if exists("s:netrw_hup[host]")
3004     call NetUserPass("ftp:".host)
3005
3006    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~ '-[sS]:'
3007"     call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3008"     call Decho("          g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3009     if g:netrw_ftp_cmd =~ '-[sS]:\S*MACHINE\>'
3010      let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3011"      call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3012     endif
3013     let b:netrw_method= 2
3014    elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3015"     call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3016     let b:netrw_method= 2
3017    else
3018     if !exists("g:netrw_uid") || g:netrw_uid == ""
3019      call NetUserPass()
3020     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3021      call NetUserPass(g:netrw_uid)
3022    " else just use current g:netrw_uid and s:netrw_passwd
3023     endif
3024     let b:netrw_method= 3
3025    endif
3026   endif
3027
3028  " Method#8: fetch {{{3
3029  elseif match(a:choice,fetchurm) == 0
3030"   call Decho("fetch://...",'~'.expand("<slnum>"))
3031   let b:netrw_method = 8
3032   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3033   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3034   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3035   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
3036
3037   " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
3038  elseif match(a:choice,mipf) == 0
3039"   call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
3040   let b:netrw_method  = 3
3041   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3042   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
3043   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
3044   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
3045   call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
3046
3047  " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3048  elseif match(a:choice,mf) == 0
3049"   call Decho("(ftp) host file",'~'.expand("<slnum>"))
3050   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3051    let b:netrw_method  = 3
3052    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3053    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3054
3055   elseif s:FileReadable(expand("$HOME/.netrc"))
3056    let b:netrw_method  = 2
3057    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3058    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3059   endif
3060
3061  " Method#9: sftp://user@hostname/...path-to-file {{{3
3062  elseif match(a:choice,sftpurm) == 0
3063"   call Decho("sftp://...",'~'.expand("<slnum>"))
3064   let b:netrw_method = 9
3065   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3066   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
3067
3068  " Method#1: Issue an rcp: hostname:filename"  (this one should be last) {{{3
3069  elseif match(a:choice,rcphf) == 0
3070"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3071   let b:netrw_method  = 1
3072   let userid          = substitute(a:choice,rcphf,'\2',"")
3073   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3074   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
3075"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3076"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3077"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3078"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3079   if userid != ""
3080    let g:netrw_uid= userid
3081   endif
3082
3083   " Method#10: file://user@hostname/...path-to-file {{{3
3084  elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
3085"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3086   let b:netrw_method = 10
3087   let b:netrw_fname  = substitute(a:choice,fileurm,'\1',"")
3088"   call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
3089
3090  " Cannot Determine Method {{{3
3091  else
3092   if !exists("g:netrw_quiet")
3093    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3094   endif
3095   let b:netrw_method  = -1
3096  endif
3097  "}}}3
3098
3099  if g:netrw_port != ""
3100   " remove any leading [:#] from port number
3101   let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
3102  elseif exists("netrw_port")
3103   " retain port number as implicit for subsequent ftp operations
3104   let g:netrw_port= netrw_port
3105  endif
3106
3107"  call Decho("a:choice       <".a:choice.">",'~'.expand("<slnum>"))
3108"  call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3109"  call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3110"  call Decho("g:netrw_port   <".g:netrw_port.">",'~'.expand("<slnum>"))
3111"  if exists("g:netrw_uid")		"Decho
3112"   call Decho("g:netrw_uid    <".g:netrw_uid.">",'~'.expand("<slnum>"))
3113"  endif					"Decho
3114"  if exists("s:netrw_passwd")		"Decho
3115"   call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3116"  endif					"Decho
3117"  call Decho("b:netrw_fname  <".b:netrw_fname.">",'~'.expand("<slnum>"))
3118"  call Dret("NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
3119endfun
3120
3121" ------------------------------------------------------------------------
3122" NetReadFixup: this sort of function is typically written by the user {{{2
3123"               to handle extra junk that their system's ftp dumps
3124"               into the transfer.  This function is provided as an
3125"               example and as a fix for a Windows 95 problem: in my
3126"               experience, win95's ftp always dumped four blank lines
3127"               at the end of the transfer.
3128if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
3129 fun! NetReadFixup(method, line1, line2)
3130"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
3131
3132   " sanity checks -- attempt to convert inputs to integers
3133   let method = a:method + 0
3134   let line1  = a:line1 + 0
3135   let line2  = a:line2 + 0
3136   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
3137"    call Dret("NetReadFixup")
3138    return
3139   endif
3140
3141   if method == 3   " ftp (no <.netrc>)
3142    let fourblanklines= line2 - 3
3143    if fourblanklines >= line1
3144     exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
3145     call histdel("/",-1)
3146    endif
3147   endif
3148
3149"   call Dret("NetReadFixup")
3150 endfun
3151endif
3152
3153" ---------------------------------------------------------------------
3154" NetUserPass: set username and password for subsequent ftp transfer {{{2
3155"   Usage:  :call NetUserPass()		               -- will prompt for userid and password
3156"	    :call NetUserPass("uid")	               -- will prompt for password
3157"	    :call NetUserPass("uid","password")        -- sets global userid and password
3158"	    :call NetUserPass("ftp:host")              -- looks up userid and password using hup dictionary
3159"	    :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
3160fun! NetUserPass(...)
3161
3162" call Dfunc("NetUserPass() a:0=".a:0)
3163
3164 if !exists('s:netrw_hup')
3165  let s:netrw_hup= {}
3166 endif
3167
3168 if a:0 == 0
3169  " case: no input arguments
3170
3171  " change host and username if not previously entered; get new password
3172  if !exists("g:netrw_machine")
3173   let g:netrw_machine= input('Enter hostname: ')
3174  endif
3175  if !exists("g:netrw_uid") || g:netrw_uid == ""
3176   " get username (user-id) via prompt
3177   let g:netrw_uid= input('Enter username: ')
3178  endif
3179  " get password via prompting
3180  let s:netrw_passwd= inputsecret("Enter Password: ")
3181
3182  " set up hup database
3183  let host = substitute(g:netrw_machine,'\..*$','','')
3184  if !exists('s:netrw_hup[host]')
3185   let s:netrw_hup[host]= {}
3186  endif
3187  let s:netrw_hup[host].uid    = g:netrw_uid
3188  let s:netrw_hup[host].passwd = s:netrw_passwd
3189
3190 elseif a:0 == 1
3191  " case: one input argument
3192
3193  if a:1 =~ '^ftp:'
3194   " get host from ftp:... url
3195   " access userid and password from hup (host-user-passwd) dictionary
3196"   call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3197   let host = substitute(a:1,'^ftp:','','')
3198   let host = substitute(host,'\..*','','')
3199   if exists("s:netrw_hup[host]")
3200    let g:netrw_uid    = s:netrw_hup[host].uid
3201    let s:netrw_passwd = s:netrw_hup[host].passwd
3202"    call Decho("get s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3203"    call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3204   else
3205    let g:netrw_uid    = input("Enter UserId: ")
3206    let s:netrw_passwd = inputsecret("Enter Password: ")
3207   endif
3208
3209  else
3210   " case: one input argument, not an url.  Using it as a new user-id.
3211"   call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3212   if exists("g:netrw_machine")
3213    if g:netrw_machine =~ '[0-9.]\+'
3214     let host= g:netrw_machine
3215    else
3216     let host= substitute(g:netrw_machine,'\..*$','','')
3217    endif
3218   else
3219    let g:netrw_machine= input('Enter hostname: ')
3220   endif
3221   let g:netrw_uid = a:1
3222"   call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3223   if exists("g:netrw_passwd")
3224    " ask for password if one not previously entered
3225    let s:netrw_passwd= g:netrw_passwd
3226   else
3227    let s:netrw_passwd = inputsecret("Enter Password: ")
3228   endif
3229  endif
3230
3231"  call Decho("host<".host.">",'~'.expand("<slnum>"))
3232  if exists("host")
3233   if !exists('s:netrw_hup[host]')
3234    let s:netrw_hup[host]= {}
3235   endif
3236   let s:netrw_hup[host].uid    = g:netrw_uid
3237   let s:netrw_hup[host].passwd = s:netrw_passwd
3238  endif
3239
3240 elseif a:0 == 2
3241  let g:netrw_uid    = a:1
3242  let s:netrw_passwd = a:2
3243
3244 elseif a:0 == 3
3245  " enter hostname, user-id, and password into the hup dictionary
3246  let host = substitute(a:1,'^\a\+:','','')
3247  let host = substitute(host,'\..*$','','')
3248  if !exists('s:netrw_hup[host]')
3249   let s:netrw_hup[host]= {}
3250  endif
3251  let s:netrw_hup[host].uid    = a:2
3252  let s:netrw_hup[host].passwd = a:3
3253  let g:netrw_uid              = s:netrw_hup[host].uid
3254  let s:netrw_passwd           = s:netrw_hup[host].passwd
3255"  call Decho("set s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3256"  call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3257 endif
3258
3259" call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
3260endfun
3261
3262" ===========================================
3263"  Shared Browsing Support:    {{{1
3264" ===========================================
3265
3266" ---------------------------------------------------------------------
3267" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3268fun! s:ExplorePatHls(pattern)
3269"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
3270  let repat= substitute(a:pattern,'^**/\{1,2}','','')
3271"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3272  let repat= escape(repat,'][.\')
3273"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3274  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
3275"  call Dret("s:ExplorePatHls repat<".repat.">")
3276  return repat
3277endfun
3278
3279" ---------------------------------------------------------------------
3280"  s:NetrwBookHistHandler: {{{2
3281"    0: (user: <mb>)   bookmark current directory
3282"    1: (user: <gb>)   change to the bookmarked directory
3283"    2: (user: <qb>)   list bookmarks
3284"    3: (browsing)     records current directory history
3285"    4: (user: <u>)    go up   (previous) directory, using history
3286"    5: (user: <U>)    go down (next)     directory, using history
3287"    6: (user: <mB>)   delete bookmark
3288fun! s:NetrwBookHistHandler(chg,curdir)
3289"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhist_cnt." histmax=".g:netrw_dirhistmax)
3290  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3291"   "  call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3292   return
3293  endif
3294
3295  let ykeep    = @@
3296  let curbufnr = bufnr("%")
3297
3298  if a:chg == 0
3299   " bookmark the current directory
3300"   call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3301   if exists("s:netrwmarkfilelist_{curbufnr}")
3302    call s:NetrwBookmark(0)
3303    echo "bookmarked marked files"
3304   else
3305    call s:MakeBookmark(a:curdir)
3306    echo "bookmarked the current directory"
3307   endif
3308
3309  elseif a:chg == 1
3310   " change to the bookmarked directory
3311"   call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3312   if exists("g:netrw_bookmarklist[v:count-1]")
3313"    call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3314    exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3315   else
3316    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3317   endif
3318
3319  elseif a:chg == 2
3320"   redraw!
3321   let didwork= 0
3322   " list user's bookmarks
3323"   call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3324   if exists("g:netrw_bookmarklist")
3325"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3326    let cnt= 1
3327    for bmd in g:netrw_bookmarklist
3328"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3329     echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3330     let didwork = 1
3331     let cnt     = cnt + 1
3332    endfor
3333   endif
3334
3335   " list directory history
3336   let cnt     = g:netrw_dirhist_cnt
3337   let first   = 1
3338   let histcnt = 0
3339   if g:netrw_dirhistmax > 0
3340    while ( first || cnt != g:netrw_dirhist_cnt )
3341"    call Decho("first=".first." cnt=".cnt." dirhist_cnt=".g:netrw_dirhist_cnt,'~'.expand("<slnum>"))
3342     if exists("g:netrw_dirhist_{cnt}")
3343"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3344      echo printf("Netrw  History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3345      let didwork= 1
3346     endif
3347     let histcnt = histcnt + 1
3348     let first   = 0
3349     let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3350     if cnt < 0
3351      let cnt= cnt + g:netrw_dirhistmax
3352     endif
3353    endwhile
3354   else
3355    let g:netrw_dirhist_cnt= 0
3356   endif
3357   if didwork
3358    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3359   endif
3360
3361  elseif a:chg == 3
3362   " saves most recently visited directories (when they differ)
3363"   call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3364   if !exists("g:netrw_dirhist_cnt") || !exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") || g:netrw_dirhist_{g:netrw_dirhist_cnt} != a:curdir
3365    if g:netrw_dirhistmax > 0
3366     let g:netrw_dirhist_cnt                   = ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
3367     let g:netrw_dirhist_{g:netrw_dirhist_cnt} = a:curdir
3368    endif
3369"    call Decho("save dirhist#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3370   endif
3371
3372  elseif a:chg == 4
3373   " u: change to the previous directory stored on the history list
3374"   call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
3375   if g:netrw_dirhistmax > 0
3376    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - v:count1 ) % g:netrw_dirhistmax
3377    if g:netrw_dirhist_cnt < 0
3378     let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
3379    endif
3380   else
3381    let g:netrw_dirhist_cnt= 0
3382   endif
3383   if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
3384"    call Decho("changedir u#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3385    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3386     setl ma noro
3387"     call Decho("setl ma noro",'~'.expand("<slnum>"))
3388     sil! NetrwKeepj %d _
3389     setl nomod
3390"     call Decho("setl nomod",'~'.expand("<slnum>"))
3391"     call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3392    endif
3393"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("<slnum>"))
3394    exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
3395   else
3396    if g:netrw_dirhistmax > 0
3397     let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + v:count1 ) % g:netrw_dirhistmax
3398    else
3399     let g:netrw_dirhist_cnt= 0
3400    endif
3401    echo "Sorry, no predecessor directory exists yet"
3402   endif
3403
3404  elseif a:chg == 5
3405   " U: change to the subsequent directory stored on the history list
3406"   call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3407   if g:netrw_dirhistmax > 0
3408    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
3409    if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
3410"    call Decho("changedir U#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3411     if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3412"      call Decho("setl ma noro",'~'.expand("<slnum>"))
3413      setl ma noro
3414      sil! NetrwKeepj %d _
3415"      call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3416"      call Decho("setl nomod",'~'.expand("<slnum>"))
3417      setl nomod
3418"      call Decho("(set nomod)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3419     endif
3420"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("<slnum>"))
3421     exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
3422    else
3423     let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax
3424     if g:netrw_dirhist_cnt < 0
3425      let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
3426     endif
3427     echo "Sorry, no successor directory exists yet"
3428    endif
3429   else
3430    let g:netrw_dirhist_cnt= 0
3431    echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
3432   endif
3433
3434  elseif a:chg == 6
3435"   call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3436   if exists("s:netrwmarkfilelist_{curbufnr}")
3437    call s:NetrwBookmark(1)
3438    echo "removed marked files from bookmarks"
3439   else
3440    " delete the v:count'th bookmark
3441    let iremove = v:count
3442    let dremove = g:netrw_bookmarklist[iremove - 1]
3443"    call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3444    call s:MergeBookmarks()
3445"    call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3446    NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3447    echo "removed ".dremove." from g:netrw_bookmarklist"
3448"    call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3449   endif
3450"   call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3451  endif
3452  call s:NetrwBookmarkMenu()
3453  call s:NetrwTgtMenu()
3454  let @@= ykeep
3455"  call Dret("s:NetrwBookHistHandler")
3456endfun
3457
3458" ---------------------------------------------------------------------
3459" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
3460"  Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
3461"                      Sister function: s:NetrwBookHistSave()
3462fun! s:NetrwBookHistRead()
3463"  call Dfunc("s:NetrwBookHistRead()")
3464  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3465"   "  call Dret("s:NetrwBookHistRead - suppressed due to g:netrw_dirhistmax")
3466   return
3467  endif
3468  let ykeep= @@
3469  if !exists("s:netrw_initbookhist")
3470   let home    = s:NetrwHome()
3471   let savefile= home."/.netrwbook"
3472   if filereadable(s:NetrwFile(savefile))
3473"    call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3474    exe "keepalt NetrwKeepj so ".savefile
3475   endif
3476   if g:netrw_dirhistmax > 0
3477    let savefile= home."/.netrwhist"
3478    if filereadable(s:NetrwFile(savefile))
3479"    call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3480     exe "keepalt NetrwKeepj so ".savefile
3481    endif
3482    let s:netrw_initbookhist= 1
3483    au VimLeave * call s:NetrwBookHistSave()
3484   endif
3485  endif
3486  let @@= ykeep
3487"  call Dret("s:NetrwBookHistRead")
3488endfun
3489
3490" ---------------------------------------------------------------------
3491" s:NetrwBookHistSave: this function saves bookmarks and history {{{2
3492"                      Sister function: s:NetrwBookHistRead()
3493"                      I used to do this via viminfo but that appears to
3494"                      be unreliable for long-term storage
3495"                      If g:netrw_dirhistmax is <= 0, no history or bookmarks
3496"                      will be saved.
3497fun! s:NetrwBookHistSave()
3498"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax)
3499  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3500"   call Dret("s:NetrwBookHistSave : dirhistmax=".g:netrw_dirhistmax)
3501   return
3502  endif
3503
3504  let savefile= s:NetrwHome()."/.netrwhist"
3505  1split
3506  call s:NetrwEnew()
3507  setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
3508  setl nocin noai noci magic nospell nohid wig= noaw
3509  setl ma noro write
3510  if exists("+acd") | setl noacd | endif
3511  sil! NetrwKeepj keepalt %d _
3512
3513  " save .netrwhist -- no attempt to merge
3514  sil! keepalt file .netrwhist
3515  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
3516  call setline(2,"let g:netrw_dirhist_cnt =".g:netrw_dirhist_cnt)
3517  let lastline = line("$")
3518  let cnt      = 1
3519  while cnt <= g:netrw_dirhist_cnt
3520   call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3521   let cnt= cnt + 1
3522  endwhile
3523  exe "sil! w! ".savefile
3524
3525  sil NetrwKeepj %d _
3526  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
3527   " merge and write .netrwbook
3528   let savefile= s:NetrwHome()."/.netrwbook"
3529
3530   if filereadable(s:NetrwFile(savefile))
3531    let booklist= deepcopy(g:netrw_bookmarklist)
3532    exe "sil NetrwKeepj keepalt so ".savefile
3533    for bdm in booklist
3534     if index(g:netrw_bookmarklist,bdm) == -1
3535      call add(g:netrw_bookmarklist,bdm)
3536     endif
3537    endfor
3538    call sort(g:netrw_bookmarklist)
3539   endif
3540
3541   " construct and save .netrwbook
3542   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3543   exe "sil! w! ".savefile
3544  endif
3545  let bgone= bufnr("%")
3546  q!
3547  exe "keepalt ".bgone."bwipe!"
3548
3549"  call Dret("s:NetrwBookHistSave")
3550endfun
3551
3552" ---------------------------------------------------------------------
3553" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3554"  list of the contents of a local or remote directory.  It is assumed that the
3555"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3556"  with the requested remote hostname first.
3557"    Often called via:  Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
3558fun! s:NetrwBrowse(islocal,dirname)
3559  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
3560"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
3561"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
3562"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3563"  call Dredir("ls!")
3564
3565  " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3566  " This is useful when one edits a local file, then :e ., then :Rex
3567  if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
3568   let w:netrw_rexfile= bufname("#")
3569  endif
3570
3571  " s:NetrwBrowse : initialize history {{{3
3572  if !exists("s:netrw_initbookhist")
3573   NetrwKeepj call s:NetrwBookHistRead()
3574  endif
3575
3576  " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
3577  if a:dirname !~ '^\a\{3,}://'
3578   let dirname= simplify(a:dirname)
3579  else
3580   let dirname= a:dirname
3581  endif
3582
3583  if exists("s:netrw_skipbrowse")
3584   unlet s:netrw_skipbrowse
3585"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("<slnum>"))
3586"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed")
3587   return
3588  endif
3589
3590  " s:NetrwBrowse : sanity checks: {{{3
3591  if !exists("*shellescape")
3592   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3593"   call Dret("s:NetrwBrowse : missing shellescape()")
3594   return
3595  endif
3596  if !exists("*fnameescape")
3597   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3598"   call Dret("s:NetrwBrowse : missing fnameescape()")
3599   return
3600  endif
3601
3602  " s:NetrwBrowse : save options: {{{3
3603  call s:NetrwOptionSave("w:")
3604
3605  " s:NetrwBrowse : re-instate any marked files {{{3
3606  if exists("s:netrwmarkfilelist_{bufnr('%')}")
3607"   call Decho("clearing marked files",'~'.expand("<slnum>"))
3608   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3609  endif
3610
3611  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
3612   " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3613"   call Decho("handle w:netrw_acdkeep:",'~'.expand("<slnum>"))
3614"   call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("<slnum>"))
3615   call s:NetrwLcd(dirname)
3616   call s:NetrwSafeOptions()
3617"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
3618
3619  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
3620   " s:NetrwBrowse :  remote regular file handler {{{3
3621"   call Decho("handle remote regular file: dirname<".dirname.">",'~'.expand("<slnum>"))
3622   if bufname(dirname) != ""
3623"    call Decho("edit buf#".bufname(dirname)." in win#".winnr(),'~'.expand("<slnum>"))
3624    exe "NetrwKeepj b ".bufname(dirname)
3625   else
3626    " attempt transfer of remote regular file
3627"    call Decho("attempt transfer as regular file<".dirname.">",'~'.expand("<slnum>"))
3628
3629    " remove any filetype indicator from end of dirname, except for the
3630    " "this is a directory" indicator (/).
3631    " There shouldn't be one of those here, anyway.
3632    let path= substitute(dirname,'[*=@|]\r\=$','','e')
3633"    call Decho("new path<".path.">",'~'.expand("<slnum>"))
3634    call s:RemotePathAnalysis(dirname)
3635
3636    " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3637    call s:NetrwEnew(dirname)
3638    call s:NetrwSafeOptions()
3639    setl ma noro
3640"    call Decho("setl ma noro",'~'.expand("<slnum>"))
3641    let b:netrw_curdir = dirname
3642    let url            = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3643"    call Decho("exe sil! keepalt file ".fnameescape(url)." (bt=".&bt.")",'~'.expand("<slnum>"))
3644    exe "sil! NetrwKeepj keepalt file ".fnameescape(url)
3645    exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3646    sil call netrw#NetRead(2,url)
3647    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3648"    call Decho("url<".url.">",'~'.expand("<slnum>"))
3649"    call Decho("s:path<".s:path.">",'~'.expand("<slnum>"))
3650"    call Decho("s:fname<".s:fname.">",'~'.expand("<slnum>"))
3651    if s:path =~ '.bz2'
3652     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3653    elseif s:path =~ '.gz'
3654     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3655    elseif s:path =~ '.gz'
3656     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3657    else
3658     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3659    endif
3660   endif
3661
3662   " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3663   call s:SetBufWinVars()
3664   call s:NetrwOptionRestore("w:")
3665"   call Decho("setl ma nomod",'~'.expand("<slnum>"))
3666   setl ma nomod noro
3667"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3668
3669"   call Dret("s:NetrwBrowse : file<".s:fname.">")
3670   return
3671  endif
3672
3673  " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
3674  call s:UseBufWinVars()
3675
3676  " set up some variables {{{3
3677  let b:netrw_browser_active = 1
3678  let dirname                = dirname
3679  let s:last_sort_by         = g:netrw_sort_by
3680
3681  " set up menu {{{3
3682  NetrwKeepj call s:NetrwMenu(1)
3683
3684  " get/set-up buffer {{{3
3685"  call Decho("saving position across a buffer refresh",'~'.expand("<slnum>"))
3686  let svpos  = netrw#SavePosn()
3687  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
3688
3689  " maintain markfile highlighting
3690  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3691"   call Decho("bufnr(%)=".bufnr('%'),'~'.expand("<slnum>"))
3692"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
3693   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3694  else
3695"   call Decho("2match none",'~'.expand("<slnum>"))
3696   2match none
3697  endif
3698  if reusing && line("$") > 1
3699   call s:NetrwOptionRestore("w:")
3700"   call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3701   setl noma nomod nowrap
3702"   call Decho("(set noma nomod nowrap)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3703"   call Dret("s:NetrwBrowse : re-using not-cleared buffer")
3704   return
3705  endif
3706
3707  " set b:netrw_curdir to the new directory name {{{3
3708"  call Decho("set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")",'~'.expand("<slnum>"))
3709  let b:netrw_curdir= dirname
3710  if b:netrw_curdir =~ '[/\\]$'
3711   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
3712  endif
3713  if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
3714   let b:netrw_curdir= b:netrw_curdir."/"
3715  endif
3716  if b:netrw_curdir == ''
3717   if has("amiga")
3718    " On the Amiga, the empty string connotes the current directory
3719    let b:netrw_curdir= getcwd()
3720   else
3721    " under unix, when the root directory is encountered, the result
3722    " from the preceding substitute is an empty string.
3723    let b:netrw_curdir= '/'
3724   endif
3725  endif
3726  if !a:islocal && b:netrw_curdir !~ '/$'
3727   let b:netrw_curdir= b:netrw_curdir.'/'
3728  endif
3729"  call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
3730
3731  " ------------
3732  " (local only) {{{3
3733  " ------------
3734  if a:islocal
3735"   call Decho("local only:",'~'.expand("<slnum>"))
3736
3737   " Set up ShellCmdPost handling.  Append current buffer to browselist
3738   call s:LocalFastBrowser()
3739
3740  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3741   if !g:netrw_keepdir
3742"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
3743"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("<slnum>"))
3744    if !exists("&l:acd") || !&l:acd
3745     call s:NetrwLcd(b:netrw_curdir)
3746    endif
3747   endif
3748
3749  " --------------------------------
3750  " remote handling: {{{3
3751  " --------------------------------
3752  else
3753"   call Decho("remote only:",'~'.expand("<slnum>"))
3754
3755   " analyze dirname and g:netrw_list_cmd {{{3
3756"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>"))
3757   if dirname =~ "^NetrwTreeListing\>"
3758    let dirname= b:netrw_curdir
3759"    call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>"))
3760   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3761    let dirname= substitute(b:netrw_curdir,'\\','/','g')
3762    if dirname !~ '/$'
3763     let dirname= dirname.'/'
3764    endif
3765    let b:netrw_curdir = dirname
3766"    call Decho("(liststyle is TREELIST) dirname<".dirname.">",'~'.expand("<slnum>"))
3767   else
3768    let dirname = substitute(dirname,'\\','/','g')
3769"    call Decho("(normal) dirname<".dirname.">",'~'.expand("<slnum>"))
3770   endif
3771
3772   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3773   if dirname !~ dirpat
3774    if !exists("g:netrw_quiet")
3775     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3776    endif
3777    NetrwKeepj call s:NetrwOptionRestore("w:")
3778"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3779    setl noma nomod nowrap
3780"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3781"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
3782    return
3783   endif
3784   let b:netrw_curdir= dirname
3785"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("<slnum>"))
3786  endif  " (additional remote handling)
3787
3788  " -----------------------
3789  " Directory Listing: {{{3
3790  " -----------------------
3791  NetrwKeepj call s:NetrwMaps(a:islocal)
3792  NetrwKeepj call s:NetrwCommands(a:islocal)
3793  NetrwKeepj call s:PerformListing(a:islocal)
3794
3795  " If there is a rexposn: restore position with rexposn
3796  " Otherwise            : set rexposn
3797  if exists("s:rexposn_".bufnr("%"))
3798   NetrwKeepj call netrw#RestorePosn(s:rexposn_{bufnr('%')})
3799  else
3800   NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
3801  endif
3802  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
3803   let &l:bexpr= "netrw#BalloonHelp()"
3804"   call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>"))
3805   setl beval
3806  endif
3807  call s:NetrwOptionRestore("w:")
3808"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3809
3810  " restore position
3811  if reusing
3812"   call Decho("reusing=".reusing.": restoring position across buffer refresh",'~'.expand("<slnum>"))
3813   call netrw#RestorePosn(svpos)
3814  endif
3815
3816  " The s:LocalBrowseRefresh() function is called by an autocmd
3817  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow, medium speed).
3818  " However, s:NetrwBrowse() causes the FocusGained event to fire the firstt time.
3819"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3820"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3821"  call Dret("s:NetrwBrowse : did PerformListing  ft<".&ft.">")
3822  return
3823endfun
3824
3825" ---------------------------------------------------------------------
3826" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
3827" may not apply correctly; ie. netrw's idea of the current directory may
3828" differ from vim's.  This function insures that netrw's idea of the current
3829" directory is used.
3830fun! s:NetrwFile(fname)
3831"  call Dfunc("s:NetrwFile(fname<".a:fname.">)")
3832
3833  if g:netrw_keepdir
3834   " vim's idea of the current directory possibly may differ from netrw's
3835   if !exists("b:netrw_curdir")
3836    let b:netrw_curdir= getcwd()
3837   endif
3838
3839   if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
3840    if a:fname =~ '^\' || a:fname =~ '^\a:\'
3841     " windows, but full path given
3842     let ret= a:fname
3843"     call Decho("windows+full path: isdirectory(".a:fname.")",'~'.expand("<slnum>"))
3844    else
3845     " windows, relative path given
3846     let ret= s:ComposePath(b:netrw_curdir,a:fname)
3847"     call Decho("windows+rltv path: isdirectory(".a:fname.")",'~'.expand("<slnum>"))
3848    endif
3849
3850   elseif a:fname =~ '^/'
3851    " not windows, full path given
3852    let ret= a:fname
3853"    call Decho("unix+full path: isdirectory(".a:fname.")",'~'.expand("<slnum>"))
3854   else
3855    " not windows, relative path given
3856    let ret= s:ComposePath(b:netrw_curdir,a:fname)
3857"    call Decho("unix+rltv path: isdirectory(".a:fname.")",'~'.expand("<slnum>"))
3858   endif
3859  else
3860   " vim and netrw agree on the current directory
3861   let ret= a:fname
3862"   call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
3863  endif
3864
3865"  call Dret("s:NetrwFile ".ret)
3866  return ret
3867endfun
3868
3869" ---------------------------------------------------------------------
3870" s:NetrwFileInfo: supports qf (query for file information) {{{2
3871fun! s:NetrwFileInfo(islocal,fname)
3872"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
3873  let ykeep= @@
3874  if a:islocal
3875   if (has("unix") || has("macunix")) && executable("/bin/ls")
3876
3877    if getline(".") == "../"
3878     echo system("/bin/ls -lsad ".s:ShellEscape(".."))
3879"     call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
3880
3881    elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
3882     echo system("/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir))
3883"     call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
3884
3885    elseif exists("b:netrw_curdir")
3886      echo system("/bin/ls -lsad ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
3887"      call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
3888
3889    else
3890"     call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
3891     echo system("/bin/ls -lsad ".s:ShellEscape(s:NetrwFile(a:fname)))
3892"     call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
3893    endif
3894   else
3895    " use vim functions to return information about file below cursor
3896"    call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
3897    if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
3898     let fname= substitute(a:fname,".$","","")
3899    else
3900     let fname= a:fname
3901    endif
3902    let t  = getftime(s:NetrwFile(fname))
3903    let sz = getfsize(s:NetrwFile(fname))
3904    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
3905"    call Decho("fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
3906   endif
3907  else
3908   echo "sorry, \"qf\" not supported yet for remote files"
3909  endif
3910  let @@= ykeep
3911"  call Dret("s:NetrwFileInfo")
3912endfun
3913
3914" ---------------------------------------------------------------------
3915" s:NetrwGetBuffer: {{{2
3916"   returns 0=cleared buffer
3917"           1=re-used buffer (buffer not cleared)
3918fun! s:NetrwGetBuffer(islocal,dirname)
3919"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
3920"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
3921  let dirname= a:dirname
3922
3923  " re-use buffer if possible {{{3
3924"  call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
3925  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
3926   " find NetrwTreeList buffer if there is one
3927"   call Decho("case liststyle=treelist: find NetrwTreeList buffer if there is one",'~'.expand("<slnum>"))
3928   if exists("w:netrw_treebufnr") && w:netrw_treebufnr > 0
3929"    call Decho("  re-using w:netrw_treebufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
3930    let eikeep= &ei
3931    setl ei=all
3932    exe "sil! keepj noswapfile keepalt b ".w:netrw_treebufnr
3933    let &ei= eikeep
3934    setl ma
3935    sil! NetrwKeepj %d _
3936"    call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
3937"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3938"    call Dret("s:NetrwGetBuffer 0<buffer cleared> : bufnum#".w:netrw_treebufnr."<NetrwTreeListing>")
3939    return 0
3940   endif
3941   let bufnum= -1
3942"   call Decho("  liststyle=TREE but w:netrw_treebufnr doesn't exist",'~'.expand("<slnum>"))
3943
3944  else
3945   " find buffer number of buffer named precisely the same as dirname {{{3
3946"   call Decho("case listtyle not treelist: find buffer numnber of buffer named precisely the same as dirname--",'~'.expand("<slnum>"))
3947"   call Dredir("(NetrwGetBuffer) ls!","ls!")
3948
3949   " get dirname and associated buffer number
3950   let bufnum  = bufnr(escape(dirname,'\'))
3951"   call Decho("  find buffer<".dirname.">'s number ",'~'.expand("<slnum>"))
3952"   call Decho("  bufnr(dirname<".escape(dirname,'\').">)=".bufnum,'~'.expand("<slnum>"))
3953
3954   if bufnum < 0 && dirname !~ '/$'
3955    " try appending a trailing /
3956"    call Decho("  try appending a trailing / to dirname<".dirname.">",'~'.expand("<slnum>"))
3957    let bufnum= bufnr(escape(dirname.'/','\'))
3958    if bufnum > 0
3959     let dirname= dirname.'/'
3960    endif
3961   endif
3962
3963   if bufnum < 0 && dirname =~ '/$'
3964    " try removing a trailing /
3965"    call Decho("  try removing a trailing / from dirname<".dirname.">",'~'.expand("<slnum>"))
3966    let bufnum= bufnr(escape(substitute(dirname,'/$','',''),'\'))
3967    if bufnum > 0
3968     let dirname= substitute(dirname,'/$','','')
3969    endif
3970   endif
3971
3972"   call Decho("  findbuf1: bufnum=bufnr('".dirname."')=".bufnum." bufname(".bufnum.")<".bufname(bufnum)."> (initial)",'~'.expand("<slnum>"))
3973   " note: !~ was used just below, but that means using ../ to go back would match (ie. abc/def/  and abc/ matches)
3974   if bufnum > 0 && bufname(bufnum) != dirname && bufname(bufnum) != '.'
3975    " handle approximate matches
3976"    call Decho("  handling approx match: bufnum#".bufnum.">0 AND bufname<".bufname(bufnum).">!=dirname<".dirname."> AND bufname(".bufnum.")!='.'",'~'.expand("<slnum>"))
3977    let ibuf    = 1
3978    let buflast = bufnr("$")
3979"    call Decho("  findbuf2: buflast=bufnr($)=".buflast,'~'.expand("<slnum>"))
3980    while ibuf <= buflast
3981     let bname= substitute(bufname(ibuf),'\\','/','g')
3982     let bname= substitute(bname,'.\zs/$','','')
3983"     call Decho("  findbuf3: while [ibuf=",ibuf."]<=[buflast=".buflast."]: dirname<".dirname."> bname=bufname(".ibuf.")<".bname.">",'~'.expand("<slnum>"))
3984     if bname != '' && dirname =~ '/'.bname.'/\=$' && dirname !~ '^/'
3985      " bname is not empty
3986      " dirname ends with bname,
3987      " dirname doesn't start with /, so its not a absolute path
3988"      call Decho("  findbuf3a: passes test 1 : dirname<".dirname.'> =~ /'.bname.'/\=$ && dirname !~ ^/','~'.expand("<slnum>"))
3989      break
3990     endif
3991     if bname =~ '^'.dirname.'/\=$'
3992      " bname begins with dirname
3993"      call Decho('  findbuf3b: passes test 2 : bname<'.bname.'>=~^'.dirname.'/\=$','~'.expand("<slnum>"))
3994      break
3995     endif
3996     if dirname =~ '^'.bname.'/$'
3997"      call Decho('  findbuf3c: passes test 3 : dirname<'.dirname.'>=~^'.bname.'/$','~'.expand("<slnum>"))
3998      break
3999     endif
4000     if bname != '' && dirname =~ '/'.bname.'$' && bname == bufname("%") && line("$") == 1
4001"      call Decho('  findbuf3d: passes test 4 : dirname<'.dirname.'>=~ /'.bname.'$','~'.expand("<slnum>"))
4002      break
4003     endif
4004     let ibuf= ibuf + 1
4005    endwhile
4006    if ibuf > buflast
4007     let bufnum= -1
4008    else
4009     let bufnum= ibuf
4010    endif
4011"    call Decho("  findbuf4: bufnum=".bufnum." (ibuf=".ibuf." buflast=".buflast.")",'~'.expand("<slnum>"))
4012   endif
4013  endif
4014
4015  " get enew buffer and name it -or- re-use buffer {{{3
4016  if bufnum < 0 || !bufexists(bufnum)   " get enew buffer and name it
4017"   call Decho("--get enew buffer and name it  (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4018   call s:NetrwEnew(dirname)
4019"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4020   " name the buffer
4021   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4022    " Got enew buffer; transform into a NetrwTreeListing
4023"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4024    if !exists("s:netrw_treelistnum")
4025     let s:netrw_treelistnum= 1
4026    else
4027     let s:netrw_treelistnum= s:netrw_treelistnum + 1
4028    endif
4029    let w:netrw_treebufnr= bufnr("%")
4030"    call Decho("  exe sil! keepalt file NetrwTreeListing ".fnameescape(s:netrw_treelistnum),'~'.expand("<slnum>"))
4031    exe 'sil! keepalt file NetrwTreeListing\ '.fnameescape(s:netrw_treelistnum)
4032    setl bt=nofile noswf
4033    nnoremap <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
4034    nnoremap <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
4035    nnoremap <silent> <buffer> [[       :sil call <SID>TreeListMove('[')<cr>
4036    nnoremap <silent> <buffer> ]]       :sil call <SID>TreeListMove(']')<cr>
4037"    call Decho("  tree listing#".s:netrw_treelistnum." bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
4038   else
4039"    let v:errmsg   = "" " Decho
4040    let escdirname = fnameescape(dirname)
4041"    call Decho("  errmsg<".v:errmsg."> bufnr(escdirname<".escdirname.">)=".bufnr(escdirname)." bufname()<".bufname(bufnr(escdirname)).">",'~'.expand("<slnum>"))
4042"    call Decho('  exe sil! keepalt file '.escdirname,'~'.expand("<slnum>"))
4043"    let v:errmsg= "" " Decho
4044    exe 'sil! keepj keepalt file '.escdirname
4045"    call Decho("  errmsg<".v:errmsg."> bufnr(".escdirname.")=".bufnr(escdirname)."<".bufname(bufnr(escdirname)).">",'~'.expand("<slnum>"))
4046   endif
4047"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4048
4049  else " Re-use the buffer
4050"   call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4051   let eikeep= &ei
4052   setl ei=all
4053   if getline(2) =~ '^" Netrw Directory Listing'
4054"    call Decho("  getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>"))
4055    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4056   else
4057"    call Decho("  getline(2)<".getline(2).'> does not match "Netrw Directory Listing" : using b '.bufnum,'~'.expand("<slnum>"))
4058    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4059   endif
4060"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
4061   if bufname("%") == '.'
4062"    call Decho("exe sil! keepalt file ".fnameescape(getcwd()),'~'.expand("<slnum>"))
4063    exe "sil! NetrwKeepj keepalt file ".fnameescape(getcwd())
4064   endif
4065   let &ei= eikeep
4066
4067   if line("$") <= 1 && getline(1) == ""
4068    " empty buffer
4069    NetrwKeepj call s:NetrwListSettings(a:islocal)
4070"    call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4071"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4072"    call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4073    return 0
4074
4075   elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4076"    call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4077    NetrwKeepj call s:NetrwListSettings(a:islocal)
4078    sil NetrwKeepj %d _
4079"    call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4080"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4081"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4082    return 0
4083
4084   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4085"    call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4086"    call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4087    sil NetrwKeepj %d _
4088    NetrwKeepj call s:NetrwListSettings(a:islocal)
4089"    call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4090"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4091"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4092    return 0
4093
4094   else
4095"    call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4096"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4097"    call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4098    return 1
4099   endif
4100  endif
4101
4102  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4103  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
4104  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
4105  "  med    1         D      H
4106  "  fast   2         H      H
4107"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
4108  let fname= expand("%")
4109  NetrwKeepj call s:NetrwListSettings(a:islocal)
4110"  call Decho("exe sil! keepalt file ".fnameescape(fname),'~'.expand("<slnum>"))
4111  exe "sil! NetrwKeepj keepalt file ".fnameescape(fname)
4112
4113  " delete all lines from buffer {{{3
4114"  call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4115"  call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4116  sil! keepalt NetrwKeepj %d _
4117
4118"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4119"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4120"  call Dret("s:NetrwGetBuffer 0<cleared buffer>")
4121  return 0
4122endfun
4123
4124" ---------------------------------------------------------------------
4125" s:NetrwGetcwd: get the current directory. {{{2
4126"   Change backslashes to forward slashes, if any.
4127"   If doesc is true, escape certain troublesome characters
4128fun! s:NetrwGetcwd(doesc)
4129"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
4130  let curdir= substitute(getcwd(),'\\','/','ge')
4131  if curdir !~ '[\/]$'
4132   let curdir= curdir.'/'
4133  endif
4134  if a:doesc
4135   let curdir= fnameescape(curdir)
4136  endif
4137"  call Dret("NetrwGetcwd <".curdir.">")
4138  return curdir
4139endfun
4140
4141" ---------------------------------------------------------------------
4142"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4143fun! s:NetrwGetWord()
4144"  call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4145"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4146  let keepsol= &l:sol
4147  setl nosol
4148
4149  call s:UseBufWinVars()
4150
4151  " insure that w:netrw_liststyle is set up
4152  if !exists("w:netrw_liststyle")
4153   if exists("g:netrw_liststyle")
4154    let w:netrw_liststyle= g:netrw_liststyle
4155   else
4156    let w:netrw_liststyle= s:THINLIST
4157   endif
4158"   call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
4159  endif
4160
4161  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4162   " Active Banner support
4163"   call Decho("active banner handling",'~'.expand("<slnum>"))
4164   NetrwKeepj norm! 0
4165   let dirname= "./"
4166   let curline= getline('.')
4167
4168   if curline =~ '"\s*Sorted by\s'
4169    NetrwKeepj norm s
4170    let s:netrw_skipbrowse= 1
4171    echo 'Pressing "s" also works'
4172
4173   elseif curline =~ '"\s*Sort sequence:'
4174    let s:netrw_skipbrowse= 1
4175    echo 'Press "S" to edit sorting sequence'
4176
4177   elseif curline =~ '"\s*Quick Help:'
4178    NetrwKeepj norm ?
4179    let s:netrw_skipbrowse= 1
4180
4181   elseif curline =~ '"\s*\%(Hiding\|Showing\):'
4182    NetrwKeepj norm a
4183    let s:netrw_skipbrowse= 1
4184    echo 'Pressing "a" also works'
4185
4186   elseif line("$") > w:netrw_bannercnt
4187    exe 'sil NetrwKeepj '.w:netrw_bannercnt
4188   endif
4189
4190  elseif w:netrw_liststyle == s:THINLIST
4191"   call Decho("thin column handling",'~'.expand("<slnum>"))
4192   NetrwKeepj norm! 0
4193   let dirname= substitute(getline('.'),'\t -->.*$','','')
4194
4195  elseif w:netrw_liststyle == s:LONGLIST
4196"   call Decho("long column handling",'~'.expand("<slnum>"))
4197   NetrwKeepj norm! 0
4198   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
4199
4200  elseif w:netrw_liststyle == s:TREELIST
4201"   call Decho("treelist handling",'~'.expand("<slnum>"))
4202   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4203   let dirname= substitute(dirname,'\t -->.*$','','')
4204
4205  else
4206"   call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4207   let dirname= getline('.')
4208
4209   if !exists("b:netrw_cpf")
4210    let b:netrw_cpf= 0
4211    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
4212    call histdel("/",-1)
4213"   "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4214   endif
4215
4216"   call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4217   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4218"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4219"   call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4220   if filestart == 0
4221    NetrwKeepj norm! 0ma
4222   else
4223    call cursor(line("."),filestart+1)
4224    NetrwKeepj norm! ma
4225   endif
4226   let rega= @a
4227   let eofname= filestart + b:netrw_cpf + 1
4228   if eofname <= col("$")
4229    call cursor(line("."),filestart+b:netrw_cpf+1)
4230    NetrwKeepj norm! "ay`a
4231   else
4232    NetrwKeepj norm! "ay$
4233   endif
4234   let dirname = @a
4235   let @a      = rega
4236"   call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4237   let dirname= substitute(dirname,'\s\+$','','e')
4238"   call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4239  endif
4240
4241  " symlinks are indicated by a trailing "@".  Remove it before further processing.
4242  let dirname= substitute(dirname,"@$","","")
4243
4244  " executables are indicated by a trailing "*".  Remove it before further processing.
4245  let dirname= substitute(dirname,"\*$","","")
4246
4247  let &l:sol= keepsol
4248
4249"  call Dret("s:NetrwGetWord <".dirname.">")
4250  return dirname
4251endfun
4252
4253" ---------------------------------------------------------------------
4254" s:NetrwListSettings: make standard settings for a netrw listing {{{2
4255fun! s:NetrwListSettings(islocal)
4256"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4257"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4258  let fname= bufname("%")
4259"  "  call Decho("(NetrwListSettings) setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
4260  setl bt=nofile nobl ma nonu nowrap noro nornu
4261"  call Decho("(NetrwListSettings) exe sil! keepalt file ".fnameescape(fname),'~'.expand("<slnum>"))
4262  exe "sil! keepalt file ".fnameescape(fname)
4263  if g:netrw_use_noswf
4264   setl noswf
4265  endif
4266"  call Dredir("ls!")
4267"  call Decho("(NetrwListSettings) exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
4268  exe "setl ts=".(g:netrw_maxfilenamelen+1)
4269  setl isk+=.,~,-
4270  if g:netrw_fastbrowse > a:islocal
4271   setl bh=hide
4272  else
4273   setl bh=delete
4274  endif
4275"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4276"  call Dret("s:NetrwListSettings")
4277endfun
4278
4279" ---------------------------------------------------------------------
4280"  s:NetrwListStyle: {{{2
4281"  islocal=0: remote browsing
4282"         =1: local browsing
4283fun! s:NetrwListStyle(islocal)
4284"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
4285
4286  let ykeep             = @@
4287  let fname             = s:NetrwGetWord()
4288  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
4289  let svpos            = netrw#SavePosn()
4290  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
4291"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
4292"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>"))
4293"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
4294
4295  if w:netrw_liststyle == s:THINLIST
4296   " use one column listing
4297"   call Decho("use one column list",'~'.expand("<slnum>"))
4298   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4299
4300  elseif w:netrw_liststyle == s:LONGLIST
4301   " use long list
4302"   call Decho("use long list",'~'.expand("<slnum>"))
4303   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
4304
4305  elseif w:netrw_liststyle == s:WIDELIST
4306   " give wide list
4307"   call Decho("use wide list",'~'.expand("<slnum>"))
4308   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4309
4310  elseif w:netrw_liststyle == s:TREELIST
4311"   call Decho("use tree list",'~'.expand("<slnum>"))
4312   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4313
4314  else
4315   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4316   let g:netrw_liststyle = s:THINLIST
4317   let w:netrw_liststyle = g:netrw_liststyle
4318   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
4319  endif
4320  setl ma noro
4321"  call Decho("setl ma noro",'~'.expand("<slnum>"))
4322
4323  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
4324"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4325  sil! NetrwKeepj %d _
4326  " following prevents tree listing buffer from being marked "modified"
4327"  call Decho("setl nomod",'~'.expand("<slnum>"))
4328  setl nomod
4329"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4330
4331  " refresh the listing
4332"  call Decho("refresh the listing",'~'.expand("<slnum>"))
4333  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4334  NetrwKeepj call s:NetrwCursor()
4335
4336  " restore position; keep cursor on the filename
4337  NetrwKeepj call netrw#RestorePosn(svpos)
4338  let @@= ykeep
4339
4340"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
4341endfun
4342
4343" ---------------------------------------------------------------------
4344" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4345fun! s:NetrwBannerCtrl(islocal)
4346"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
4347
4348  let ykeep= @@
4349  " toggle the banner (enable/suppress)
4350  let g:netrw_banner= !g:netrw_banner
4351
4352  " refresh the listing
4353  let svpos= netrw#SavePosn()
4354  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4355
4356  " keep cursor on the filename
4357  let fname= s:NetrwGetWord()
4358  sil NetrwKeepj $
4359  let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4360"  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4361  if result <= 0 && exists("w:netrw_bannercnt")
4362   exe "NetrwKeepj ".w:netrw_bannercnt
4363  endif
4364  let @@= ykeep
4365"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
4366endfun
4367
4368" ---------------------------------------------------------------------
4369" s:NetrwBookmark: supports :NetrwMB[!] [file]s                 {{{2
4370"
4371"  No bang: enters files/directories into Netrw's bookmark system
4372"   No argument and in netrw buffer:
4373"     if there are marked files: bookmark marked files
4374"     otherwise                : bookmark file/directory under cursor
4375"   No argument and not in netrw buffer: bookmarks current open file
4376"   Has arguments: globs them individually and bookmarks them
4377"
4378"  With bang: deletes files/directories from Netrw's bookmark system
4379fun! s:NetrwBookmark(del,...)
4380"  call Dfunc("s:NetrwBookmark(del=".a:del.",...) a:0=".a:0)
4381  if a:0 == 0
4382   if &ft == "netrw"
4383    let curbufnr = bufnr("%")
4384
4385    if exists("s:netrwmarkfilelist_{curbufnr}")
4386     " for every filename in the marked list
4387"     call Decho("bookmark every filename in marked list",'~'.expand("<slnum>"))
4388     let svpos  = netrw#SavePosn()
4389     let islocal= expand("%") !~ '^\a\{3,}://'
4390     for fname in s:netrwmarkfilelist_{curbufnr}
4391      if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4392     endfor
4393     let curdir  = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4394     call s:NetrwUnmarkList(curbufnr,curdir)
4395     NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./'))
4396     NetrwKeepj call netrw#RestorePosn(svpos)
4397    else
4398     let fname= s:NetrwGetWord()
4399     if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4400    endif
4401
4402   else
4403    " bookmark currently open file
4404"    call Decho("bookmark currently open file",'~'.expand("<slnum>"))
4405    let fname= expand("%")
4406    if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4407   endif
4408
4409  else
4410   " bookmark specified files
4411   "  attempts to infer if working remote or local
4412   "  by deciding if the current file begins with an url
4413   "  Globbing cannot be done remotely.
4414   let islocal= expand("%") !~ '^\a\{3,}://'
4415"   call Decho("bookmark specified file".((a:0>1)? "s" : ""),'~'.expand("<slnum>"))
4416   let i = 1
4417   while i <= a:0
4418    if islocal
4419     if v:version == 704 && has("patch656")
4420      let mbfiles= glob(a:{i},0,1,1)
4421     else
4422      let mbfiles= glob(a:{i},0,1)
4423     endif
4424    else
4425     let mbfiles= [a:{i}]
4426    endif
4427"    call Decho("mbfiles".string(mbfiles),'~'.expand("<slnum>"))
4428    for mbfile in mbfiles
4429"     call Decho("mbfile<".mbfile.">",'~'.expand("<slnum>"))
4430     if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4431    endfor
4432    let i= i + 1
4433   endwhile
4434  endif
4435
4436  " update the menu
4437  call s:NetrwBookmarkMenu()
4438
4439"  call Dret("s:NetrwBookmark")
4440endfun
4441
4442" ---------------------------------------------------------------------
4443" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4444"                      .2.[cnt] for bookmarks, and
4445"                      .3.[cnt] for history
4446"                      (see s:NetrwMenu())
4447fun! s:NetrwBookmarkMenu()
4448  if !exists("s:netrw_menucnt")
4449   return
4450  endif
4451"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhist_cnt." menucnt=".s:netrw_menucnt)
4452
4453  " the following test assures that gvim is running, has menus available, and has menus enabled.
4454  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
4455   if exists("g:NetrwTopLvlMenu")
4456"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4457    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4458    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4459   endif
4460   if !exists("s:netrw_initbookhist")
4461    call s:NetrwBookHistRead()
4462   endif
4463
4464   " show bookmarked places
4465   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4466    let cnt= 1
4467    for bmd in g:netrw_bookmarklist
4468"     call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd,'~'.expand("<slnum>"))
4469     let bmd= escape(bmd,g:netrw_menu_escape)
4470
4471     " show bookmarks for goto menu
4472     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
4473
4474     " show bookmarks for deletion menu
4475     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
4476     let cnt= cnt + 1
4477    endfor
4478
4479   endif
4480
4481   " show directory browsing history
4482   if g:netrw_dirhistmax > 0
4483    let cnt     = g:netrw_dirhist_cnt
4484    let first   = 1
4485    let histcnt = 0
4486    while ( first || cnt != g:netrw_dirhist_cnt )
4487     let histcnt  = histcnt + 1
4488     let priority = g:netrw_dirhist_cnt + histcnt
4489     if exists("g:netrw_dirhist_{cnt}")
4490      let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4491"     call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir,'~'.expand("<slnum>"))
4492      exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
4493     endif
4494     let first = 0
4495     let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
4496     if cnt < 0
4497      let cnt= cnt + g:netrw_dirhistmax
4498     endif
4499    endwhile
4500   endif
4501
4502  endif
4503"  call Dret("NetrwBookmarkMenu")
4504endfun
4505
4506" ---------------------------------------------------------------------
4507"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4508"                       directory and a new directory name.  Also, if the
4509"                       "new directory name" is actually a file,
4510"                       NetrwBrowseChgDir() edits the file.
4511fun! s:NetrwBrowseChgDir(islocal,newdir,...)
4512"  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 : "").">")
4513"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4514
4515  let ykeep= @@
4516  if !exists("b:netrw_curdir")
4517   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4518   " and the current window is the NetrwMessage window.
4519   let @@= ykeep
4520"   call Decho("b:netrw_curdir doesn't exist!",'~'.expand("<slnum>"))
4521"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
4522"   call Dredir("ls!")
4523"   call Dret("s:NetrwBrowseChgDir")
4524   return
4525  endif
4526
4527  " NetrwBrowseChgDir: save options and initialize {{{3
4528"  call Decho("saving options",'~'.expand("<slnum>"))
4529  NetrwKeepj call s:NetrwOptionSave("s:")
4530  NetrwKeepj call s:NetrwSafeOptions()
4531  let nbcd_curpos                = netrw#SavePosn()
4532  let s:nbcd_curpos_{bufnr('%')} = nbcd_curpos
4533"  call Decho("setting s:nbcd_curpos_".bufnr('%')." to SavePosn",'~'.expand("<slnum>"))
4534  if (has("win32") || has("win95") || has("win64") || has("win16"))
4535   let dirname = substitute(b:netrw_curdir,'\\','/','ge')
4536  else
4537   let dirname = b:netrw_curdir
4538  endif
4539  let newdir    = a:newdir
4540  let dolockout = 0
4541  let dorestore = 1
4542"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
4543
4544  " ignore <cr>s when done in the banner
4545"  call Decho('ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("<slnum>"))
4546  if g:netrw_banner
4547"   call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>"))
4548   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4549    if getline(".") =~ 'Quick Help'
4550"     call Decho("#1: quickhelp=".g:netrw_quickhelp." ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4551     let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4552"     call Decho("#2: quickhelp=".g:netrw_quickhelp." ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4553     setl ma noro nowrap
4554     NetrwKeepj call setline(line('.'),'"   Quick Help: <F1>:help  '.s:QuickHelp[g:netrw_quickhelp])
4555     setl noma nomod nowrap
4556     NetrwKeepj call netrw#RestorePosn(nbcd_curpos)
4557     NetrwKeepj call s:NetrwOptionRestore("s:")
4558"     call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4559    endif
4560   endif
4561"  else " Decho
4562"   call Decho("(s:NetrwBrowseChgdir) g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("<slnum>"))
4563  endif
4564
4565  " set up o/s-dependent directory recognition pattern
4566  if has("amiga")
4567   let dirpat= '[\/:]$'
4568  else
4569   let dirpat= '[\/]$'
4570  endif
4571"  call Decho("set up o/s-dependent directory recognition pattern: dirname<".dirname.">  dirpat<".dirpat.">",'~'.expand("<slnum>"))
4572
4573  if dirname !~ dirpat
4574   " apparently vim is "recognizing" that it is in a directory and
4575   " is removing the trailing "/".  Bad idea, so let's put it back.
4576   let dirname= dirname.'/'
4577"   call Decho("adjusting dirname<".dirname.'>  (put trailing "/" back)','~'.expand("<slnum>"))
4578  endif
4579
4580"  "  call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>"))
4581  if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
4582   " ------------------------------
4583   " NetrwBrowseChgDir: edit a file {{{3
4584   " ------------------------------
4585"   call Decho('edit-a-file: case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>"))
4586
4587   " save position for benefit of Rexplore
4588   let s:rexposn_{bufnr("%")}= netrw#SavePosn()
4589"   call Decho("edit-a-file: setting s:rexposn_".bufnr("%")."<".bufname("%")."> to SavePosn",'~'.expand("<slnum>"))
4590"   call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
4591"   call Decho("edit-a-file: w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a')." w:netrw_treedict:".(exists("w:netrw_treedict")? "exists" : 'n/a')." newdir<".newdir.">",'~'.expand("<slnum>"))
4592
4593   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4594"    call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("<slnum>"))
4595"    call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("<slnum>"))
4596    let dirname= s:NetrwTreeDir(a:islocal)
4597    if dirname =~ '/$'
4598     let dirname= dirname.newdir
4599    else
4600     let dirname= dirname."/".newdir
4601    endif
4602"    call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>"))
4603"    call Decho("edit-a-file: tree listing",'~'.expand("<slnum>"))
4604   elseif newdir =~ '^\(/\|\a:\)'
4605    let dirname= newdir
4606   else
4607    let dirname= s:ComposePath(dirname,newdir)
4608   endif
4609"   call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>"))
4610   " this lets netrw#BrowseX avoid the edit
4611   if a:0 < 1
4612"    call Decho("edit-a-file: set up windows for editing<".fnameescape(dirname).">  didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist"),'~'.expand("<slnum>"))
4613    NetrwKeepj call s:NetrwOptionRestore("s:")
4614    if !exists("s:didsplit")
4615"     call Decho("edit-a-file: s:didsplit does not exist; g:netrw_browse_split=".string(g:netrw_browse_split)." win#".winnr(),'~'.expand("<slnum>"))
4616     if type(g:netrw_browse_split) == 3
4617      " open file in server
4618      " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4619"      call Decho("edit-a-file: open file in server",'~'.expand("<slnum>"))
4620      call s:NetrwServerEdit(a:islocal,dirname)
4621"      call Dret("s:NetrwBrowseChgDir")
4622      return
4623     elseif g:netrw_browse_split == 1
4624      " horizontally splitting the window first
4625"      call Decho("edit-a-file: horizontally splitting window prior to edit",'~'.expand("<slnum>"))
4626      keepalt new
4627      if !&ea
4628       keepalt wincmd _
4629      endif
4630     elseif g:netrw_browse_split == 2
4631      " vertically splitting the window first
4632"      call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>"))
4633      keepalt rightb vert new
4634      if !&ea
4635       keepalt wincmd |
4636      endif
4637     elseif g:netrw_browse_split == 3
4638      " open file in new tab
4639"      call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>"))
4640      keepalt tabnew
4641     elseif g:netrw_browse_split == 4
4642      " act like "P" (ie. open previous window)
4643"      call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>"))
4644      if s:NetrwPrevWinOpen(2) == 3
4645       let @@= ykeep
4646"       call Dret("s:NetrwBrowseChgDir")
4647       return
4648      endif
4649     else
4650      " handling a file, didn't split, so remove menu
4651"      call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>"))
4652      call s:NetrwMenu(0)
4653      " optional change to window
4654      if g:netrw_chgwin >= 1
4655"       call Decho("edit-a-file: changing window to #".g:netrw_chgwin,'~'.expand("<slnum>"))
4656       if winnr("$")+1 == g:netrw_chgwin
4657	" if g:netrw_chgwin is set to one more than the last window, then
4658	" vertically split the last window to make that window available.
4659	let curwin= winnr()
4660	exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4661	vs
4662	exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4663       endif
4664       exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4665      endif
4666     endif
4667    endif
4668
4669    " the point where netrw actually edits the (local) file
4670    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4671    " no keepalt to support  :e #  to return to a directory listing
4672    if a:islocal
4673"     call Decho("edit-a-file: edit local file: exe e! ".fnameescape(dirname),'~'.expand("<slnum>"))
4674     " some like c-^ to return to the last edited file
4675     " others like c-^ to return to the netrw buffer
4676     if exists("g:netrw_altfile") && g:netrw_altfile
4677      exe "NetrwKeepj keepalt e! ".fnameescape(dirname)
4678     else
4679      exe "NetrwKeepj e! ".fnameescape(dirname)
4680     endif
4681"     call Decho("edit-a-file: after e! ".dirname.": hidden=".&hidden." bufhidden<".&bufhidden."> mod=".&mod,'~'.expand("<slnum>"))
4682     call s:NetrwCursor()
4683     if &hidden || &bufhidden == "hide"
4684      " file came from vim's hidden storage.  Don't "restore" options with it.
4685      let dorestore= 0
4686     endif
4687    else
4688"     call Decho("edit-a-file: remote file: NetrwBrowse will edit it",'~'.expand("<slnum>"))
4689    endif
4690    let dolockout= 1
4691
4692    " handle g:Netrw_funcref -- call external-to-netrw functions
4693    "   This code will handle g:Netrw_funcref as an individual function reference
4694    "   or as a list of function references.  It will ignore anything that's not
4695    "   a function reference.  See  :help Funcref  for information about function references.
4696    if exists("g:Netrw_funcref")
4697"     call Decho("edit-a-file: handle optional Funcrefs",'~'.expand("<slnum>"))
4698     if type(g:Netrw_funcref) == 2
4699"      call Decho("edit-a-file: handling a g:Netrw_funcref",'~'.expand("<slnum>"))
4700      NetrwKeepj call g:Netrw_funcref()
4701     elseif type(g:Netrw_funcref) == 3
4702"      call Decho("edit-a-file: handling a list of g:Netrw_funcrefs",'~'.expand("<slnum>"))
4703      for Fncref in g:Netrw_funcref
4704       if type(FncRef) == 2
4705        NetrwKeepj call FncRef()
4706       endif
4707      endfor
4708     endif
4709    endif
4710   endif
4711
4712  elseif newdir =~ '^/'
4713   " ----------------------------------------------------
4714   " NetrwBrowseChgDir: just go to the new directory spec {{{3
4715   " ----------------------------------------------------
4716"   call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("<slnum>"))
4717   let dirname = newdir
4718   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4719   NetrwKeepj call s:NetrwOptionRestore("s:")
4720   norm! m`
4721
4722  elseif newdir == './'
4723   " ---------------------------------------------
4724   " NetrwBrowseChgDir: refresh the directory list {{{3
4725   " ---------------------------------------------
4726"   call Decho('refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("<slnum>"))
4727   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4728   norm! m`
4729
4730  elseif newdir == '../'
4731   " --------------------------------------
4732   " NetrwBrowseChgDir: go up one directory {{{3
4733   " --------------------------------------
4734"   call Decho('go-up: case "go up one directory": newdir == "../"','~'.expand("<slnum>"))
4735
4736   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4737    " force a refresh
4738"    call Decho("go-up: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4739"    call Decho("go-up: setl noro ma",'~'.expand("<slnum>"))
4740    setl noro ma
4741    NetrwKeepj %d _
4742   endif
4743
4744   if has("amiga")
4745    " amiga
4746"    call Decho('go-up: case "go up one directory": newdir == "../" and amiga','~'.expand("<slnum>"))
4747    if a:islocal
4748     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
4749     let dirname= substitute(dirname,'/$','','')
4750    else
4751     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
4752    endif
4753"    call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4754
4755   elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
4756    " windows
4757    if a:islocal
4758     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4759     if dirname == ""
4760      let dirname= '/'
4761     endif
4762    else
4763     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4764    endif
4765    if dirname =~ '^\a:$'
4766     let dirname= dirname.'/'
4767    endif
4768"    call Decho("go-up: windows: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4769
4770   else
4771    " unix or cygwin
4772"    call Decho('go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("<slnum>"))
4773    if a:islocal
4774     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4775     if dirname == ""
4776      let dirname= '/'
4777     endif
4778    else
4779     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4780    endif
4781"    call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4782   endif
4783   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4784   norm m`
4785
4786  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4787   " --------------------------------------
4788   " NetrwBrowseChgDir: Handle Tree Listing {{{3
4789   " --------------------------------------
4790"   call Decho('tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("<slnum>"))
4791   " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
4792"   call Decho("tree-list: setl noro ma",'~'.expand("<slnum>"))
4793   setl noro ma
4794   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
4795"    call Decho("tree-list: clear buffer<".expand("%")."> with :%d  (force refresh)",'~'.expand("<slnum>"))
4796    NetrwKeepj %d _
4797   endif
4798   let treedir      = s:NetrwTreeDir(a:islocal)
4799"   call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>"))
4800   let s:treecurpos = nbcd_curpos
4801   let haskey       = 0
4802"   call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
4803
4804   " search treedict for tree dir as-is
4805"   call Decho("search treedict for tree dir as-is",'~'.expand("<slnum>"))
4806   if has_key(w:netrw_treedict,treedir)
4807"    call Decho('tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>"))
4808    let haskey= 1
4809   else
4810"    call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
4811   endif
4812
4813   " search treedict for treedir with a [/@] appended
4814"   call Decho("search treedict for treedir with a [/@] appended",'~'.expand("<slnum>"))
4815   if !haskey && treedir !~ '[/@]$'
4816    if has_key(w:netrw_treedict,treedir."/")
4817     let treedir= treedir."/"
4818"     call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
4819     let haskey = 1
4820    else
4821"     call Decho('tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("<slnum>"))
4822    endif
4823   endif
4824
4825   " search treedict for treedir with any trailing / elided
4826"   call Decho("search treedict for treedir with any trailing / elided",'~'.expand("<slnum>"))
4827   if !haskey && treedir =~ '/$'
4828    let treedir= substitute(treedir,'/$','','')
4829    if has_key(w:netrw_treedict,treedir)
4830"     call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
4831     let haskey = 1
4832    else
4833"     call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
4834    endif
4835   endif
4836
4837"   call Decho("haskey=".haskey,'~'.expand("<slnum>"))
4838   if haskey
4839    " close tree listing for selected subdirectory
4840"    call Decho("tree-list: closing selected subdirectory<".dirname.">",'~'.expand("<slnum>"))
4841    call remove(w:netrw_treedict,treedir)
4842"    call Decho("tree-list: removed     entry<".treedir."> from treedict",'~'.expand("<slnum>"))
4843"    call Decho("tree-list: yielding treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
4844    let dirname= w:netrw_treetop
4845   else
4846    " go down one directory
4847    let dirname= substitute(treedir,'/*$','/','')
4848"    call Decho("tree-list: go down one dir: treedir<".treedir.">",'~'.expand("<slnum>"))
4849"    call Decho("tree-list: ...            : dirname<".dirname.">",'~'.expand("<slnum>"))
4850   endif
4851   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4852"   call Decho("setting s:treeforceredraw to true",'~'.expand("<slnum>"))
4853   let s:treeforceredraw = 1
4854
4855  else
4856   " ----------------------------------------
4857   " NetrwBrowseChgDir: Go down one directory {{{3
4858   " ----------------------------------------
4859   let dirname    = s:ComposePath(dirname,newdir)
4860"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("<slnum>"))
4861   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4862   norm m`
4863  endif
4864
4865 " --------------------------------------
4866 " NetrwBrowseChgDir: Restore and Cleanup {{{3
4867 " --------------------------------------
4868  if dorestore
4869   " dorestore is zero'd when a local file was hidden or bufhidden;
4870   " in such a case, we want to keep whatever settings it may have.
4871"   call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("<slnum>"))
4872   NetrwKeepj call s:NetrwOptionRestore("s:")
4873"  else " Decho
4874"   call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>"))
4875  endif
4876  if dolockout && dorestore
4877"   call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>"))
4878   if filewritable(dirname)
4879"    call Decho("restore: doing modification lockout settings: ma nomod noro",'~'.expand("<slnum>"))
4880"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
4881    setl ma noro nomod
4882"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4883   else
4884"    call Decho("restore: doing modification lockout settings: ma nomod ro",'~'.expand("<slnum>"))
4885"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
4886    setl ma ro nomod
4887"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4888   endif
4889  endif
4890  let @@= ykeep
4891
4892"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
4893  return dirname
4894endfun
4895
4896" ---------------------------------------------------------------------
4897" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
4898"    for thin, long, and wide: cursor placed just after banner
4899"    for tree, keeps cursor on current filename
4900fun! s:NetrwBrowseUpDir(islocal)
4901"  call Dfunc("s:NetrwBrowseUpDir(islocal=".a:islocal.")")
4902  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
4903   " this test needed because occasionally this function seems to be incorrectly called
4904   " when multiple leftmouse clicks are taken when atop the one line help in the banner.
4905   " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
4906   " directories.
4907"   call Dret("s:NetrwBrowseUpDir : cursor not in file area")
4908   return
4909  endif
4910
4911  norm! 0
4912  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4913"   call Decho("case: treestyle",'~'.expand("<slnum>"))
4914   let curline= getline(".")
4915   let swwline= winline() - 1
4916   if exists("w:netrw_treetop")
4917    let b:netrw_curdir= w:netrw_treetop
4918   endif
4919   let curdir= b:netrw_curdir
4920   if a:islocal
4921    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
4922   else
4923    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
4924   endif
4925   if !search('\c^'.s:treedepthstring.curline,'cw')
4926    if !search('\c^'.curline,'cw')
4927     sil! NetrwKeepj 1
4928    endif
4929   endif
4930   exe "sil! NetrwKeepj norm! z\<cr>"
4931   while winline() < swwline
4932    let curwinline= winline()
4933    exe "sil! NetrwKeepj norm! \<c-y>"
4934    if curwinline == winline()
4935     break
4936    endif
4937   endwhile
4938  else
4939"   call Decho("case: not treestyle",'~'.expand("<slnum>"))
4940   if exists("b:netrw_curdir")
4941    let curdir= b:netrw_curdir
4942   else
4943    let curdir= expand(getcwd())
4944   endif
4945   if a:islocal
4946    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
4947   else
4948    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
4949   endif
4950   if exists("w:netrw_bannercnt")
4951"    call Decho("moving to line#".w:netrw_bannercnt,'~'.expand("<slnum>"))
4952    exe w:netrw_bannercnt
4953   else
4954    1
4955   endif
4956  endif
4957  let curdir= substitute(curdir,'^.*[\/]','','')
4958  call search('\<'.curdir.'\>','wc')
4959"  call Dret("s:NetrwBrowseUpDir")
4960endfun
4961
4962" ---------------------------------------------------------------------
4963" netrw#BrowseX:  (implements "x") executes a special "viewer" script or program for the {{{2
4964"              given filename; typically this means given their extension.
4965"              0=local, 1=remote
4966fun! netrw#BrowseX(fname,remote)
4967"  call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")")
4968
4969  " if its really just a directory, then do a "gf" instead
4970  if a:fname =~ '/$'
4971   norm! gf
4972"   call Dret("netrw#BrowseX : did gf instead")
4973  endif
4974
4975
4976  let ykeep      = @@
4977  let screenposn = netrw#SavePosn()
4978
4979  " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
4980  let awkeep     = &aw
4981  set noaw
4982
4983  " special core dump handler
4984  if a:fname =~ '/core\(\.\d\+\)\=$'
4985   if exists("g:Netrw_corehandler")
4986    if type(g:Netrw_corehandler) == 2
4987     " g:Netrw_corehandler is a function reference (see :help Funcref)
4988"     call Decho("g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
4989     call g:Netrw_corehandler(s:NetrwFile(a:fname))
4990    elseif type(g:Netrw_corehandler) == 3
4991     " g:Netrw_corehandler is a List of function references (see :help Funcref)
4992"     call Decho("g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
4993     for Fncref in g:Netrw_corehandler
4994      if type(FncRef) == 2
4995       call FncRef(a:fname)
4996      endif
4997     endfor
4998    endif
4999    call netrw#RestorePosn(screenposn)
5000    let @@= ykeep
5001    let &aw= awkeep
5002"    call Dret("netrw#BrowseX : coredump handler invoked")
5003    return
5004   endif
5005  endif
5006
5007  " set up the filename
5008  " (lower case the extension, make a local copy of a remote file)
5009  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5010  if has("win32") || has("win95") || has("win64") || has("win16")
5011   let exten= substitute(exten,'^.*$','\L&\E','')
5012  endif
5013"  call Decho("exten<".exten.">",'~'.expand("<slnum>"))
5014
5015  if a:remote == 1
5016   " create a local copy
5017"   call Decho("remote: a:remote=".a:remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
5018   setl bh=delete
5019   call netrw#NetRead(3,a:fname)
5020   " attempt to rename tempfile
5021   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5022   let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5023"   call Decho("basename<".basename.">",'~'.expand("<slnum>"))
5024"   call Decho("newname <".newname.">",'~'.expand("<slnum>"))
5025   if rename(s:netrw_tmpfile,newname) == 0
5026    " renaming succeeded
5027    let fname= newname
5028   else
5029    " renaming failed
5030    let fname= s:netrw_tmpfile
5031   endif
5032  else
5033"   call Decho("local: a:remote=".a:remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
5034   let fname= a:fname
5035   " special ~ handler for local
5036   if fname =~ '^\~' && expand("$HOME") != ""
5037"    call Decho('invoking special ~ handler','~'.expand("<slnum>"))
5038    let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5039   endif
5040  endif
5041"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
5042"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
5043
5044  " set up redirection
5045  if &srr =~ "%s"
5046   if (has("win32") || has("win95") || has("win64") || has("win16"))
5047    let redir= substitute(&srr,"%s","nul","")
5048   else
5049    let redir= substitute(&srr,"%s","/dev/null","")
5050   endif
5051  elseif (has("win32") || has("win95") || has("win64") || has("win16"))
5052   let redir= &srr . "nul"
5053  else
5054   let redir= &srr . "/dev/null"
5055  endif
5056"  call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
5057
5058  " extract any viewing options.  Assumes that they're set apart by quotes.
5059"  call Decho("extract any viewing options",'~'.expand("<slnum>"))
5060  if exists("g:netrw_browsex_viewer")
5061"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5062   if g:netrw_browsex_viewer =~ '\s'
5063    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5064    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5065    let oviewer = ''
5066    let cnt     = 1
5067    while !executable(viewer) && viewer != oviewer
5068     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5069     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5070     let cnt     = cnt + 1
5071     let oviewer = viewer
5072"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5073    endwhile
5074   else
5075    let viewer  = g:netrw_browsex_viewer
5076    let viewopt = ""
5077   endif
5078"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5079  endif
5080
5081  " execute the file handler
5082"  call Decho("execute the file handler (if any)",'~'.expand("<slnum>"))
5083  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
5084"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5085   let ret= netrwFileHandlers#Invoke(exten,fname)
5086
5087  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
5088"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5089   call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
5090   let ret= v:shell_error
5091
5092  elseif has("win32") || has("win64")
5093"   call Decho("windows",'~'.expand("<slnum>"))
5094   if executable("start")
5095    call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5096   elseif executable("rundll32")
5097    call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5098   else
5099    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5100   endif
5101   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
5102   let ret= v:shell_error
5103
5104  elseif has("win32unix")
5105   let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
5106"   call Decho("cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
5107   if executable("start")
5108    call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5109   elseif executable("rundll32")
5110    call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5111   elseif executable("cygstart")
5112    call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
5113   else
5114    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5115   endif
5116   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
5117   let ret= v:shell_error
5118
5119  elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
5120"   call Decho("unix and kfmclient",'~'.expand("<slnum>"))
5121   call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
5122   let ret= v:shell_error
5123
5124  elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
5125"   call Decho("unix, exo-open, xdg-open",'~'.expand("<slnum>"))
5126   call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir)
5127   let ret= v:shell_error
5128
5129  elseif has("unix") && executable("xdg-open")
5130"   call Decho("unix and xdg-open",'~'.expand("<slnum>"))
5131   call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir)
5132   let ret= v:shell_error
5133
5134  elseif has("macunix") && executable("open")
5135"   call Decho("macunix and open",'~'.expand("<slnum>"))
5136   call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
5137   let ret= v:shell_error
5138
5139  else
5140   " netrwFileHandlers#Invoke() always returns 0
5141   let ret= netrwFileHandlers#Invoke(exten,fname)
5142  endif
5143
5144  " if unsuccessful, attempt netrwFileHandlers#Invoke()
5145  if ret
5146   let ret= netrwFileHandlers#Invoke(exten,fname)
5147  endif
5148
5149  " restoring redraw! after external file handlers
5150  redraw!
5151
5152  " cleanup: remove temporary file,
5153  "          delete current buffer if success with handler,
5154  "          return to prior buffer (directory listing)
5155  "          Feb 12, 2008: had to de-activiate removal of
5156  "          temporary file because it wasn't getting seen.
5157"  if a:remote == 1 && fname != a:fname
5158""   call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
5159"   call s:NetrwDelete(fname)
5160"  endif
5161
5162  if a:remote == 1
5163   setl bh=delete bt=nofile
5164   if g:netrw_use_noswf
5165    setl noswf
5166   endif
5167   exe "sil! NetrwKeepj norm! \<c-o>"
5168"   redraw!
5169  endif
5170  call netrw#RestorePosn(screenposn)
5171  let @@ = ykeep
5172  let &aw= awkeep
5173
5174"  call Dret("netrw#BrowseX")
5175endfun
5176
5177" ---------------------------------------------------------------------
5178" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5179fun! netrw#BrowseXVis()
5180"  call Dfunc("netrw#BrowseXVis()")
5181  let atkeep = @@
5182  norm! gvy
5183"  call Decho("@@<".@@.">",'~'.expand("<slnum>"))
5184  call netrw#BrowseX(@@,netrw#CheckIfRemote())
5185  let @@     = atkeep
5186"  call Dret("netrw#BrowseXVis")
5187endfun
5188
5189" ---------------------------------------------------------------------
5190" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5191fun! netrw#CheckIfRemote()
5192"  call Dfunc("netrw#CheckIfRemote()")
5193  if expand("%") =~ '^\a\{3,}://'
5194"   call Dret("netrw#CheckIfRemote 1")
5195   return 1
5196  else
5197"   call Dret("netrw#CheckIfRemote 0")
5198   return 0
5199  endif
5200endfun
5201
5202" ---------------------------------------------------------------------
5203" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5204fun! s:NetrwChgPerm(islocal,curdir)
5205"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
5206  let ykeep  = @@
5207  call inputsave()
5208  let newperm= input("Enter new permission: ")
5209  call inputrestore()
5210  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5211  let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5212"  call Decho("chgperm<".chgperm.">",'~'.expand("<slnum>"))
5213  call system(chgperm)
5214  if v:shell_error != 0
5215   NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5216  endif
5217  if a:islocal
5218   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5219  endif
5220  let @@= ykeep
5221"  call Dret("s:NetrwChgPerm")
5222endfun
5223
5224" ---------------------------------------------------------------------
5225" s:CheckIfKde: checks if kdeinit is running {{{2
5226"    Returns 0: kdeinit not running
5227"            1: kdeinit is  running
5228fun! s:CheckIfKde()
5229"  call Dfunc("s:CheckIfKde()")
5230  " seems kde systems often have gnome-open due to dependencies, even though
5231  " gnome-open's subsidiary display tools are largely absent.  Kde systems
5232  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
5233  if !exists("s:haskdeinit")
5234   if has("unix") && executable("ps") && !has("win32unix")
5235    let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5236    if v:shell_error
5237     let s:haskdeinit = 0
5238    endif
5239   else
5240    let s:haskdeinit= 0
5241   endif
5242"   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5243  endif
5244
5245"  call Dret("s:CheckIfKde ".s:haskdeinit)
5246  return s:haskdeinit
5247endfun
5248
5249" ---------------------------------------------------------------------
5250" s:NetrwClearExplore: clear explore variables (if any) {{{2
5251fun! s:NetrwClearExplore()
5252"  call Dfunc("s:NetrwClearExplore()")
5253  2match none
5254  if exists("s:explore_match")        |unlet s:explore_match        |endif
5255  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
5256  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5257  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
5258  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
5259  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
5260  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5261  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
5262  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
5263"   redraw!
5264  echo " "
5265  echo " "
5266"  call Dret("s:NetrwClearExplore")
5267endfun
5268
5269" ---------------------------------------------------------------------
5270" s:NetrwExploreListUniq: {{{2
5271fun! s:NetrwExploreListUniq(explist)
5272"  call Dfunc("s:NetrwExploreListUniq(explist<".string(a:explist).">)")
5273
5274  " this assumes that the list is already sorted
5275  let newexplist= []
5276  for member in a:explist
5277   if !exists("uniqmember") || member != uniqmember
5278    let uniqmember = member
5279    let newexplist = newexplist + [ member ]
5280   endif
5281  endfor
5282
5283"  call Dret("s:NetrwExploreListUniq newexplist<".string(newexplist).">")
5284  return newexplist
5285endfun
5286
5287" ---------------------------------------------------------------------
5288" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5289fun! s:NetrwForceChgDir(islocal,newdir)
5290"  call Dfunc("s:NetrwForceChgDir(islocal=".a:islocal." newdir<".a:newdir.">)")
5291  let ykeep= @@
5292  if a:newdir !~ '/$'
5293   " ok, looks like force is needed to get directory-style treatment
5294   if a:newdir =~ '@$'
5295    let newdir= substitute(a:newdir,'@$','/','')
5296   elseif a:newdir =~ '[*=|\\]$'
5297    let newdir= substitute(a:newdir,'.$','/','')
5298   else
5299    let newdir= a:newdir.'/'
5300   endif
5301"   call Decho("adjusting newdir<".newdir."> due to gd",'~'.expand("<slnum>"))
5302  else
5303   " should already be getting treatment as a directory
5304   let newdir= a:newdir
5305  endif
5306  let newdir= s:NetrwBrowseChgDir(a:islocal,newdir)
5307  call s:NetrwBrowse(a:islocal,newdir)
5308  let @@= ykeep
5309"  call Dret("s:NetrwForceChgDir")
5310endfun
5311
5312" ---------------------------------------------------------------------
5313" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5314fun! s:NetrwForceFile(islocal,newfile)
5315"  call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)")
5316  if a:newfile =~ '[/@*=|\\]$'
5317   let newfile= substitute(a:newfile,'.$','','')
5318  else
5319   let newfile= a:newfile
5320  endif
5321  if a:islocal
5322   call s:NetrwBrowseChgDir(a:islocal,newfile)
5323  else
5324   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile))
5325  endif
5326"  call Dret("s:NetrwForceFile")
5327endfun
5328
5329" ---------------------------------------------------------------------
5330" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5331"          and switches the hiding mode.  The actual hiding is done by
5332"          s:NetrwListHide().
5333"             g:netrw_hide= 0: show all
5334"                           1: show not-hidden files
5335"                           2: show hidden files only
5336fun! s:NetrwHide(islocal)
5337"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
5338  let ykeep= @@
5339  let svpos= netrw#SavePosn()
5340
5341  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5342"   call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>"))
5343"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5344
5345   " hide the files in the markfile list
5346   for fname in s:netrwmarkfilelist_{bufnr("%")}
5347"    call Decho("match(g:netrw_list_hide<".g:netrw_list_hide.'> fname<\<'.fname.'\>>)='.match(g:netrw_list_hide,'\<'.fname.'\>')." l:isk=".&l:isk,'~'.expand("<slnum>"))
5348    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5349     " remove fname from hiding list
5350     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5351     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5352     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5353"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5354    else
5355     " append fname to hiding list
5356     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5357      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5358     else
5359      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5360     endif
5361"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5362    endif
5363   endfor
5364   NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5365   let g:netrw_hide= 1
5366
5367  else
5368
5369   " switch between show-all/show-not-hidden/show-hidden
5370   let g:netrw_hide=(g:netrw_hide+1)%3
5371   exe "NetrwKeepj norm! 0"
5372   if g:netrw_hide && g:netrw_list_hide == ""
5373    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5374    let @@= ykeep
5375"    call Dret("NetrwHide")
5376    return
5377   endif
5378  endif
5379
5380  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5381  NetrwKeepj call netrw#RestorePosn(svpos)
5382  let @@= ykeep
5383"  call Dret("NetrwHide")
5384endfun
5385
5386" ---------------------------------------------------------------------
5387" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5388fun! s:NetrwHideEdit(islocal)
5389"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
5390
5391  let ykeep= @@
5392  " save current cursor position
5393  let svpos= netrw#SavePosn()
5394
5395  " get new hiding list from user
5396  call inputsave()
5397  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5398  call inputrestore()
5399  let g:netrw_list_hide= newhide
5400"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5401
5402  " refresh the listing
5403  sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
5404
5405  " restore cursor position
5406  call netrw#RestorePosn(svpos)
5407  let @@= ykeep
5408
5409"  call Dret("NetrwHideEdit")
5410endfun
5411
5412" ---------------------------------------------------------------------
5413" s:NetrwHidden: invoked by "gh" {{{2
5414fun! s:NetrwHidden(islocal)
5415"  call Dfunc("s:NetrwHidden()")
5416  let ykeep= @@
5417  "  save current position
5418  let svpos= netrw#SavePosn()
5419
5420  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5421   " remove pattern from hiding list
5422   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5423  elseif s:Strlen(g:netrw_list_hide) >= 1
5424   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5425  else
5426   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5427  endif
5428
5429  " refresh screen and return to saved position
5430  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5431  NetrwKeepj call netrw#RestorePosn(svpos)
5432  let @@= ykeep
5433"  call Dret("s:NetrwHidden")
5434endfun
5435
5436" ---------------------------------------------------------------------
5437"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5438fun! s:NetrwHome()
5439  if exists("g:netrw_home")
5440   let home= g:netrw_home
5441  else
5442   " go to vim plugin home
5443   for home in split(&rtp,',') + ['']
5444    if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5445     let basehome= substitute(home,'[/\\]\.vim$','','')
5446     if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5447     let home= basehome."/.vim"
5448     break
5449    endif
5450   endfor
5451   if home == ""
5452    " just pick the first directory
5453    let home= substitute(&rtp,',.*$','','')
5454   endif
5455   if (has("win32") || has("win95") || has("win64") || has("win16"))
5456    let home= substitute(home,'/','\\','g')
5457   endif
5458  endif
5459  " insure that the home directory exists
5460  if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5461   if exists("g:netrw_mkdir")
5462    call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5463   else
5464    call mkdir(home)
5465   endif
5466  endif
5467  let g:netrw_home= home
5468  return home
5469endfun
5470
5471" ---------------------------------------------------------------------
5472" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5473fun! s:NetrwLeftmouse(islocal)
5474  if exists("s:netrwdrag")
5475   return
5476  endif
5477"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
5478
5479  let ykeep= @@
5480  " check if the status bar was clicked on instead of a file/directory name
5481  while getchar(0) != 0
5482   "clear the input stream
5483  endwhile
5484  call feedkeys("\<LeftMouse>")
5485  let c          = getchar()
5486  let mouse_lnum = v:mouse_lnum
5487  let wlastline  = line('w$')
5488  let lastline   = line('$')
5489"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr(),'~'.expand("<slnum>"))
5490"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0),'~'.expand("<slnum>"))
5491  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5492   " appears to be a status bar leftmouse click
5493   let @@= ykeep
5494"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
5495   return
5496  endif
5497   " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5498   " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5499   " without this test when its disabled.
5500   " May 26, 2014: edit file, :Lex, resize window -- causes refresh.  Reinstated a modified test.  See if problems develop.
5501"   call Decho("v:mouse_col=".v:mouse_col." col#".col('.')." virtcol#".virtcol('.')." col($)#".col("$")." virtcol($)#".virtcol("$"),'~'.expand("<slnum>"))
5502   if v:mouse_col > virtcol('.')
5503    let @@= ykeep
5504"    call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
5505    return
5506   endif
5507
5508  if a:islocal
5509   if exists("b:netrw_curdir")
5510    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
5511   endif
5512  else
5513   if exists("b:netrw_curdir")
5514    NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5515   endif
5516  endif
5517  let @@= ykeep
5518"  call Dret("s:NetrwLeftmouse")
5519endfun
5520
5521" ---------------------------------------------------------------------
5522" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5523fun! s:NetrwCLeftmouse(islocal)
5524"  call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")")
5525  call s:NetrwMarkFileTgt(a:islocal)
5526"  call Dret("s:NetrwCLeftmouse")
5527endfun
5528
5529" ---------------------------------------------------------------------
5530" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER  (implements <c-r>){{{2
5531"   a:islocal=0 : <c-r> not used, remote
5532"   a:islocal=1 : <c-r> no  used, local
5533"   a:islocal=2 : <c-r>     used, remote
5534"   a:islocal=3 : <c-r>     used, local
5535fun! s:NetrwServerEdit(islocal,fname)
5536"  call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5537  let islocal = a:islocal%2      " =0: remote           =1: local
5538  let ctrlr   = a:islocal >= 2   " =0: <c-r> not used   =1: <c-r> used
5539"  call Decho("islocal=".islocal." ctrlr=".ctrlr,'~'.expand("<slnum>"))
5540
5541  if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5542   " handle directories in the local window -- not in the remote vim server
5543   " user must have closed the NETRWSERVER window.  Treat as a normal editing from netrw.
5544"   call Decho("handling directory in client window",'~'.expand("<slnum>"))
5545   let g:netrw_browse_split= 0
5546   if exists("s:netrw_browse_split_".winnr())
5547    let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5548    unlet s:netrw_browse_split_{winnr()}
5549   endif
5550   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5551"   call Dret("s:NetrwServerEdit")
5552   return
5553  endif
5554
5555"  call Decho("handling file in server window",'~'.expand("<slnum>"))
5556  if has("clientserver") && executable("gvim")
5557"   call Decho("has clientserver and gvim",'~'.expand("<slnum>"))
5558
5559    if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
5560"     call Decho("g:netrw_browse_split=".string(g:netrw_browse_split),'~'.expand("<slnum>"))
5561     let srvrname = g:netrw_browse_split[0]
5562     let tabnum   = g:netrw_browse_split[1]
5563     let winnum   = g:netrw_browse_split[2]
5564
5565     if serverlist() !~ '\<'.srvrname.'\>'
5566"      call Decho("server not available; ctrlr=".ctrlr,'~'.expand("<slnum>"))
5567
5568      if !ctrlr
5569       " user must have closed the server window and the user did not use <c-r>, but
5570       " used something like <cr>.
5571"       call Decho("user must have closed server AND did not use ctrl-r",'~'.expand("<slnum>"))
5572       if exists("g:netrw_browse_split")
5573	unlet g:netrw_browse_split
5574       endif
5575       let g:netrw_browse_split= 0
5576       if exists("s:netrw_browse_split_".winnr())
5577        let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5578       endif
5579       call s:NetrwBrowseChgDir(islocal,a:fname)
5580"       call Dret("s:NetrwServerEdit")
5581       return
5582
5583      elseif has("win32") && executable("start")
5584       " start up remote netrw server under windows
5585"       call Decho("starting up gvim server<".srvrname."> for windows",'~'.expand("<slnum>"))
5586       call system("start gvim --servername ".srvrname)
5587
5588      else
5589       " start up remote netrw server under linux
5590"       call Decho("starting up gvim server<".srvrname.">",'~'.expand("<slnum>"))
5591       call system("gvim --servername ".srvrname)
5592      endif
5593     endif
5594
5595"     call Decho("srvrname<".srvrname."> tabnum=".tabnum." winnum=".winnum." server-editing<".a:fname.">",'~'.expand("<slnum>"))
5596     call remote_send(srvrname,":tabn ".tabnum."\<cr>")
5597     call remote_send(srvrname,":".winnum."wincmd w\<cr>")
5598     call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5599
5600    else
5601
5602     if serverlist() !~ '\<'.g:netrw_servername.'\>'
5603
5604      if !ctrlr
5605"       call Decho("server<".g:netrw_servername."> not available and ctrl-r not used",'~'.expand("<slnum>"))
5606       if exists("g:netrw_browse_split")
5607	unlet g:netrw_browse_split
5608       endif
5609       let g:netrw_browse_split= 0
5610       call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5611"       call Dret("s:NetrwServerEdit")
5612       return
5613
5614      else
5615"       call Decho("server<".g:netrw_servername."> not available but ctrl-r used",'~'.expand("<slnum>"))
5616       if has("win32") && executable("start")
5617        " start up remote netrw server under windows
5618"        call Decho("starting up gvim server<".g:netrw_servername."> for windows",'~'.expand("<slnum>"))
5619        call system("start gvim --servername ".g:netrw_servername)
5620       else
5621        " start up remote netrw server under linux
5622"        call Decho("starting up gvim server<".g:netrw_servername.">",'~'.expand("<slnum>"))
5623        call system("gvim --servername ".g:netrw_servername)
5624       endif
5625      endif
5626     endif
5627
5628     while 1
5629      try
5630"       call Decho("remote-send: e ".a:fname,'~'.expand("<slnum>"))
5631       call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5632       break
5633      catch /^Vim\%((\a\+)\)\=:E241/
5634       sleep 200m
5635      endtry
5636     endwhile
5637
5638     if exists("g:netrw_browse_split")
5639      if type(g:netrw_browse_split) != 3
5640        let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
5641       endif
5642      unlet g:netrw_browse_split
5643     endif
5644     let g:netrw_browse_split= [g:netrw_servername,1,1]
5645    endif
5646
5647   else
5648    call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
5649   endif
5650
5651"  call Dret("s:NetrwServerEdit")
5652endfun
5653
5654" ---------------------------------------------------------------------
5655" s:NetrwSLeftmouse: marks the file under the cursor.  May be dragged to select additional files {{{2
5656fun! s:NetrwSLeftmouse(islocal)
5657"  call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
5658
5659  let s:ngw= s:NetrwGetWord()
5660  call s:NetrwMarkFile(a:islocal,s:ngw)
5661
5662"  call Dret("s:NetrwSLeftmouse")
5663endfun
5664
5665" ---------------------------------------------------------------------
5666" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
5667"                   Used to mark multiple files.
5668fun! s:NetrwSLeftdrag(islocal)
5669"  call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
5670  if !exists("s:netrwdrag")
5671   let s:netrwdrag = winnr()
5672   if a:islocal
5673    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
5674   else
5675    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
5676   endif
5677  endif
5678  let ngw = s:NetrwGetWord()
5679  if !exists("s:ngw") || s:ngw != ngw
5680   call s:NetrwMarkFile(a:islocal,ngw)
5681  endif
5682  let s:ngw= ngw
5683"  call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5684endfun
5685
5686" ---------------------------------------------------------------------
5687" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
5688fun! s:NetrwSLeftrelease(islocal)
5689"  call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5690  if exists("s:netrwdrag")
5691   nunmap <s-leftrelease>
5692   let ngw = s:NetrwGetWord()
5693   if !exists("s:ngw") || s:ngw != ngw
5694    call s:NetrwMarkFile(a:islocal,ngw)
5695   endif
5696   if exists("s:ngw")
5697    unlet s:ngw
5698   endif
5699   unlet s:netrwdrag
5700  endif
5701"  call Dret("s:NetrwSLeftrelease")
5702endfun
5703
5704" ---------------------------------------------------------------------
5705" s:NetrwListHide: uses [range]g~...~d to delete files that match comma {{{2
5706" separated patterns given in g:netrw_list_hide
5707fun! s:NetrwListHide()
5708"  call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
5709  let ykeep= @@
5710
5711  " find a character not in the "hide" string to use as a separator for :g and :v commands
5712  " How-it-works: take the hiding command, convert it into a range.  Duplicate
5713  " characters don't matter.  Remove all such characters from the '/~...90'
5714  " string.  Use the first character left as a separator character.
5715  let listhide= g:netrw_list_hide
5716  let sep     = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
5717"  call Decho("sep=".sep,'~'.expand("<slnum>"))
5718
5719  while listhide != ""
5720   if listhide =~ ','
5721    let hide     = substitute(listhide,',.*$','','e')
5722    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
5723   else
5724    let hide     = listhide
5725    let listhide = ""
5726   endif
5727
5728   " Prune the list by hiding any files which match
5729   if g:netrw_hide == 1
5730"    call Decho("hiding<".hide."> listhide<".listhide.">",'~'.expand("<slnum>"))
5731    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
5732   elseif g:netrw_hide == 2
5733"    call Decho("showing<".hide."> listhide<".listhide.">",'~'.expand("<slnum>"))
5734    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
5735   endif
5736  endwhile
5737  if g:netrw_hide == 2
5738   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
5739   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
5740  endif
5741
5742  " remove any blank lines that have somehow remained.
5743  " This seems to happen under Windows.
5744  exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
5745
5746  let @@= ykeep
5747"  call Dret("s:NetrwListHide")
5748endfun
5749
5750" ---------------------------------------------------------------------
5751" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
5752"                 implements the "d" mapping.
5753fun! s:NetrwMakeDir(usrhost)
5754"  call Dfunc("s:NetrwMakeDir(usrhost<".a:usrhost.">)")
5755
5756  let ykeep= @@
5757  " get name of new directory from user.  A bare <CR> will skip.
5758  " if its currently a directory, also request will be skipped, but with
5759  " a message.
5760  call inputsave()
5761  let newdirname= input("Please give directory name: ")
5762  call inputrestore()
5763"  call Decho("newdirname<".newdirname.">",'~'.expand("<slnum>"))
5764
5765  if newdirname == ""
5766   let @@= ykeep
5767"   call Dret("s:NetrwMakeDir : user aborted with bare <cr>")
5768   return
5769  endif
5770
5771  if a:usrhost == ""
5772"   call Decho("local mkdir",'~'.expand("<slnum>"))
5773
5774   " Local mkdir:
5775   " sanity checks
5776   let fullnewdir= b:netrw_curdir.'/'.newdirname
5777"   call Decho("fullnewdir<".fullnewdir.">",'~'.expand("<slnum>"))
5778   if isdirectory(s:NetrwFile(fullnewdir))
5779    if !exists("g:netrw_quiet")
5780     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
5781    endif
5782    let @@= ykeep
5783"    call Dret("s:NetrwMakeDir : directory<".newdirname."> exists previously")
5784    return
5785   endif
5786   if s:FileReadable(fullnewdir)
5787    if !exists("g:netrw_quiet")
5788     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
5789    endif
5790    let @@= ykeep
5791"    call Dret("s:NetrwMakeDir : file<".newdirname."> exists previously")
5792    return
5793   endif
5794
5795   " requested new local directory is neither a pre-existing file or
5796   " directory, so make it!
5797   if exists("*mkdir")
5798    if has("unix")
5799     call mkdir(fullnewdir,"p",xor(0777, system("umask")))
5800    else
5801     call mkdir(fullnewdir,"p")
5802    endif
5803   else
5804    let netrw_origdir= s:NetrwGetcwd(1)
5805    call s:NetrwLcd(b:netrw_curdir)
5806"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("<slnum>"))
5807    call s:NetrwExe("sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
5808    if v:shell_error != 0
5809     let @@= ykeep
5810     call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
5811"     call Dret("s:NetrwMakeDir : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
5812     return
5813    endif
5814    if !g:netrw_keepdir
5815"     call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
5816     call s:NetrwLcd(netrw_origdir)
5817    endif
5818   endif
5819
5820   if v:shell_error == 0
5821    " refresh listing
5822"    call Decho("refresh listing",'~'.expand("<slnum>"))
5823    let svpos= netrw#SavePosn()
5824    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
5825    call netrw#RestorePosn(svpos)
5826   elseif !exists("g:netrw_quiet")
5827    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
5828   endif
5829"   redraw!
5830
5831  elseif !exists("b:netrw_method") || b:netrw_method == 4
5832   " Remote mkdir:  using ssh
5833"   call Decho("remote mkdir",'~'.expand("<slnum>"))
5834   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
5835   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
5836   call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
5837   if v:shell_error == 0
5838    " refresh listing
5839    let svpos= netrw#SavePosn()
5840    NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5841    NetrwKeepj call netrw#RestorePosn(svpos)
5842   elseif !exists("g:netrw_quiet")
5843    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
5844   endif
5845"   redraw!
5846
5847  elseif b:netrw_method == 2
5848   " Remote mkdir:  using ftp+.netrc
5849   let svpos= netrw#SavePosn()
5850"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
5851   if exists("b:netrw_fname")
5852"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
5853    let remotepath= b:netrw_fname
5854   else
5855    let remotepath= ""
5856   endif
5857   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
5858   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5859   NetrwKeepj call netrw#RestorePosn(svpos)
5860
5861  elseif b:netrw_method == 3
5862   " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
5863   let svpos= netrw#SavePosn()
5864"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
5865   if exists("b:netrw_fname")
5866"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
5867    let remotepath= b:netrw_fname
5868   else
5869    let remotepath= ""
5870   endif
5871   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
5872   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5873   NetrwKeepj call netrw#RestorePosn(svpos)
5874  endif
5875
5876  let @@= ykeep
5877"  call Dret("s:NetrwMakeDir")
5878endfun
5879
5880" ---------------------------------------------------------------------
5881" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
5882fun! s:TreeSqueezeDir(islocal)
5883"  call Dfunc("s:TreeSqueezeDir(islocal=".a:islocal.")")
5884  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5885   " its a tree-listing style
5886   let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
5887   let iline    = line(".") - 1
5888   let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
5889"   call Decho("curdepth=".curdepth,'~'.expand("<slnum>"))
5890"   call Decho("stopline#".stopline,'~'.expand("<slnum>"))
5891"   call Decho("starting with line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
5892   while iline > stopline
5893    " find a line that has less depth
5894    let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
5895"    call Decho("considering  line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
5896    if depth < curdepth
5897     break
5898    endif
5899    norm! k
5900   endwhile
5901"   call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
5902   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord()))
5903  endif
5904"  call Dret("s:TreeSqueezeDir")
5905endfun
5906
5907" ---------------------------------------------------------------------
5908" s:NetrwMaps: {{{2
5909fun! s:NetrwMaps(islocal)
5910"  call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
5911
5912  if g:netrw_mousemaps && g:netrw_retmap
5913"   call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
5914   if !hasmapto("<Plug>NetrwReturn")
5915    if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
5916"     call Decho("making map for 2-leftmouse",'~'.expand("<slnum>"))
5917     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
5918    elseif maparg("<c-leftmouse>","n") == ""
5919"     call Decho("making map for c-leftmouse",'~'.expand("<slnum>"))
5920     nmap <unique> <silent> <c-leftmouse>	<Plug>NetrwReturn
5921    endif
5922   endif
5923   nno <silent> <Plug>NetrwReturn	:Rexplore<cr>
5924"   call Decho("made <Plug>NetrwReturn map",'~'.expand("<slnum>"))
5925  endif
5926
5927  if a:islocal
5928"   call Decho("make local maps",'~'.expand("<slnum>"))
5929   " local normal-mode maps
5930   nnoremap <buffer> <silent> <nowait> a	:call <SID>NetrwHide(1)<cr>
5931   nnoremap <buffer> <silent> <nowait> %	:call <SID>NetrwOpenFile(1)<cr>
5932   nnoremap <buffer> <silent> <nowait> c	:call <SID>NetrwLcd(b:netrw_curdir)<cr>
5933   nnoremap <buffer> <silent> <nowait> C	:<c-u>call <SID>NetrwSetChgwin()<cr>
5934   nnoremap <buffer> <silent> <nowait> <cr>	:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
5935   nnoremap <buffer> <silent> <nowait> <s-cr>	:call <SID>TreeSqueezeDir(1)<cr>
5936   nnoremap <buffer> <silent> <nowait> <c-r>	:call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
5937   nnoremap <buffer> <silent> <nowait> d	:call <SID>NetrwMakeDir("")<cr>
5938   nnoremap <buffer> <silent> <nowait> -	:call <SID>NetrwBrowseUpDir(1)<cr>
5939   nnoremap <buffer> <silent> <nowait> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
5940   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
5941   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
5942   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
5943   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr>
5944   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
5945   nnoremap <buffer> <silent> <nowait> I	:call <SID>NetrwBannerCtrl(1)<cr>
5946   nnoremap <buffer> <silent> <nowait> i	:call <SID>NetrwListStyle(1)<cr>
5947   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
5948   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
5949   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
5950   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
5951   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
5952   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
5953   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
5954   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
5955   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
5956   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
5957   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
5958   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
5959   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
5960   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
5961   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
5962   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
5963   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
5964   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
5965   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
5966   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
5967   nnoremap <buffer> <silent> <nowait> O	:call <SID>NetrwObtain(1)<cr>
5968   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(3)<cr>
5969   nnoremap <buffer> <silent> <nowait> p	:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
5970   nnoremap <buffer> <silent> <nowait> P	:call <SID>NetrwPrevWinOpen(1)<cr>
5971   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
5972   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
5973   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
5974   nnoremap <buffer> <silent> <nowait> 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>
5975   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(1)<cr>
5976   nnoremap <buffer> <silent> <nowait> S	:call <SID>NetSortSequence(1)<cr>
5977   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(4)<cr>
5978   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr>
5979   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr>
5980   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
5981   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
5982   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(5)<cr>
5983   nnoremap <buffer> <silent> <nowait> x	:call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
5984   nnoremap <buffer> <silent> <nowait> X	:call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
5985   " local insert-mode maps
5986   inoremap <buffer> <silent> <nowait> a	<c-o>:call <SID>NetrwHide(1)<cr>
5987   inoremap <buffer> <silent> <nowait> c	<c-o>:exe "NetrwKeepj lcd ".fnameescape(b:netrw_curdir)<cr>
5988   inoremap <buffer> <silent> <nowait> c	<c-o>:call <SID>NetrwLcd(b:netrw_curdir)<cr>
5989   inoremap <buffer> <silent> <nowait> C	<c-o>:call <SID>NetrwSetChgwin()<cr>
5990   inoremap <buffer> <silent> <nowait> %	<c-o>:call <SID>NetrwOpenFile(1)<cr>
5991   inoremap <buffer> <silent> <nowait> -	<c-o>:call <SID>NetrwBrowseUpDir(1)<cr>
5992   inoremap <buffer> <silent> <nowait> <cr>	<c-o>:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
5993   inoremap <buffer> <silent> <nowait> <s-cr>	<c-o>:call <SID>TreeSqueezeDir(1)<cr>
5994   inoremap <buffer> <silent> <nowait> d	<c-o>:call <SID>NetrwMakeDir("")<cr>
5995   inoremap <buffer> <silent> <nowait> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
5996   inoremap <buffer> <silent> <nowait> gh	<c-o>:<c-u>call <SID>NetrwHidden(1)<cr>
5997   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr>
5998   inoremap <buffer> <silent> <nowait> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
5999   inoremap <buffer> <silent> <nowait> I	<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
6000   inoremap <buffer> <silent> <nowait> i	<c-o>:call <SID>NetrwListStyle(1)<cr>
6001   inoremap <buffer> <silent> <nowait> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6002   inoremap <buffer> <silent> <nowait> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6003   inoremap <buffer> <silent> <nowait> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6004   inoremap <buffer> <silent> <nowait> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6005   inoremap <buffer> <silent> <nowait> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6006   inoremap <buffer> <silent> <nowait> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6007   inoremap <buffer> <silent> <nowait> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6008   inoremap <buffer> <silent> <nowait> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6009   inoremap <buffer> <silent> <nowait> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6010   inoremap <buffer> <silent> <nowait> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6011   inoremap <buffer> <silent> <nowait> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6012   inoremap <buffer> <silent> <nowait> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6013   inoremap <buffer> <silent> <nowait> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6014   inoremap <buffer> <silent> <nowait> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6015   inoremap <buffer> <silent> <nowait> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6016   inoremap <buffer> <silent> <nowait> mv	<c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6017   inoremap <buffer> <silent> <nowait> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6018   inoremap <buffer> <silent> <nowait> mX	<c-o>:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6019   inoremap <buffer> <silent> <nowait> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6020   inoremap <buffer> <silent> <nowait> O	<c-o>:call <SID>NetrwObtain(1)<cr>
6021   inoremap <buffer> <silent> <nowait> o	<c-o>:call <SID>NetrwSplit(3)<cr>
6022   inoremap <buffer> <silent> <nowait> p	<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6023   inoremap <buffer> <silent> <nowait> P	<c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
6024   inoremap <buffer> <silent> <nowait> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6025   inoremap <buffer> <silent> <nowait> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6026   inoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6027   inoremap <buffer> <silent> <nowait> 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>
6028   inoremap <buffer> <silent> <nowait> s	<c-o>:call <SID>NetrwSortStyle(1)<cr>
6029   inoremap <buffer> <silent> <nowait> S	<c-o>:call <SID>NetSortSequence(1)<cr>
6030   inoremap <buffer> <silent> <nowait> t	<c-o>:call <SID>NetrwSplit(4)<cr>
6031   inoremap <buffer> <silent> <nowait> Tb	<c-o>:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr>
6032   inoremap <buffer> <silent> <nowait> Th	<c-o>:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr>
6033   inoremap <buffer> <silent> <nowait> u	<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6034   inoremap <buffer> <silent> <nowait> U	<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6035   inoremap <buffer> <silent> <nowait> v	<c-o>:call <SID>NetrwSplit(5)<cr>
6036   inoremap <buffer> <silent> <nowait> x	<c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6037   if !hasmapto('<Plug>NetrwHideEdit')
6038    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6039    imap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6040   endif
6041   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(1)<cr>
6042   if !hasmapto('<Plug>NetrwRefresh')
6043    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6044    imap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6045   endif
6046   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr>
6047   if s:didstarstar || !mapcheck("<s-down>","n")
6048    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6049    inoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6050   endif
6051   if s:didstarstar || !mapcheck("<s-up>","n")
6052    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6053    inoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6054   endif
6055   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6056   if g:netrw_mousemaps == 1
6057    nmap <buffer> <leftmouse>   	<Plug>NetrwLeftmouse
6058    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
6059    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6060    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(1)<cr>
6061    nmap <buffer> <middlemouse>		<Plug>NetrwMiddlemouse
6062    nno  <buffer> <silent>		<Plug>NetrwMiddlemouse	<leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
6063    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6064    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(1)<cr>
6065    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6066    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(1)<cr>
6067    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6068    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6069    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6070    ino  <buffer> <silent>		<Plug>ILeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(1)<cr>
6071    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6072    ino  <buffer> <silent>		<Plug>IMiddlemouse	<c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
6073    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6074    ino  <buffer> <silent>		<Plug>ISLeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6075    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6076    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6077    exe 'inoremap <buffer> <silent> <rightmouse>  <c-o><leftmouse><c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6078   endif
6079   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6080   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6081   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6082   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("")<cr>'
6083   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6084   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6085   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6086   exe 'inoremap <buffer> <silent> <nowait> <del>	<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6087   exe 'inoremap <buffer> <silent> <nowait> D		<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6088   exe 'inoremap <buffer> <silent> <nowait> R		<c-o>:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6089   exe 'inoremap <buffer> <silent> <nowait> d		<c-o>:call <SID>NetrwMakeDir("")<cr>'
6090   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6091
6092   " support user-specified maps
6093   call netrw#UserMaps(1)
6094
6095  else " remote
6096"   call Decho("make remote maps",'~'.expand("<slnum>"))
6097   call s:RemotePathAnalysis(b:netrw_curdir)
6098   " remote normal-mode maps
6099   nnoremap <buffer> <silent> <nowait> <cr>	:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6100   nnoremap <buffer> <silent> <nowait> <s-cr>	:call <SID>TreeSqueezeDir(0)<cr>
6101   nnoremap <buffer> <silent> <nowait> <c-l>	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6102   nnoremap <buffer> <silent> <nowait> <c-r>	:call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6103   nnoremap <buffer> <silent> <nowait> -	:call <SID>NetrwBrowseUpDir(0)<cr>
6104   nnoremap <buffer> <silent> <nowait> a	:call <SID>NetrwHide(0)<cr>
6105   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6106   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6107   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6108   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6109   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6110   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6111   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6112   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6113   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6114   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6115   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6116   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6117   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6118   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6119   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6120   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6121   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6122   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6123   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6124   nnoremap <buffer> <silent> <nowait> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6125   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6126   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6127   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
6128   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6129   nnoremap <buffer> <silent> <nowait> C		:<c-u>call <SID>NetrwSetChgwin()<cr>
6130   nnoremap <buffer> <silent> <nowait> i		:call <SID>NetrwListStyle(0)<cr>
6131   nnoremap <buffer> <silent> <nowait> I		:call <SID>NetrwBannerCtrl(1)<cr>
6132   nnoremap <buffer> <silent> <nowait> o		:call <SID>NetrwSplit(0)<cr>
6133   nnoremap <buffer> <silent> <nowait> O		:call <SID>NetrwObtain(0)<cr>
6134   nnoremap <buffer> <silent> <nowait> p		:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6135   nnoremap <buffer> <silent> <nowait> P		:call <SID>NetrwPrevWinOpen(0)<cr>
6136   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6137   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6138   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6139   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6140   nnoremap <buffer> <silent> <nowait> 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>
6141   nnoremap <buffer> <silent> <nowait> s		:call <SID>NetrwSortStyle(0)<cr>
6142   nnoremap <buffer> <silent> <nowait> S		:call <SID>NetSortSequence(0)<cr>
6143   nnoremap <buffer> <silent> <nowait> t		:call <SID>NetrwSplit(1)<cr>
6144   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr>
6145   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr>
6146   nnoremap <buffer> <silent> <nowait> u		:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6147   nnoremap <buffer> <silent> <nowait> U		:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6148   nnoremap <buffer> <silent> <nowait> v		:call <SID>NetrwSplit(2)<cr>
6149   nnoremap <buffer> <silent> <nowait> x		:call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6150   nnoremap <buffer> <silent> <nowait> %		:call <SID>NetrwOpenFile(0)<cr>
6151   " remote insert-mode maps
6152   inoremap <buffer> <silent> <nowait> <cr>	<c-o>:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6153   inoremap <buffer> <silent> <nowait> <c-l>	<c-o>:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6154   inoremap <buffer> <silent> <nowait> <s-cr>	<c-o>:call <SID>TreeSqueezeDir(0)<cr>
6155   inoremap <buffer> <silent> <nowait> -		<c-o>:call <SID>NetrwBrowseUpDir(0)<cr>
6156   inoremap <buffer> <silent> <nowait> a		<c-o>:call <SID>NetrwHide(0)<cr>
6157   inoremap <buffer> <silent> <nowait> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6158   inoremap <buffer> <silent> <nowait> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6159   inoremap <buffer> <silent> <nowait> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6160   inoremap <buffer> <silent> <nowait> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6161   inoremap <buffer> <silent> <nowait> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6162   inoremap <buffer> <silent> <nowait> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6163   inoremap <buffer> <silent> <nowait> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6164   inoremap <buffer> <silent> <nowait> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6165   inoremap <buffer> <silent> <nowait> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6166   inoremap <buffer> <silent> <nowait> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6167   inoremap <buffer> <silent> <nowait> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6168   inoremap <buffer> <silent> <nowait> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6169   inoremap <buffer> <silent> <nowait> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6170   inoremap <buffer> <silent> <nowait> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6171   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6172   inoremap <buffer> <silent> <nowait> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6173   inoremap <buffer> <silent> <nowait> mX	<c-o>:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6174   inoremap <buffer> <silent> <nowait> mv	<c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6175   inoremap <buffer> <silent> <nowait> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6176   inoremap <buffer> <silent> <nowait> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6177   inoremap <buffer> <silent> <nowait> gh	<c-o>:<c-u>call <SID>NetrwHidden(0)<cr>
6178   inoremap <buffer> <silent> <nowait> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6179   inoremap <buffer> <silent> <nowait> C		<c-o>:call <SID>NetrwSetChgwin()<cr>
6180   inoremap <buffer> <silent> <nowait> i		<c-o>:call <SID>NetrwListStyle(0)<cr>
6181   inoremap <buffer> <silent> <nowait> I		<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
6182   inoremap <buffer> <silent> <nowait> o		<c-o>:call <SID>NetrwSplit(0)<cr>
6183   inoremap <buffer> <silent> <nowait> O		<c-o>:call <SID>NetrwObtain(0)<cr>
6184   inoremap <buffer> <silent> <nowait> p		<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6185   inoremap <buffer> <silent> <nowait> P		<c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
6186   inoremap <buffer> <silent> <nowait> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6187   inoremap <buffer> <silent> <nowait> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6188   inoremap <buffer> <silent> <nowait> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6189   inoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6190   inoremap <buffer> <silent> <nowait> 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>
6191   inoremap <buffer> <silent> <nowait> s		<c-o>:call <SID>NetrwSortStyle(0)<cr>
6192   inoremap <buffer> <silent> <nowait> S		<c-o>:call <SID>NetSortSequence(0)<cr>
6193   inoremap <buffer> <silent> <nowait> t		<c-o>:call <SID>NetrwSplit(1)<cr>
6194   inoremap <buffer> <silent> <nowait> Tb	<c-o>:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr>
6195   inoremap <buffer> <silent> <nowait> Th	<c-o>:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr>
6196   inoremap <buffer> <silent> <nowait> u		<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6197   inoremap <buffer> <silent> <nowait> U		<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6198   inoremap <buffer> <silent> <nowait> v		<c-o>:call <SID>NetrwSplit(2)<cr>
6199   inoremap <buffer> <silent> <nowait> x		<c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6200   inoremap <buffer> <silent> <nowait> %		<c-o>:call <SID>NetrwOpenFile(0)<cr>
6201   if !hasmapto('<Plug>NetrwHideEdit')
6202    nmap <buffer> <c-h> <Plug>NetrwHideEdit
6203    imap <buffer> <c-h> <Plug>NetrwHideEdit
6204   endif
6205   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
6206   if !hasmapto('<Plug>NetrwRefresh')
6207    nmap <buffer> <c-l> <Plug>NetrwRefresh
6208    imap <buffer> <c-l> <Plug>NetrwRefresh
6209   endif
6210
6211   let mapsafepath     = escape(s:path, s:netrw_map_escape)
6212   let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6213
6214   nnoremap <buffer> <silent> <Plug>NetrwRefresh	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6215   if g:netrw_mousemaps == 1
6216    nmap <buffer> <leftmouse>		<Plug>NetrwLeftmouse
6217    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
6218    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6219    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(0)<cr>
6220    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6221    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(0)<cr>
6222    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6223    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(0)<cr>
6224    nmap <middlemouse>			<Plug>NetrwMiddlemouse
6225    nno  <buffer> <silent>		<middlemouse>		<Plug>NetrwMiddlemouse <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
6226    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6227    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6228    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6229    ino  <buffer> <silent>		<Plug>ILeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(0)<cr>
6230    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6231    ino  <buffer> <silent>		<Plug>IMiddlemouse	<c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
6232    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6233    ino  <buffer> <silent>		<Plug>ISLeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6234    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6235    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6236    exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6237   endif
6238   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6239   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6240   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6241   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6242   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6243   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6244   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6245   exe 'inoremap <buffer> <silent> <nowait> <del>	<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6246   exe 'inoremap <buffer> <silent> <nowait> d		<c-o>:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6247   exe 'inoremap <buffer> <silent> <nowait> D		<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6248   exe 'inoremap <buffer> <silent> <nowait> R		<c-o>:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6249   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6250   inoremap <buffer> <F1>			<c-o>:he netrw-quickhelp<cr>
6251
6252   " support user-specified maps
6253   call netrw#UserMaps(0)
6254  endif
6255
6256"  call Dret("s:NetrwMaps")
6257endfun
6258
6259" ---------------------------------------------------------------------
6260" s:NetrwCommands: sets up commands 				{{{2
6261"  If -buffer, the command is only available from within netrw buffers
6262"  Otherwise, the command is available from any window, so long as netrw
6263"  has been used at least once in the session.
6264fun! s:NetrwCommands(islocal)
6265"  call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6266
6267  com! -nargs=* -complete=file -bang	NetrwMB	call s:NetrwBookmark(<bang>0,<f-args>)
6268  com! -nargs=*			    	NetrwC	call s:NetrwSetChgwin(<q-args>)
6269  com! Rexplore if exists("w:netrw_rexlocal")|call s:NetrwRexplore(w:netrw_rexlocal,exists("w:netrw_rexdir")? w:netrw_rexdir : ".")|else|call netrw#ErrorMsg(s:WARNING,"not a former netrw window",79)|endif
6270  if a:islocal
6271   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(1,<f-args>)
6272  else
6273   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(0,<f-args>)
6274  endif
6275  com! -buffer -nargs=? -complete=file	MT	call s:NetrwMarkTarget(<q-args>)
6276
6277"  call Dret("s:NetrwCommands")
6278endfun
6279
6280" ---------------------------------------------------------------------
6281" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6282"                   glob()ing only works with local files
6283fun! s:NetrwMarkFiles(islocal,...)
6284"  call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6285  let curdir = s:NetrwGetCurdir(a:islocal)
6286  let i      = 1
6287  while i <= a:0
6288   if a:islocal
6289    if v:version == 704 && has("patch656")
6290     let mffiles= glob(a:{i},0,1,1)
6291    else
6292     let mffiles= glob(a:{i},0,1)
6293    endif
6294   else
6295    let mffiles= [a:{i}]
6296   endif
6297"   call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6298   for mffile in mffiles
6299"    call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6300    call s:NetrwMarkFile(a:islocal,mffile)
6301   endfor
6302   let i= i + 1
6303  endwhile
6304"  call Dret("s:NetrwMarkFiles")
6305endfun
6306
6307" ---------------------------------------------------------------------
6308" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6309fun! s:NetrwMarkTarget(...)
6310"  call Dfunc("s:NetrwMarkTarget() a:0=".a:0)
6311  if a:0 == 0 || (a:0 == 1 && a:1 == "")
6312   let curdir = s:NetrwGetCurdir(1)
6313   let tgt    = b:netrw_curdir
6314  else
6315   let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6316   let tgt    = a:1
6317  endif
6318"  call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
6319  let s:netrwmftgt         = tgt
6320  let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6321  let curislocal           = b:netrw_curdir !~ '^\a\{3,}://'
6322  let svpos                = netrw#SavePosn()
6323  call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./'))
6324  call netrw#RestorePosn(svpos)
6325"  call Dret("s:NetrwMarkTarget")
6326endfun
6327
6328" ---------------------------------------------------------------------
6329" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6330"                  mark and unmark files.  If a markfile list exists,
6331"                  then the rename and delete functions will use it instead
6332"                  of whatever may happen to be under the cursor at that
6333"                  moment.  When the mouse and gui are available,
6334"                  shift-leftmouse may also be used to mark files.
6335"
6336"  Creates two lists
6337"    s:netrwmarkfilelist    -- holds complete paths to all marked files
6338"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
6339"
6340"  Creates a marked file match string
6341"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
6342"
6343"  Creates a buffer version of islocal
6344"    b:netrw_islocal
6345fun! s:NetrwMarkFile(islocal,fname)
6346"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6347"  call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6348
6349  " sanity check
6350  if empty(a:fname)
6351"   call Dret("s:NetrwMarkFile : emtpy fname")
6352   return
6353  endif
6354  let curdir = s:NetrwGetCurdir(a:islocal)
6355
6356  let ykeep   = @@
6357  let curbufnr= bufnr("%")
6358  if a:fname =~ '^\a'
6359   let leader= '\<'
6360  else
6361   let leader= ''
6362  endif
6363  if a:fname =~ '\a$'
6364   let trailer = '\>[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6365  else
6366   let trailer = '[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6367  endif
6368
6369  if exists("s:netrwmarkfilelist_".curbufnr)
6370   " markfile list pre-exists
6371"   call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6372"   call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6373"   call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6374   let b:netrw_islocal= a:islocal
6375
6376   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6377    " append filename to buffer's markfilelist
6378"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6379    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6380    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6381
6382   else
6383    " remove filename from buffer's markfilelist
6384"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6385    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6386    if s:netrwmarkfilelist_{curbufnr} == []
6387     " local markfilelist is empty; remove it entirely
6388"     call Decho("markfile list now empty",'~'.expand("<slnum>"))
6389     call s:NetrwUnmarkList(curbufnr,curdir)
6390    else
6391     " rebuild match list to display markings correctly
6392"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6393     let s:netrwmarkfilemtch_{curbufnr}= ""
6394     let first                         = 1
6395     for fname in s:netrwmarkfilelist_{curbufnr}
6396      if first
6397       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6398      else
6399       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6400      endif
6401      let first= 0
6402     endfor
6403"     call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6404    endif
6405   endif
6406
6407  else
6408   " initialize new markfilelist
6409"   call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6410
6411"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6412   let s:netrwmarkfilelist_{curbufnr}= []
6413   call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6414"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6415
6416   " build initial markfile matching pattern
6417   if a:fname =~ '/$'
6418    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6419   else
6420    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6421   endif
6422"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6423  endif
6424
6425  " handle global markfilelist
6426  if exists("s:netrwmarkfilelist")
6427   let dname= s:ComposePath(b:netrw_curdir,a:fname)
6428   if index(s:netrwmarkfilelist,dname) == -1
6429    " append new filename to global markfilelist
6430    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6431"    call Decho("append filename<".a:fname."> to global markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6432   else
6433    " remove new filename from global markfilelist
6434"    call Decho("filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6435    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6436"    call Decho("ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6437    if s:netrwmarkfilelist == []
6438     unlet s:netrwmarkfilelist
6439    endif
6440   endif
6441  else
6442   " initialize new global-directory markfilelist
6443   let s:netrwmarkfilelist= []
6444   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6445"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6446  endif
6447
6448  " set up 2match'ing to netrwmarkfilemtch_# list
6449  if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6450"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6451   if exists("g:did_drchip_netrwlist_syntax")
6452    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6453   endif
6454  else
6455"   call Decho("2match none",'~'.expand("<slnum>"))
6456   2match none
6457  endif
6458  let @@= ykeep
6459"  call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">")
6460endfun
6461
6462" ---------------------------------------------------------------------
6463" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6464"                          compress/decompress files using the programs
6465"                          in g:netrw_compress and g:netrw_uncompress,
6466"                          using g:netrw_compress_suffix to know which to
6467"                          do.  By default:
6468"                            g:netrw_compress        = "gzip"
6469"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6470fun! s:NetrwMarkFileCompress(islocal)
6471"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
6472  let svpos    = netrw#SavePosn()
6473  let curdir   = s:NetrwGetCurdir(a:islocal)
6474  let curbufnr = bufnr("%")
6475
6476  " sanity check
6477  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6478   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6479"   call Dret("s:NetrwMarkFileCompress")
6480   return
6481  endif
6482"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6483
6484  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6485
6486   " for every filename in the marked list
6487   for fname in s:netrwmarkfilelist_{curbufnr}
6488    let sfx= substitute(fname,'^.\{-}\(\.\a\+\)$','\1','')
6489"    call Decho("extracted sfx<".sfx.">",'~'.expand("<slnum>"))
6490    if exists("g:netrw_decompress['".sfx."']")
6491     " fname has a suffix indicating that its compressed; apply associated decompression routine
6492     let exe= g:netrw_decompress[sfx]
6493"     call Decho("fname<".fname."> is compressed so decompress with <".exe.">",'~'.expand("<slnum>"))
6494     let exe= netrw#WinPath(exe)
6495     if a:islocal
6496      if g:netrw_keepdir
6497       let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6498      endif
6499     else
6500      let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6501     endif
6502     if executable(exe)
6503      if a:islocal
6504       call system(exe." ".fname)
6505      else
6506       NetrwKeepj call s:RemoteSystem(exe." ".fname)
6507      endif
6508     else
6509      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6510     endif
6511    endif
6512    unlet sfx
6513
6514    if exists("exe")
6515     unlet exe
6516    elseif a:islocal
6517     " fname not a compressed file, so compress it
6518     call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
6519    else
6520     " fname not a compressed file, so compress it
6521     NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
6522    endif
6523   endfor	" for every file in the marked list
6524
6525   call s:NetrwUnmarkList(curbufnr,curdir)
6526   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6527   NetrwKeepj call netrw#RestorePosn(svpos)
6528  endif
6529"  call Dret("s:NetrwMarkFileCompress")
6530endfun
6531
6532" ---------------------------------------------------------------------
6533" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
6534"                      If no marked files, then set up directory as the
6535"                      target.  Currently does not support copying entire
6536"                      directories.  Uses the local-buffer marked file list.
6537"                      Returns 1=success  (used by NetrwMarkFileMove())
6538"                              0=failure
6539fun! s:NetrwMarkFileCopy(islocal,...)
6540"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
6541
6542  let curdir   = s:NetrwGetCurdir(a:islocal)
6543  let curbufnr = bufnr("%")
6544
6545  " sanity check
6546  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6547   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6548"   call Dret("s:NetrwMarkFileCopy")
6549   return
6550  endif
6551"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6552
6553  if !exists("s:netrwmftgt")
6554   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
6555"   call Dret("s:NetrwMarkFileCopy 0")
6556   return 0
6557  endif
6558"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
6559
6560  if      a:islocal &&  s:netrwmftgt_islocal
6561   " Copy marked files, local directory to local directory
6562"   call Decho("copy from local to local",'~'.expand("<slnum>"))
6563   if !executable(g:netrw_localcopycmd) && g:netrw_localcopycmd !~ '^'.expand("$COMSPEC").'\s'
6564    call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
6565"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
6566    return
6567   endif
6568
6569   " copy marked files while within the same directory (ie. allow renaming)
6570   if simplify(s:netrwmftgt) == simplify(b:netrw_curdir)
6571    if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
6572     " only one marked file
6573"     call Decho("case: only one marked file",'~'.expand("<slnum>"))
6574     let args    = s:ShellEscape(b:netrw_curdir."/".s:netrwmarkfilelist_{bufnr('%')}[0])
6575     let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
6576    elseif a:0 == 1
6577"     call Decho("case: handling one input argument",'~'.expand("<slnum>"))
6578     " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
6579     let args    = s:ShellEscape(b:netrw_curdir."/".a:1)
6580     let oldname = a:1
6581    else
6582     " copy multiple marked files inside the same directory
6583"     call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
6584     let s:recursive= 1
6585     for oldname in s:netrwmarkfilelist_{bufnr("%")}
6586      let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
6587      if ret == 0
6588       break
6589      endif
6590     endfor
6591     unlet s:recursive
6592     call s:NetrwUnmarkList(curbufnr,curdir)
6593"     call Dret("s:NetrwMarkFileCopy ".ret)
6594     return ret
6595    endif
6596
6597    call inputsave()
6598    let newname= input("Copy ".oldname." to : ",oldname,"file")
6599    call inputrestore()
6600    if newname == ""
6601"     call Dret("s:NetrwMarkFileCopy 0")
6602     return 0
6603    endif
6604    let args= s:ShellEscape(oldname)
6605    let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
6606   else
6607    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
6608    let tgt = s:ShellEscape(s:netrwmftgt)
6609   endif
6610   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
6611    let args= substitute(args,'/','\\','g')
6612    let tgt = substitute(tgt, '/','\\','g')
6613   endif
6614   if args =~ "'"|let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
6615   if tgt  =~ "'"|let tgt = substitute(tgt,"'\\(.*\\)'",'\1','') |endif
6616   if args =~ '//$'|let args= substitute(args,'//$','/','')|endif
6617   if isdirectory(s:NetrwFile(args))
6618"    call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
6619    let copycmd= g:netrw_localcopydircmd
6620"    call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
6621    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
6622     " window's xcopy doesn't copy a directory to a target properly.  Instead, it copies a directory's
6623     " contents to a target.  One must append the source directory name to the target to get xcopy to
6624     " do the right thing.
6625     let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
6626"     call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
6627    endif
6628   else
6629    let copycmd= g:netrw_localcopycmd
6630   endif
6631   if g:netrw_localcopycmd =~ '\s'
6632    let copycmd     = substitute(copycmd,'\s.*$','','')
6633    let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
6634    let copycmd     = netrw#WinPath(copycmd).copycmdargs
6635   else
6636    let copycmd = netrw#WinPath(copycmd)
6637   endif
6638"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
6639"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
6640"   call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
6641"   call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
6642   call system(copycmd." '".args."' '".tgt."'")
6643   if v:shell_error != 0
6644    if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
6645     call netrw#ErrorMsg(s:ERROR,"copy failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",101)
6646    else
6647     call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
6648    endif
6649"    call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
6650    return 0
6651   endif
6652
6653  elseif  a:islocal && !s:netrwmftgt_islocal
6654   " Copy marked files, local directory to remote directory
6655"   call Decho("copy from local to remote",'~'.expand("<slnum>"))
6656   NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6657
6658  elseif !a:islocal &&  s:netrwmftgt_islocal
6659   " Copy marked files, remote directory to local directory
6660"   call Decho("copy from remote to local",'~'.expand("<slnum>"))
6661   NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6662
6663  elseif !a:islocal && !s:netrwmftgt_islocal
6664   " Copy marked files, remote directory to remote directory
6665"   call Decho("copy from remote to remote",'~'.expand("<slnum>"))
6666   let curdir = getcwd()
6667   let tmpdir = s:GetTempfile("")
6668   if tmpdir !~ '/'
6669    let tmpdir= curdir."/".tmpdir
6670   endif
6671   if exists("*mkdir")
6672    call mkdir(tmpdir)
6673   else
6674    call s:NetrwExe("sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1))
6675    if v:shell_error != 0
6676     call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6677"     call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
6678     return
6679    endif
6680   endif
6681   if isdirectory(s:NetrwFile(tmpdir))
6682    call s:NetrwLcd(tmpdir)
6683    NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
6684    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
6685    NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
6686    if getcwd() == tmpdir
6687     for fname in s:netrwmarkfilelist_{bufnr('%')}
6688      NetrwKeepj call s:NetrwDelete(fname)
6689     endfor
6690     call s:NetrwLcd(curdir)
6691     call s:NetrwExe("sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1))
6692     if v:shell_error != 0
6693      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localrmdir<".g:netrw_localrmdir."> to something that works",80)
6694"      call Dret("s:NetrwMarkFileCopy : failed: sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1) )
6695      return
6696     endif
6697    else
6698     call s:NetrwLcd(curdir)
6699    endif
6700   endif
6701  endif
6702
6703  " -------
6704  " cleanup
6705  " -------
6706"   call Decho("cleanup",'~'.expand("<slnum>"))
6707  if !exists("s:recursive")
6708   " remove markings from local buffer
6709   call s:NetrwUnmarkList(curbufnr,curdir)
6710  endif
6711
6712  " refresh buffers
6713  if !s:netrwmftgt_islocal
6714   call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
6715  endif
6716  if a:islocal
6717   NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
6718  endif
6719  if g:netrw_fastbrowse <= 1
6720   NetrwKeepj call s:LocalBrowseRefresh()
6721  endif
6722
6723"  call Dret("s:NetrwMarkFileCopy 1")
6724  return 1
6725endfun
6726
6727" ---------------------------------------------------------------------
6728" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
6729"                      invoke vim's diff mode on the marked files.
6730"                      Either two or three files can be so handled.
6731"                      Uses the global marked file list.
6732fun! s:NetrwMarkFileDiff(islocal)
6733"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6734  let curbufnr= bufnr("%")
6735
6736  " sanity check
6737  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6738   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6739"   call Dret("s:NetrwMarkFileDiff")
6740   return
6741  endif
6742  let curdir= s:NetrwGetCurdir(a:islocal)
6743"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6744
6745  if exists("s:netrwmarkfilelist_{".curbufnr."}")
6746   let cnt    = 0
6747   for fname in s:netrwmarkfilelist
6748    let cnt= cnt + 1
6749    if cnt == 1
6750"     call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
6751     exe "NetrwKeepj e ".fnameescape(fname)
6752     diffthis
6753    elseif cnt == 2 || cnt == 3
6754     vsplit
6755     wincmd l
6756"     call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
6757     exe "NetrwKeepj e ".fnameescape(fname)
6758     diffthis
6759    else
6760     break
6761    endif
6762   endfor
6763   call s:NetrwUnmarkList(curbufnr,curdir)
6764  endif
6765
6766"  call Dret("s:NetrwMarkFileDiff")
6767endfun
6768
6769" ---------------------------------------------------------------------
6770" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
6771"                       Uses global markfilelist
6772fun! s:NetrwMarkFileEdit(islocal)
6773"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
6774
6775  let curdir   = s:NetrwGetCurdir(a:islocal)
6776  let curbufnr = bufnr("%")
6777
6778  " sanity check
6779  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6780   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6781"   call Dret("s:NetrwMarkFileEdit")
6782   return
6783  endif
6784"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6785
6786  if exists("s:netrwmarkfilelist_{curbufnr}")
6787   call s:SetRexDir(a:islocal,curdir)
6788   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
6789   " unmark markedfile list
6790"   call s:NetrwUnmarkList(curbufnr,curdir)
6791   call s:NetrwUnmarkAll()
6792"   call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
6793   exe "sil args ".flist
6794  endif
6795  echo "(use :bn, :bp to navigate files; :Rex to return)"
6796
6797"  call Dret("s:NetrwMarkFileEdit")
6798endfun
6799
6800" ---------------------------------------------------------------------
6801" s:NetrwMarkFileQFEL: convert a quickfix-error list into a marked file list {{{2
6802fun! s:NetrwMarkFileQFEL(islocal,qfel)
6803"  call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
6804  call s:NetrwUnmarkAll()
6805  let curbufnr= bufnr("%")
6806
6807  if !empty(a:qfel)
6808   for entry in a:qfel
6809    let bufnmbr= entry["bufnr"]
6810"    call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
6811    if !exists("s:netrwmarkfilelist_{curbufnr}")
6812"     call Decho("case: no marked file list",'~'.expand("<slnum>"))
6813     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
6814    elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
6815     " s:NetrwMarkFile will remove duplicate entries from the marked file list.
6816     " So, this test lets two or more hits on the same pattern to be ignored.
6817"     call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
6818     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
6819    else
6820"     call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
6821    endif
6822   endfor
6823   echo "(use me to edit marked files)"
6824  else
6825   call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
6826  endif
6827
6828"  call Dret("s:NetrwMarkFileQFEL")
6829endfun
6830
6831" ---------------------------------------------------------------------
6832" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
6833"                     mx enbloc=0: Uses the local marked-file list, applies command to each file individually
6834"                     mX enbloc=1: Uses the global marked-file list, applies command to entire list
6835fun! s:NetrwMarkFileExe(islocal,enbloc)
6836"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")")
6837  let svpos    = netrw#SavePosn()
6838  let curdir   = s:NetrwGetCurdir(a:islocal)
6839  let curbufnr = bufnr("%")
6840
6841  if a:enbloc == 0
6842   " individually apply command to files, one at a time
6843    " sanity check
6844    if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6845     NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6846"     call Dret("s:NetrwMarkFileExe")
6847     return
6848    endif
6849"    call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6850
6851    if exists("s:netrwmarkfilelist_{curbufnr}")
6852     " get the command
6853     call inputsave()
6854     let cmd= input("Enter command: ","","file")
6855     call inputrestore()
6856"     call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
6857     if cmd == ""
6858"      call Dret("s:NetrwMarkFileExe : early exit, empty command")
6859      return
6860     endif
6861
6862     " apply command to marked files, individually.  Substitute: filename -> %
6863     " If no %, then append a space and the filename to the command
6864     for fname in s:netrwmarkfilelist_{curbufnr}
6865      if a:islocal
6866       if g:netrw_keepdir
6867	let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
6868       endif
6869      else
6870       let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
6871      endif
6872      if cmd =~ '%'
6873       let xcmd= substitute(cmd,'%',fname,'g')
6874      else
6875       let xcmd= cmd.' '.fname
6876      endif
6877      if a:islocal
6878"       call Decho("local: xcmd<".xcmd.">",'~'.expand("<slnum>"))
6879       let ret= system(xcmd)
6880      else
6881"       call Decho("remote: xcmd<".xcmd.">",'~'.expand("<slnum>"))
6882       let ret= s:RemoteSystem(xcmd)
6883      endif
6884      if v:shell_error < 0
6885       NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
6886       break
6887      else
6888       echo ret
6889      endif
6890     endfor
6891
6892   " unmark marked file list
6893   call s:NetrwUnmarkList(curbufnr,curdir)
6894
6895   " refresh the listing
6896   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6897   NetrwKeepj call netrw#RestorePosn(svpos)
6898  else
6899   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
6900  endif
6901
6902 else " apply command to global list of files, en bloc
6903
6904  call inputsave()
6905  let cmd= input("Enter command: ","","file")
6906  call inputrestore()
6907"  call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
6908  if cmd == ""
6909"   call Dret("s:NetrwMarkFileExe : early exit, empty command")
6910   return
6911  endif
6912  if cmd =~ '%'
6913   let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
6914  else
6915   let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
6916  endif
6917  if a:islocal
6918   call system(cmd)
6919   if v:shell_error < 0
6920    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
6921   endif
6922  else
6923   let ret= s:RemoteSystem(cmd)
6924  endif
6925  call s:NetrwUnmarkAll()
6926
6927  " refresh the listing
6928  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6929  NetrwKeepj call netrw#RestorePosn(svpos)
6930
6931 endif
6932
6933"  call Dret("s:NetrwMarkFileExe")
6934endfun
6935
6936" ---------------------------------------------------------------------
6937" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
6938"                  as the marked file(s) (toggles suffix presence)
6939"                  Uses the local marked file list.
6940fun! s:NetrwMarkHideSfx(islocal)
6941"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
6942  let svpos    = netrw#SavePosn()
6943  let curbufnr = bufnr("%")
6944
6945  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
6946  if exists("s:netrwmarkfilelist_{curbufnr}")
6947
6948   for fname in s:netrwmarkfilelist_{curbufnr}
6949"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
6950     " construct suffix pattern
6951     if fname =~ '\.'
6952      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
6953     else
6954      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
6955     endif
6956     " determine if its in the hiding list or not
6957     let inhidelist= 0
6958     if g:netrw_list_hide != ""
6959      let itemnum = 0
6960      let hidelist= split(g:netrw_list_hide,',')
6961      for hidepat in hidelist
6962       if sfxpat == hidepat
6963        let inhidelist= 1
6964        break
6965       endif
6966       let itemnum= itemnum + 1
6967      endfor
6968     endif
6969"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
6970     if inhidelist
6971      " remove sfxpat from list
6972      call remove(hidelist,itemnum)
6973      let g:netrw_list_hide= join(hidelist,",")
6974     elseif g:netrw_list_hide != ""
6975      " append sfxpat to non-empty list
6976      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
6977     else
6978      " set hiding list to sfxpat
6979      let g:netrw_list_hide= sfxpat
6980     endif
6981    endfor
6982
6983   " refresh the listing
6984   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6985   NetrwKeepj call netrw#RestorePosn(svpos)
6986  else
6987   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
6988  endif
6989
6990"  call Dret("s:NetrwMarkHideSfx")
6991endfun
6992
6993" ---------------------------------------------------------------------
6994" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
6995"                     Uses the local marked-file list.
6996fun! s:NetrwMarkFileVimCmd(islocal)
6997"  call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")")
6998  let svpos    = netrw#SavePosn()
6999  let curdir   = s:NetrwGetCurdir(a:islocal)
7000  let curbufnr = bufnr("%")
7001
7002  " sanity check
7003  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7004   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7005"   call Dret("s:NetrwMarkFileVimCmd")
7006   return
7007  endif
7008"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7009
7010  if exists("s:netrwmarkfilelist_{curbufnr}")
7011   " get the command
7012   call inputsave()
7013   let cmd= input("Enter vim command: ","","file")
7014   call inputrestore()
7015"   call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7016   if cmd == ""
7017"    "   call Dret("s:NetrwMarkFileVimCmd : early exit, empty command")
7018    return
7019   endif
7020
7021   " apply command to marked files.  Substitute: filename -> %
7022   " If no %, then append a space and the filename to the command
7023   for fname in s:netrwmarkfilelist_{curbufnr}
7024"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7025    if a:islocal
7026     1split
7027     exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7028"     call Decho("local<".fname.">: exe ".cmd,'~'.expand("<slnum>"))
7029     exe cmd
7030     exe "sil! keepalt wq!"
7031    else
7032"     call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET",'~'.expand("<slnum>"))
7033     echo "sorry, \"mv\" not supported yet for remote files"
7034    endif
7035   endfor
7036
7037   " unmark marked file list
7038   call s:NetrwUnmarkList(curbufnr,curdir)
7039
7040   " refresh the listing
7041   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7042   NetrwKeepj call netrw#RestorePosn(svpos)
7043  else
7044   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7045  endif
7046
7047"  call Dret("s:NetrwMarkFileVimCmd")
7048endfun
7049
7050" ---------------------------------------------------------------------
7051" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7052"                  as the marked file(s) (toggles suffix presence)
7053"                  Uses the local marked file list.
7054fun! s:NetrwMarkHideSfx(islocal)
7055"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7056  let svpos    = netrw#SavePosn()
7057  let curbufnr = bufnr("%")
7058
7059  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7060  if exists("s:netrwmarkfilelist_{curbufnr}")
7061
7062   for fname in s:netrwmarkfilelist_{curbufnr}
7063"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7064     " construct suffix pattern
7065     if fname =~ '\.'
7066      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7067     else
7068      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7069     endif
7070     " determine if its in the hiding list or not
7071     let inhidelist= 0
7072     if g:netrw_list_hide != ""
7073      let itemnum = 0
7074      let hidelist= split(g:netrw_list_hide,',')
7075      for hidepat in hidelist
7076       if sfxpat == hidepat
7077        let inhidelist= 1
7078        break
7079       endif
7080       let itemnum= itemnum + 1
7081      endfor
7082     endif
7083"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7084     if inhidelist
7085      " remove sfxpat from list
7086      call remove(hidelist,itemnum)
7087      let g:netrw_list_hide= join(hidelist,",")
7088     elseif g:netrw_list_hide != ""
7089      " append sfxpat to non-empty list
7090      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7091     else
7092      " set hiding list to sfxpat
7093      let g:netrw_list_hide= sfxpat
7094     endif
7095    endfor
7096
7097   " refresh the listing
7098   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7099   NetrwKeepj call netrw#RestorePosn(svpos)
7100  else
7101   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7102  endif
7103
7104"  call Dret("s:NetrwMarkHideSfx")
7105endfun
7106
7107" ---------------------------------------------------------------------
7108" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7109"                     Uses the global markfilelist
7110fun! s:NetrwMarkFileGrep(islocal)
7111"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7112  let svpos    = netrw#SavePosn()
7113  let curbufnr = bufnr("%")
7114  let curdir   = s:NetrwGetCurdir(a:islocal)
7115
7116  if exists("s:netrwmarkfilelist")
7117"  call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7118   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7119   call s:NetrwUnmarkAll()
7120  else
7121"   call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7122   let netrwmarkfilelist= "*"
7123  endif
7124
7125  " ask user for pattern
7126  call inputsave()
7127  let pat= input("Enter pattern: ","")
7128  call inputrestore()
7129  let patbang = ""
7130  if pat =~ '^!'
7131   let patbang = "!"
7132   let pat     = strpart(pat,2)
7133  endif
7134  if pat =~ '^\i'
7135   let pat    = escape(pat,'/')
7136   let pat    = '/'.pat.'/'
7137  else
7138   let nonisi = pat[0]
7139  endif
7140
7141  " use vimgrep for both local and remote
7142"  call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7143  try
7144   exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7145  catch /^Vim\%((\a\+)\)\=:E480/
7146   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7147"   call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7148   return
7149  endtry
7150  echo "(use :cn, :cp to navigate, :Rex to return)"
7151
7152  2match none
7153  NetrwKeepj call netrw#RestorePosn(svpos)
7154
7155  if exists("nonisi")
7156   " original, user-supplied pattern did not begin with a character from isident
7157"   call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7158   if pat =~ nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7159    call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7160   endif
7161  endif
7162
7163"  call Dret("s:NetrwMarkFileGrep")
7164endfun
7165
7166" ---------------------------------------------------------------------
7167" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7168"                      uses the global marked file list
7169"                      s:netrwmfloc= 0: target directory is remote
7170"                                  = 1: target directory is local
7171fun! s:NetrwMarkFileMove(islocal)
7172"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7173  let curdir   = s:NetrwGetCurdir(a:islocal)
7174  let curbufnr = bufnr("%")
7175
7176  " sanity check
7177  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7178   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7179"   call Dret("s:NetrwMarkFileMove")
7180   return
7181  endif
7182"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7183
7184  if !exists("s:netrwmftgt")
7185   NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7186"   call Dret("s:NetrwMarkFileCopy 0")
7187   return 0
7188  endif
7189"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7190
7191  if      a:islocal &&  s:netrwmftgt_islocal
7192   " move: local -> local
7193"   call Decho("move from local to local",'~'.expand("<slnum>"))
7194"   call Decho("local to local move",'~'.expand("<slnum>"))
7195   if !executable(g:netrw_localmovecmd) && g:netrw_localmovecmd !~ '^'.expand("$COMSPEC").'\s'
7196    call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7197"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7198    return
7199   endif
7200   let tgt         = s:ShellEscape(s:netrwmftgt)
7201"   call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7202   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7203    let tgt         = substitute(tgt, '/','\\','g')
7204"    call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7205    if g:netrw_localmovecmd =~ '\s'
7206     let movecmd     = substitute(g:netrw_localmovecmd,'\s.*$','','')
7207     let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7208     let movecmd     = netrw#WinPath(movecmd).movecmdargs
7209"     call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7210    else
7211     let movecmd = netrw#WinPath(movecmd)
7212"     call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7213    endif
7214   else
7215    let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7216"    call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7217   endif
7218   for fname in s:netrwmarkfilelist_{bufnr("%")}
7219    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7220     let fname= substitute(fname,'/','\\','g')
7221    endif
7222"    call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7223    let ret= system(movecmd." ".s:ShellEscape(fname)." ".tgt)
7224    if v:shell_error != 0
7225     if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7226      call netrw#ErrorMsg(s:ERROR,"move failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",100)
7227     else
7228      call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7229     endif
7230     break
7231    endif
7232   endfor
7233
7234  elseif  a:islocal && !s:netrwmftgt_islocal
7235   " move: local -> remote
7236"   call Decho("move from local to remote",'~'.expand("<slnum>"))
7237"   call Decho("copy",'~'.expand("<slnum>"))
7238   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7239   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7240"   call Decho("remove",'~'.expand("<slnum>"))
7241   for fname in mflist
7242    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7243    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7244   endfor
7245   unlet mflist
7246
7247  elseif !a:islocal &&  s:netrwmftgt_islocal
7248   " move: remote -> local
7249"   call Decho("move from remote to local",'~'.expand("<slnum>"))
7250"   call Decho("copy",'~'.expand("<slnum>"))
7251   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7252   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7253"   call Decho("remove",'~'.expand("<slnum>"))
7254   for fname in mflist
7255    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7256    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7257   endfor
7258   unlet mflist
7259
7260  elseif !a:islocal && !s:netrwmftgt_islocal
7261   " move: remote -> remote
7262"   call Decho("move from remote to remote",'~'.expand("<slnum>"))
7263"   call Decho("copy",'~'.expand("<slnum>"))
7264   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7265   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7266"   call Decho("remove",'~'.expand("<slnum>"))
7267   for fname in mflist
7268    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7269    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7270   endfor
7271   unlet mflist
7272  endif
7273
7274  " -------
7275  " cleanup
7276  " -------
7277"  call Decho("cleanup",'~'.expand("<slnum>"))
7278
7279  " remove markings from local buffer
7280  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7281
7282  " refresh buffers
7283  if !s:netrwmftgt_islocal
7284"   call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7285   NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7286  endif
7287  if a:islocal
7288"   call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7289   NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7290  endif
7291  if g:netrw_fastbrowse <= 1
7292"   call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7293   NetrwKeepj call s:LocalBrowseRefresh()
7294  endif
7295
7296"  call Dret("s:NetrwMarkFileMove")
7297endfun
7298
7299" ---------------------------------------------------------------------
7300" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7301"                       using the hardcopy command.  Local marked-file list only.
7302fun! s:NetrwMarkFilePrint(islocal)
7303"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7304  let curbufnr= bufnr("%")
7305
7306  " sanity check
7307  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7308   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7309"   call Dret("s:NetrwMarkFilePrint")
7310   return
7311  endif
7312"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7313  let curdir= s:NetrwGetCurdir(a:islocal)
7314
7315  if exists("s:netrwmarkfilelist_{curbufnr}")
7316   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7317   call s:NetrwUnmarkList(curbufnr,curdir)
7318   for fname in netrwmarkfilelist
7319    if a:islocal
7320     if g:netrw_keepdir
7321      let fname= s:ComposePath(curdir,fname)
7322     endif
7323    else
7324     let fname= curdir.fname
7325    endif
7326    1split
7327    " the autocmds will handle both local and remote files
7328"    call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7329    exe "sil NetrwKeepj e ".fnameescape(fname)
7330"    call Decho("hardcopy",'~'.expand("<slnum>"))
7331    hardcopy
7332    q
7333   endfor
7334   2match none
7335  endif
7336"  call Dret("s:NetrwMarkFilePrint")
7337endfun
7338
7339" ---------------------------------------------------------------------
7340" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7341"                        files when given a regexp (for which a prompt is
7342"                        issued) (matches to name of files).
7343fun! s:NetrwMarkFileRegexp(islocal)
7344"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7345
7346  " get the regular expression
7347  call inputsave()
7348  let regexp= input("Enter regexp: ","","file")
7349  call inputrestore()
7350
7351  if a:islocal
7352   let curdir= s:NetrwGetCurdir(a:islocal)
7353   " get the matching list of files using local glob()
7354"   call Decho("handle local regexp",'~'.expand("<slnum>"))
7355   let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7356   if v:version == 704 && has("patch656")
7357    let files   = glob(s:ComposePath(dirname,regexp),0,0,1)
7358   else
7359    let files   = glob(s:ComposePath(dirname,regexp),0,0)
7360   endif
7361"   call Decho("files<".files.">",'~'.expand("<slnum>"))
7362   let filelist= split(files,"\n")
7363
7364  " mark the list of files
7365  for fname in filelist
7366"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7367   NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7368  endfor
7369
7370  else
7371"   call Decho("handle remote regexp",'~'.expand("<slnum>"))
7372
7373   " convert displayed listing into a filelist
7374   let eikeep = &ei
7375   let areg   = @a
7376   sil NetrwKeepj %y a
7377   setl ei=all ma
7378"   call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7379   1split
7380   NetrwKeepj call s:NetrwEnew()
7381   NetrwKeepj call s:NetrwSafeOptions()
7382   sil NetrwKeepj norm! "ap
7383   NetrwKeepj 2
7384   let bannercnt= search('^" =====','W')
7385   exe "sil NetrwKeepj 1,".bannercnt."d"
7386   setl bt=nofile
7387   if     g:netrw_liststyle == s:LONGLIST
7388    sil NetrwKeepj %s/\s\{2,}\S.*$//e
7389    call histdel("/",-1)
7390   elseif g:netrw_liststyle == s:WIDELIST
7391    sil NetrwKeepj %s/\s\{2,}/\r/ge
7392    call histdel("/",-1)
7393   elseif g:netrw_liststyle == s:TREELIST
7394    exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7395    sil! NetrwKeepj g/^ .*$/d
7396    call histdel("/",-1)
7397    call histdel("/",-1)
7398   endif
7399   " convert regexp into the more usual glob-style format
7400   let regexp= substitute(regexp,'\*','.*','g')
7401"   call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7402   exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7403   call histdel("/",-1)
7404   let filelist= getline(1,line("$"))
7405   q!
7406   for filename in filelist
7407    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7408   endfor
7409   unlet filelist
7410   let @a  = areg
7411   let &ei = eikeep
7412  endif
7413  echo "  (use me to edit marked files)"
7414
7415"  call Dret("s:NetrwMarkFileRegexp")
7416endfun
7417
7418" ---------------------------------------------------------------------
7419" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7420"                        Uses the local marked file list.
7421fun! s:NetrwMarkFileSource(islocal)
7422"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7423  let curbufnr= bufnr("%")
7424
7425  " sanity check
7426  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7427   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7428"   call Dret("s:NetrwMarkFileSource")
7429   return
7430  endif
7431"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7432  let curdir= s:NetrwGetCurdir(a:islocal)
7433
7434  if exists("s:netrwmarkfilelist_{curbufnr}")
7435   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7436   call s:NetrwUnmarkList(curbufnr,curdir)
7437   for fname in netrwmarkfilelist
7438    if a:islocal
7439     if g:netrw_keepdir
7440      let fname= s:ComposePath(curdir,fname)
7441     endif
7442    else
7443     let fname= curdir.fname
7444    endif
7445    " the autocmds will handle sourcing both local and remote files
7446"    call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7447    exe "so ".fnameescape(fname)
7448   endfor
7449   2match none
7450  endif
7451"  call Dret("s:NetrwMarkFileSource")
7452endfun
7453
7454" ---------------------------------------------------------------------
7455" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
7456"                     Uses the global markfilelist
7457fun! s:NetrwMarkFileTag(islocal)
7458"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
7459  let svpos    = netrw#SavePosn()
7460  let curdir   = s:NetrwGetCurdir(a:islocal)
7461  let curbufnr = bufnr("%")
7462
7463  " sanity check
7464  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7465   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7466"   call Dret("s:NetrwMarkFileTag")
7467   return
7468  endif
7469"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7470
7471  if exists("s:netrwmarkfilelist")
7472"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7473   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
7474   call s:NetrwUnmarkAll()
7475
7476   if a:islocal
7477    if executable(g:netrw_ctags)
7478"     call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("<slnum>"))
7479     call system(g:netrw_ctags." ".netrwmarkfilelist)
7480    else
7481     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
7482    endif
7483   else
7484    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
7485    call netrw#Obtain(a:islocal,"tags")
7486    let curdir= b:netrw_curdir
7487    1split
7488    NetrwKeepj e tags
7489    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
7490"    call Decho("curdir<".curdir."> path<".path.">",'~'.expand("<slnum>"))
7491    exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
7492    call histdel("/",-1)
7493    wq!
7494   endif
7495   2match none
7496   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7497   call netrw#RestorePosn(svpos)
7498  endif
7499
7500"  call Dret("s:NetrwMarkFileTag")
7501endfun
7502
7503" ---------------------------------------------------------------------
7504" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
7505"   Sets up two variables,
7506"     s:netrwmftgt         : holds the target directory
7507"     s:netrwmftgt_islocal : 0=target directory is remote
7508"                            1=target directory is local
7509fun! s:NetrwMarkFileTgt(islocal)
7510"  call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
7511  let svpos  = netrw#SavePosn()
7512  let curdir = s:NetrwGetCurdir(a:islocal)
7513  let hadtgt = exists("s:netrwmftgt")
7514  if !exists("w:netrw_bannercnt")
7515   let w:netrw_bannercnt= b:netrw_bannercnt
7516  endif
7517
7518  " set up target
7519  if line(".") < w:netrw_bannercnt
7520"   call Decho("set up target: line(.) < w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
7521   " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
7522   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
7523"    call Decho("cursor in banner region, and target already is <".b:netrw_curdir.">: removing target",'~'.expand("<slnum>"))
7524    unlet s:netrwmftgt s:netrwmftgt_islocal
7525    if g:netrw_fastbrowse <= 1
7526     call s:LocalBrowseRefresh()
7527    endif
7528    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7529    call netrw#RestorePosn(svpos)
7530"    call Dret("s:NetrwMarkFileTgt : removed target")
7531    return
7532   else
7533    let s:netrwmftgt= b:netrw_curdir
7534"    call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7535   endif
7536
7537  else
7538   " get word under cursor.
7539   "  * If directory, use it for the target.
7540   "  * If file, use b:netrw_curdir for the target
7541"   call Decho("get word under cursor",'~'.expand("<slnum>"))
7542   let curword= s:NetrwGetWord()
7543   let tgtdir = s:ComposePath(curdir,curword)
7544   if a:islocal && isdirectory(s:NetrwFile(tgtdir))
7545    let s:netrwmftgt = tgtdir
7546"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7547   elseif !a:islocal && tgtdir =~ '/$'
7548    let s:netrwmftgt = tgtdir
7549"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7550   else
7551    let s:netrwmftgt = curdir
7552"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7553   endif
7554  endif
7555  if a:islocal
7556   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
7557   let s:netrwmftgt= simplify(s:netrwmftgt)
7558"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7559  endif
7560  if g:netrw_cygwin
7561   let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
7562   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
7563  endif
7564  let s:netrwmftgt_islocal= a:islocal
7565
7566  " need to do refresh so that the banner will be updated
7567  "  s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
7568  if g:netrw_fastbrowse <= 1
7569"   call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers")
7570   call s:LocalBrowseRefresh()
7571  endif
7572"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7573  if w:netrw_liststyle == s:TREELIST
7574   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop))
7575  else
7576   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7577  endif
7578  call netrw#RestorePosn(svpos)
7579  if !hadtgt
7580   sil! NetrwKeepj norm! j
7581  endif
7582
7583"  call Decho("getmatches=".string(getmatches()),'~'.expand("<slnum>"))
7584"  call Decho("s:netrwmarkfilelist=".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : 'n/a'),'~'.expand("<slnum>"))
7585"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
7586endfun
7587
7588" ---------------------------------------------------------------------
7589" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
7590fun! s:NetrwGetCurdir(islocal)
7591"  call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
7592
7593  if w:netrw_liststyle == s:TREELIST
7594   let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
7595"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
7596  elseif !exists("b:netrw_curdir")
7597   let b:netrw_curdir= getcwd()
7598"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
7599  endif
7600
7601"  call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern")
7602  if b:netrw_curdir !~ '\<\a\{3,}://'
7603   let curdir= b:netrw_curdir
7604"   call Decho("g:netrw_keepdir=".g:netrw_keepdir)
7605   if g:netrw_keepdir == 0
7606    call s:NetrwLcd(curdir)
7607   endif
7608  endif
7609
7610"  call Dret("s:NetrwGetCurdir <".curdir.">")
7611  return b:netrw_curdir
7612endfun
7613
7614" ---------------------------------------------------------------------
7615" s:NetrwOpenFile: query user for a filename and open it {{{2
7616fun! s:NetrwOpenFile(islocal)
7617"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
7618  let ykeep= @@
7619  call inputsave()
7620  let fname= input("Enter filename: ")
7621  call inputrestore()
7622  if fname !~ '[/\\]'
7623   if exists("b:netrw_curdir")
7624    if exists("g:netrw_quiet")
7625     let netrw_quiet_keep = g:netrw_quiet
7626    endif
7627    let g:netrw_quiet = 1
7628    " save position for benefit of Rexplore
7629    let s:rexposn_{bufnr("%")}= netrw#SavePosn()
7630"    call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to SavePosn",'~'.expand("<slnum>"))
7631    if b:netrw_curdir =~ '/$'
7632     exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
7633    else
7634     exe "e ".fnameescape(b:netrw_curdir."/".fname)
7635    endif
7636    if exists("netrw_quiet_keep")
7637     let g:netrw_quiet= netrw_quiet_keep
7638    else
7639     unlet g:netrw_quiet
7640    endif
7641   endif
7642  else
7643   exe "NetrwKeepj e ".fnameescape(fname)
7644  endif
7645  let @@= ykeep
7646"  call Dret("s:NetrwOpenFile")
7647endfun
7648
7649" ---------------------------------------------------------------------
7650" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
7651"               For the mapping to this function be made via
7652"               netrwPlugin, you'll need to have had
7653"               g:netrw_usetab set to non-zero.
7654fun! netrw#Shrink()
7655"  call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
7656  let curwin  = winnr()
7657  let wiwkeep = &wiw
7658  set wiw=1
7659
7660  if &ft == "netrw"
7661   if winwidth(0) > g:netrw_wiw
7662    let t:netrw_winwidth= winwidth(0)
7663    exe "vert resize ".g:netrw_wiw
7664    wincmd l
7665    if winnr() == curwin
7666     wincmd h
7667    endif
7668"    call Decho("vert resize 0",'~'.expand("<slnum>"))
7669   else
7670    exe "vert resize ".t:netrw_winwidth
7671"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7672   endif
7673
7674  elseif exists("t:netrw_lexbufnr")
7675   exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
7676   if     winwidth(bufwinnr(t:netrw_lexbufnr)) >  g:netrw_wiw
7677    let t:netrw_winwidth= winwidth(0)
7678    exe "vert resize ".g:netrw_wiw
7679    wincmd l
7680    if winnr() == curwin
7681     wincmd h
7682    endif
7683"    call Decho("vert resize 0",'~'.expand("<slnum>"))
7684   elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
7685    exe "vert resize ".t:netrw_winwidth
7686"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7687   else
7688    call netrw#Lexplore(0,0)
7689   endif
7690
7691  else
7692   call netrw#Lexplore(0,0)
7693  endif
7694  let wiw= wiwkeep
7695
7696"  call Dret("netrw#Shrink")
7697endfun
7698
7699" ---------------------------------------------------------------------
7700" s:NetSortSequence: allows user to edit the sorting sequence {{{2
7701fun! s:NetSortSequence(islocal)
7702"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
7703
7704  let ykeep= @@
7705  let svpos= netrw#SavePosn()
7706  call inputsave()
7707  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
7708  call inputrestore()
7709
7710  " refresh the listing
7711  let g:netrw_sort_sequence= newsortseq
7712  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7713  NetrwKeepj call netrw#RestorePosn(svpos)
7714  let @@= ykeep
7715
7716"  call Dret("NetSortSequence")
7717endfun
7718
7719" ---------------------------------------------------------------------
7720" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
7721"   User access provided by the <mF> mapping. (see :help netrw-mF)
7722"   Used by many MarkFile functions.
7723fun! s:NetrwUnmarkList(curbufnr,curdir)
7724"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
7725
7726  "  remove all files in local marked-file list from global list
7727  if exists("s:netrwmarkfilelist")
7728   for mfile in s:netrwmarkfilelist_{a:curbufnr}
7729    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
7730    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
7731    call remove(s:netrwmarkfilelist,idx)            " remove from global list
7732   endfor
7733   if s:netrwmarkfilelist == []
7734    unlet s:netrwmarkfilelist
7735   endif
7736
7737   " getting rid of the local marked-file lists is easy
7738   unlet s:netrwmarkfilelist_{a:curbufnr}
7739  endif
7740  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
7741   unlet s:netrwmarkfilemtch_{a:curbufnr}
7742  endif
7743  2match none
7744"  call Dret("s:NetrwUnmarkList")
7745endfun
7746
7747" ---------------------------------------------------------------------
7748" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
7749fun! s:NetrwUnmarkAll()
7750"  call Dfunc("s:NetrwUnmarkAll()")
7751  if exists("s:netrwmarkfilelist")
7752   unlet s:netrwmarkfilelist
7753  endif
7754  sil call s:NetrwUnmarkAll2()
7755  2match none
7756"  call Dret("s:NetrwUnmarkAll")
7757endfun
7758
7759" ---------------------------------------------------------------------
7760" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
7761fun! s:NetrwUnmarkAll2()
7762"  call Dfunc("s:NetrwUnmarkAll2()")
7763  redir => netrwmarkfilelist_let
7764  let
7765  redir END
7766  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
7767  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
7768  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
7769  for flist in netrwmarkfilelist_list
7770   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
7771   unlet s:netrwmarkfilelist_{curbufnr}
7772   unlet s:netrwmarkfilemtch_{curbufnr}
7773  endfor
7774"  call Dret("s:NetrwUnmarkAll2")
7775endfun
7776
7777" ---------------------------------------------------------------------
7778" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
7779"
7780" Marked files are in two types of lists:
7781"    s:netrwmarkfilelist    -- holds complete paths to all marked files
7782"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
7783"
7784" Marked files suitable for use with 2match are in:
7785"    s:netrwmarkfilemtch_#   -- used with 2match to display marked files
7786fun! s:NetrwUnMarkFile(islocal)
7787"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
7788  let svpos    = netrw#SavePosn()
7789  let curbufnr = bufnr("%")
7790
7791  " unmark marked file list
7792  " (although I expect s:NetrwUpload() to do it, I'm just making sure)
7793  if exists("s:netrwmarkfilelist")
7794"   "   call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
7795   unlet s:netrwmarkfilelist
7796  endif
7797
7798  let ibuf= 1
7799  while ibuf < bufnr("$")
7800   if exists("s:netrwmarkfilelist_".ibuf)
7801    unlet s:netrwmarkfilelist_{ibuf}
7802    unlet s:netrwmarkfilemtch_{ibuf}
7803   endif
7804   let ibuf = ibuf + 1
7805  endwhile
7806  2match none
7807
7808"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7809  call netrw#RestorePosn(svpos)
7810"  call Dret("s:NetrwUnMarkFile")
7811endfun
7812
7813" ---------------------------------------------------------------------
7814" s:NetrwMenu: generates the menu for gvim and netrw {{{2
7815fun! s:NetrwMenu(domenu)
7816
7817  if !exists("g:NetrwMenuPriority")
7818   let g:NetrwMenuPriority= 80
7819  endif
7820
7821  if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
7822"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
7823
7824   if !exists("s:netrw_menu_enabled") && a:domenu
7825"    call Decho("initialize menu",'~'.expand("<slnum>"))
7826    let s:netrw_menu_enabled= 1
7827    exe 'sil! menu '.g:NetrwMenuPriority.'.1      '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
7828    exe 'sil! menu '.g:NetrwMenuPriority.'.5      '.g:NetrwTopLvlMenu.'-Sep1-	:'
7829    exe 'sil! menu '.g:NetrwMenuPriority.'.6      '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
7830    exe 'sil! menu '.g:NetrwMenuPriority.'.7      '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
7831    if g:netrw_dirhistmax > 0
7832     exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
7833     exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
7834     exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
7835     exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
7836    else
7837     exe 'sil! menu '.g:NetrwMenuPriority.'.8     '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History	:echo "(disabled)"'."\<cr>"
7838    endif
7839    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1    '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o	o'
7840    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2    '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v	v'
7841    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3    '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t	t'
7842    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4    '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p	p'
7843    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
7844    exe 'sil! menu '.g:NetrwMenuPriority.'.9.6    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
7845    exe 'sil! menu '.g:NetrwMenuPriority.'.9.7    '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
7846    exe 'sil! menu '.g:NetrwMenuPriority.'.9.8    '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
7847    exe 'sil! menu '.g:NetrwMenuPriority.'.9.9    '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
7848    exe 'sil! menu '.g:NetrwMenuPriority.'.10     '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
7849    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
7850    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
7851    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
7852    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
7853    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
7854    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t	t'
7855    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
7856    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1   '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
7857    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
7858    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
7859    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
7860    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
7861    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
7862    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
7863    exe 'sil! menu '.g:NetrwMenuPriority.'.13     '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
7864    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
7865    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
7866    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3   '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
7867    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4   '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
7868    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5   '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
7869    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6   '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
7870    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7   '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
7871    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8   '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
7872    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9   '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
7873    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10  '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
7874    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11  '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
7875    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12  '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
7876    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13  '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
7877    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14  '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
7878    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15  '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
7879    exe 'sil! menu '.g:NetrwMenuPriority.'.15     '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
7880    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i	:let w:netrw_liststyle=0<cr><c-L>'
7881    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i	:let w:netrw_liststyle=1<cr><c-L>'
7882    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i	:let w:netrw_liststyle=2<cr><c-L>'
7883    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i	:let w:netrw_liststyle=3<cr><c-L>'
7884    exe 'sil! menu '.g:NetrwMenuPriority.'.16.2.1 '.g:NetrwTopLvlMenu.'Style.Normal-Hide-Show.Show\ All<tab>a	:let g:netrw_hide=0<cr><c-L>'
7885    exe 'sil! menu '.g:NetrwMenuPriority.'.16.2.3 '.g:NetrwTopLvlMenu.'Style.Normal-Hide-Show.Normal<tab>a	:let g:netrw_hide=1<cr><c-L>'
7886    exe 'sil! menu '.g:NetrwMenuPriority.'.16.2.2 '.g:NetrwTopLvlMenu.'Style.Normal-Hide-Show.Hidden\ Only<tab>a	:let g:netrw_hide=2<cr><c-L>'
7887    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3   '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
7888    exe 'sil! menu '.g:NetrwMenuPriority.'.16.4.1 '.g:NetrwTopLvlMenu.'Style.Sorting\ Method.Name<tab>s       :let g:netrw_sort_by="name"<cr><c-L>'
7889    exe 'sil! menu '.g:NetrwMenuPriority.'.16.4.2 '.g:NetrwTopLvlMenu.'Style.Sorting\ Method.Time<tab>s       :let g:netrw_sort_by="time"<cr><c-L>'
7890    exe 'sil! menu '.g:NetrwMenuPriority.'.16.4.3 '.g:NetrwTopLvlMenu.'Style.Sorting\ Method.Size<tab>s       :let g:netrw_sort_by="size"<cr><c-L>'
7891    exe 'sil! menu '.g:NetrwMenuPriority.'.16.4.3 '.g:NetrwTopLvlMenu.'Style.Sorting\ Method.Exten<tab>s      :let g:netrw_sort_by="exten"<cr><c-L>'
7892    exe 'sil! menu '.g:NetrwMenuPriority.'.17     '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
7893    exe 'sil! menu '.g:NetrwMenuPriority.'.18     '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
7894    let s:netrw_menucnt= 28
7895    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
7896    call s:NetrwTgtMenu()      " let bookmarks and history be easy targets
7897
7898   elseif !a:domenu
7899    let s:netrwcnt = 0
7900    let curwin     = winnr()
7901    windo if getline(2) =~ "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
7902    exe curwin."wincmd w"
7903
7904    if s:netrwcnt <= 1
7905"     call Decho("clear menus",'~'.expand("<slnum>"))
7906     exe 'sil! unmenu '.g:NetrwTopLvlMenu
7907"     call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
7908     sil! unlet s:netrw_menu_enabled
7909    endif
7910   endif
7911"   call Dret("NetrwMenu")
7912   return
7913  endif
7914
7915endfun
7916
7917" ---------------------------------------------------------------------
7918" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
7919"                Used by the O maps (as <SID>NetrwObtain())
7920fun! s:NetrwObtain(islocal)
7921"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
7922
7923  let ykeep= @@
7924  if exists("s:netrwmarkfilelist_{bufnr('%')}")
7925   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
7926   call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
7927   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
7928  else
7929   call netrw#Obtain(a:islocal,expand("<cWORD>"))
7930  endif
7931  let @@= ykeep
7932
7933"  call Dret("NetrwObtain")
7934endfun
7935
7936" ---------------------------------------------------------------------
7937" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
7938"   If there's only one window, then the window will first be split.
7939"   Returns:
7940"     choice = 0 : didn't have to choose
7941"     choice = 1 : saved modified file in window first
7942"     choice = 2 : didn't save modified file, opened window
7943"     choice = 3 : cancel open
7944fun! s:NetrwPrevWinOpen(islocal)
7945"  call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")")
7946
7947  let ykeep= @@
7948  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
7949  let curdir = b:netrw_curdir
7950
7951  " get last window number and the word currently under the cursor
7952  let origwin   = winnr()
7953  let lastwinnr = winnr("$")
7954  let curword   = s:NetrwGetWord()
7955  let choice    = 0
7956  let s:treedir = s:NetrwTreeDir(a:islocal)
7957  let curdir    = s:treedir
7958"  call Decho("winnr($)#".lastwinnr." curword<".curword.">",'~'.expand("<slnum>"))
7959
7960  let didsplit = 0
7961  if lastwinnr == 1
7962   " if only one window, open a new one first
7963"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("<slnum>"))
7964   if g:netrw_preview
7965    " vertically split preview window
7966    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
7967"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("<slnum>"))
7968    exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
7969   else
7970    " horizontally split preview window
7971    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
7972"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
7973    exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
7974   endif
7975   let didsplit = 1
7976"   call Decho("did split",'~'.expand("<slnum>"))
7977
7978  else
7979   NetrwKeepj call s:SaveBufVars()
7980   let eikeep= &ei
7981   setl ei=all
7982   wincmd p
7983"   call Decho("wincmd p  (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
7984
7985   " prevwinnr: the window number of the "prev" window
7986   " prevbufnr: the buffer number of the buffer in the "prev" window
7987   " bnrcnt   : the qty of windows open on the "prev" buffer
7988   let prevwinnr   = winnr()
7989   let prevbufnr   = bufnr("%")
7990   let prevbufname = bufname("%")
7991   let prevmod     = &mod
7992   let bnrcnt      = 0
7993   NetrwKeepj call s:RestoreBufVars()
7994"   call Decho("after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr,'~'.expand("<slnum>"))
7995
7996   " if the previous window's buffer has been changed (ie. its modified flag is set),
7997   " and it doesn't appear in any other extant window, then ask the
7998   " user if s/he wants to abandon modifications therein.
7999   if prevmod
8000"    call Decho("detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr(),'~'.expand("<slnum>"))
8001    windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8002"    call Decho("prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr,'~'.expand("<slnum>"))
8003    exe prevwinnr."wincmd w"
8004
8005    if bnrcnt == 1 && &hidden == 0
8006     " only one copy of the modified buffer in a window, and
8007     " hidden not set, so overwriting will lose the modified file.  Ask first...
8008     let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8009"     call Decho("(NetrwPrevWinOpen) prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("<slnum>"))
8010     let &ei= eikeep
8011
8012     if choice == 1
8013      " Yes -- write file & then browse
8014      let v:errmsg= ""
8015      sil w
8016      if v:errmsg != ""
8017       call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8018       exe origwin."wincmd w"
8019       let &ei = eikeep
8020       let @@  = ykeep
8021"       call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">")
8022       return choice
8023      endif
8024
8025     elseif choice == 2
8026      " No -- don't worry about changed file, just browse anyway
8027"      call Decho("don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")",'~'.expand("<slnum>"))
8028      echomsg "**note** changes to ".prevbufname." abandoned"
8029
8030     else
8031      " Cancel -- don't do this
8032"      call Decho("cancel, don't browse, switch to win#".origwin,'~'.expand("<slnum>"))
8033      exe origwin."wincmd w"
8034      let &ei= eikeep
8035      let @@ = ykeep
8036"      call Dret("s:NetrwPrevWinOpen ".choice." : cancelled")
8037      return choice
8038     endif
8039    endif
8040   endif
8041   let &ei= eikeep
8042  endif
8043
8044  " restore b:netrw_curdir (window split/enew may have lost it)
8045  let b:netrw_curdir= curdir
8046  if a:islocal < 2
8047   if a:islocal
8048    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
8049   else
8050    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
8051   endif
8052  endif
8053  let @@= ykeep
8054"  call Dret("s:NetrwPrevWinOpen ".choice)
8055  return choice
8056endfun
8057
8058" ---------------------------------------------------------------------
8059" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8060"                Always assumed to be local -> remote
8061"                call s:NetrwUpload(filename, target)
8062"                call s:NetrwUpload(filename, target, fromdirectory)
8063fun! s:NetrwUpload(fname,tgt,...)
8064"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
8065
8066  if a:tgt =~ '^\a\{3,}://'
8067   let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
8068  else
8069   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
8070  endif
8071"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
8072
8073  if a:0 > 0
8074   let fromdir= a:1
8075  else
8076   let fromdir= getcwd()
8077  endif
8078"  call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
8079
8080  if type(a:fname) == 1
8081   " handle uploading a single file using NetWrite
8082"   call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8083   1split
8084"   call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8085   exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8086"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8087   if a:tgt =~ '/$'
8088    let wfname= substitute(a:fname,'^.*/','','')
8089"    call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8090    exe "w! ".fnameescape(a:tgt.wfname)
8091   else
8092"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8093    exe "w ".fnameescape(a:tgt)
8094"    call Decho("done writing local->remote",'~'.expand("<slnum>"))
8095   endif
8096   q!
8097
8098  elseif type(a:fname) == 3
8099   " handle uploading a list of files via scp
8100"   call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8101   let curdir= getcwd()
8102   if a:tgt =~ '^scp:'
8103    call s:NetrwLcd(fromdir)
8104    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8105    let args    = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8106    if exists("g:netrw_port") && g:netrw_port != ""
8107     let useport= " ".g:netrw_scpport." ".g:netrw_port
8108    else
8109     let useport= ""
8110    endif
8111    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8112    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8113    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8114    call s:NetrwLcd(curdir)
8115
8116   elseif a:tgt =~ '^ftp:'
8117    call s:NetrwMethod(a:tgt)
8118
8119    if b:netrw_method == 2
8120     " handle uploading a list of files via ftp+.netrc
8121     let netrw_fname = b:netrw_fname
8122     sil NetrwKeepj new
8123"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8124
8125     NetrwKeepj put =g:netrw_ftpmode
8126"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8127
8128     if exists("g:netrw_ftpextracmd")
8129      NetrwKeepj put =g:netrw_ftpextracmd
8130"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8131     endif
8132
8133     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8134"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8135
8136     if tgtdir == ""
8137      let tgtdir= '/'
8138     endif
8139     NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8140"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8141
8142     for fname in a:fname
8143      NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8144"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8145     endfor
8146
8147     if exists("g:netrw_port") && g:netrw_port != ""
8148      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8149     else
8150"      call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8151      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8152     endif
8153     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8154     sil NetrwKeepj g/Local directory now/d
8155     call histdel("/",-1)
8156     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8157      call netrw#ErrorMsg(s:ERROR,getline(1),14)
8158     else
8159      bw!|q
8160     endif
8161
8162    elseif b:netrw_method == 3
8163     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8164     let netrw_fname= b:netrw_fname
8165     NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8166     let tmpbufnr= bufnr("%")
8167     setl ff=unix
8168
8169     if exists("g:netrw_port") && g:netrw_port != ""
8170      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8171"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8172     else
8173      NetrwKeepj put ='open '.g:netrw_machine
8174"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8175     endif
8176
8177     if exists("g:netrw_uid") && g:netrw_uid != ""
8178      if exists("g:netrw_ftp") && g:netrw_ftp == 1
8179       NetrwKeepj put =g:netrw_uid
8180"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8181       if exists("s:netrw_passwd")
8182        NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8183       endif
8184"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8185      elseif exists("s:netrw_passwd")
8186       NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8187"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8188      endif
8189     endif
8190
8191     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8192"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8193
8194     if exists("b:netrw_fname") && b:netrw_fname != ""
8195      NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8196"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8197     endif
8198
8199     if exists("g:netrw_ftpextracmd")
8200      NetrwKeepj put =g:netrw_ftpextracmd
8201"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8202     endif
8203
8204     for fname in a:fname
8205      NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8206"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8207     endfor
8208
8209     " perform ftp:
8210     " -i       : turns off interactive prompting from ftp
8211     " -n  unix : DON'T use <.netrc>, even though it exists
8212     " -n  win32: quit being obnoxious about password
8213     NetrwKeepj norm! 1Gdd
8214     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8215     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8216     sil NetrwKeepj g/Local directory now/d
8217     call histdel("/",-1)
8218     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8219      let debugkeep= &debug
8220      setl debug=msg
8221      call netrw#ErrorMsg(s:ERROR,getline(1),15)
8222      let &debug = debugkeep
8223      let mod    = 1
8224     else
8225      bw!|q
8226     endif
8227    elseif !exists("b:netrw_method") || b:netrw_method < 0
8228"     call Dfunc("netrw#NetrwUpload : unsupported method")
8229     return
8230    endif
8231   else
8232    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
8233   endif
8234  endif
8235
8236"  call Dret("s:NetrwUpload")
8237endfun
8238
8239" ---------------------------------------------------------------------
8240" s:NetrwPreview: {{{2
8241fun! s:NetrwPreview(path) range
8242"  call Dfunc("NetrwPreview(path<".a:path.">)")
8243  let ykeep= @@
8244  NetrwKeepj call s:NetrwOptionSave("s:")
8245  NetrwKeepj call s:NetrwSafeOptions()
8246  if has("quickfix")
8247   if !isdirectory(s:NetrwFile(a:path))
8248    if g:netrw_preview && !g:netrw_alto
8249     let pvhkeep = &pvh
8250     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8251     let &pvh    = winwidth(0) - winsz
8252    endif
8253    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8254    if exists("pvhkeep")
8255     let &pvh= pvhkeep
8256    endif
8257   elseif !exists("g:netrw_quiet")
8258    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
8259   endif
8260  elseif !exists("g:netrw_quiet")
8261   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
8262  endif
8263  NetrwKeepj call s:NetrwOptionRestore("s:")
8264  let @@= ykeep
8265"  call Dret("NetrwPreview")
8266endfun
8267
8268" ---------------------------------------------------------------------
8269" s:NetrwRefresh: {{{2
8270fun! s:NetrwRefresh(islocal,dirname)
8271"  call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction)
8272  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
8273  setl ma noro
8274"  call Decho("setl ma noro",'~'.expand("<slnum>"))
8275"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8276  let ykeep      = @@
8277
8278  " save the cursor position before refresh.
8279  let screenposn = netrw#SavePosn()
8280
8281"  call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8282"  call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
8283  sil! NetrwKeepj %d _
8284  if a:islocal
8285   NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
8286  else
8287   NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
8288  endif
8289
8290  " restore position
8291  NetrwKeepj call netrw#RestorePosn(screenposn)
8292
8293  " restore file marks
8294  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8295"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8296   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8297  else
8298"   call Decho("2match none  (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8299   2match none
8300  endif
8301
8302"  restore
8303  let @@= ykeep
8304"  call Dret("s:NetrwRefresh")
8305endfun
8306
8307" ---------------------------------------------------------------------
8308" s:NetrwRefreshDir: refreshes a directory by name {{{2
8309"                    Called by NetrwMarkFileCopy()
8310"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
8311fun! s:NetrwRefreshDir(islocal,dirname)
8312"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) g:netrw_fastbrowse=".g:netrw_fastbrowse)
8313  if g:netrw_fastbrowse == 0
8314   " slowest mode (keep buffers refreshed, local or remote)
8315"   call Decho("slowest mode: keep buffers refreshed, local or remote",'~'.expand("<slnum>"))
8316   let tgtwin= bufwinnr(a:dirname)
8317"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin,'~'.expand("<slnum>"))
8318
8319   if tgtwin > 0
8320    " tgtwin is being displayed, so refresh it
8321    let curwin= winnr()
8322"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")",'~'.expand("<slnum>"))
8323    exe tgtwin."wincmd w"
8324    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8325    exe curwin."wincmd w"
8326
8327   elseif bufnr(a:dirname) > 0
8328    let bn= bufnr(a:dirname)
8329"    call Decho("bd bufnr(".a:dirname.")=".bn,'~'.expand("<slnum>"))
8330    exe "sil keepj bd ".bn
8331   endif
8332
8333  elseif g:netrw_fastbrowse <= 1
8334"   call Decho("medium-speed mode: refresh local buffers only",'~'.expand("<slnum>"))
8335   NetrwKeepj call s:LocalBrowseRefresh()
8336  endif
8337"  call Dret("s:NetrwRefreshDir")
8338endfun
8339
8340" ---------------------------------------------------------------------
8341" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8342" window number to do its editing in.
8343" Supports   [count]C  where the count, if present, is used to specify
8344" a window to use for editing via the <cr> mapping.
8345fun! s:NetrwSetChgwin(...)
8346"  call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
8347  if a:0 > 0
8348"   call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8349   if a:1 == ""    " :NetrwC win#
8350    let g:netrw_chgwin= winnr()
8351   else              " :NetrwC
8352    let g:netrw_chgwin= a:1
8353   endif
8354  elseif v:count > 0 " [count]C
8355   let g:netrw_chgwin= v:count
8356  else               " C
8357   let g:netrw_chgwin= winnr()
8358  endif
8359  echo "editing window now set to window#".g:netrw_chgwin
8360"  call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
8361endfun
8362
8363" ---------------------------------------------------------------------
8364" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8365"          What this function does is to compute a priority for the patterns
8366"          in the g:netrw_sort_sequence.  It applies a substitute to any
8367"          "files" that satisfy each pattern, putting the priority / in
8368"          front.  An "*" pattern handles the default priority.
8369fun! s:NetrwSetSort()
8370"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
8371  let ykeep= @@
8372  if w:netrw_liststyle == s:LONGLIST
8373   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
8374  else
8375   let seqlist  = g:netrw_sort_sequence
8376  endif
8377  " sanity check -- insure that * appears somewhere
8378  if seqlist == ""
8379   let seqlist= '*'
8380  elseif seqlist !~ '\*'
8381   let seqlist= seqlist.',*'
8382  endif
8383  let priority = 1
8384  while seqlist != ""
8385   if seqlist =~ ','
8386    let seq     = substitute(seqlist,',.*$','','e')
8387    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
8388   else
8389    let seq     = seqlist
8390    let seqlist = ""
8391   endif
8392   if priority < 10
8393    let spriority= "00".priority.g:netrw_sepchr
8394   elseif priority < 100
8395    let spriority= "0".priority.g:netrw_sepchr
8396   else
8397    let spriority= priority.g:netrw_sepchr
8398   endif
8399"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
8400
8401   " sanity check
8402   if w:netrw_bannercnt > line("$")
8403    " apparently no files were left after a Hiding pattern was used
8404"    call Dret("SetSort : no files left after hiding")
8405    return
8406   endif
8407   if seq == '*'
8408    let starpriority= spriority
8409   else
8410    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
8411    call histdel("/",-1)
8412    " sometimes multiple sorting patterns will match the same file or directory.
8413    " The following substitute is intended to remove the excess matches.
8414    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
8415    NetrwKeepj call histdel("/",-1)
8416   endif
8417   let priority = priority + 1
8418  endwhile
8419  if exists("starpriority")
8420   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
8421   NetrwKeepj call histdel("/",-1)
8422  endif
8423
8424  " Following line associated with priority -- items that satisfy a priority
8425  " pattern get prefixed by ###/ which permits easy sorting by priority.
8426  " Sometimes files can satisfy multiple priority patterns -- only the latest
8427  " priority pattern needs to be retained.  So, at this point, these excess
8428  " priority prefixes need to be removed, but not directories that happen to
8429  " be just digits themselves.
8430  exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
8431  NetrwKeepj call histdel("/",-1)
8432  let @@= ykeep
8433
8434"  call Dret("SetSort")
8435endfun
8436
8437" ---------------------------------------------------------------------
8438" s:NetrwSetTgt: sets the target to the specified choice index {{{2
8439"    Implements [count]Tb  (bookhist<b>)
8440"               [count]Th  (bookhist<h>)
8441"               See :help netrw-qb for how to make the choice.
8442fun! s:NetrwSetTgt(bookhist,choice)
8443"  call Dfunc("s:NetrwSetTgt(bookhist<".a:bookhist."> choice#".a:choice.")")
8444
8445  if     a:bookhist == 'b'
8446   " supports choosing a bookmark as a target using a qb-generated list
8447   let choice= a:choice - 1
8448   if exists("g:netrw_bookmarklist[".choice."]")
8449    call netrw#MakeTgt(g:netrw_bookmarklist[choice])
8450   else
8451    echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
8452   endif
8453
8454  elseif a:bookhist == 'h'
8455   " supports choosing a history stack entry as a target using a qb-generated list
8456   let choice= (a:choice % g:netrw_dirhistmax) + 1
8457   if exists("g:netrw_dirhist_".choice)
8458    let histentry = g:netrw_dirhist_{choice}
8459    call netrw#MakeTgt(histentry)
8460   else
8461    echomsg "Sorry, history#".a:choice." not available!"
8462   endif
8463  endif
8464
8465"  call Dret("s:NetrwSetTgt")
8466endfun
8467
8468" =====================================================================
8469" s:NetrwSortStyle: change sorting style (name - time - size) and refresh display {{{2
8470fun! s:NetrwSortStyle(islocal)
8471"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
8472  NetrwKeepj call s:NetrwSaveWordPosn()
8473  let svpos= netrw#SavePosn()
8474
8475  let g:netrw_sort_by= (g:netrw_sort_by =~ '^n')? 'time' : (g:netrw_sort_by =~ '^t')? 'size' : (g:netrw_sort_by =~ '^siz')? 'exten' : 'name'
8476  NetrwKeepj norm! 0
8477  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8478  NetrwKeepj call netrw#RestorePosn(svpos)
8479
8480"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
8481endfun
8482
8483" ---------------------------------------------------------------------
8484" s:NetrwSplit: mode {{{2
8485"           =0 : net   and o
8486"           =1 : net   and t
8487"           =2 : net   and v
8488"           =3 : local and o
8489"           =4 : local and t
8490"           =5 : local and v
8491fun! s:NetrwSplit(mode)
8492"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
8493
8494  let ykeep= @@
8495  call s:SaveWinVars()
8496
8497  if a:mode == 0
8498   " remote and o
8499   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8500   if winsz == 0|let winsz= ""|endif
8501"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8502   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8503   let s:didsplit= 1
8504   NetrwKeepj call s:RestoreWinVars()
8505   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
8506   unlet s:didsplit
8507
8508  elseif a:mode == 1
8509   " remote and t
8510   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
8511"   call Decho("tabnew",'~'.expand("<slnum>"))
8512   tabnew
8513   let s:didsplit= 1
8514   NetrwKeepj call s:RestoreWinVars()
8515   NetrwKeepj call s:NetrwBrowse(0,newdir)
8516   unlet s:didsplit
8517
8518  elseif a:mode == 2
8519   " remote and v
8520   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8521   if winsz == 0|let winsz= ""|endif
8522"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
8523   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8524   let s:didsplit= 1
8525   NetrwKeepj call s:RestoreWinVars()
8526   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
8527   unlet s:didsplit
8528
8529  elseif a:mode == 3
8530   " local and o
8531   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8532   if winsz == 0|let winsz= ""|endif
8533"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8534   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8535   let s:didsplit= 1
8536   NetrwKeepj call s:RestoreWinVars()
8537   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8538   unlet s:didsplit
8539
8540  elseif a:mode == 4
8541   " local and t
8542   let cursorword  = s:NetrwGetWord()
8543   let eikeep      = &ei
8544   let netrw_winnr = winnr()
8545   let netrw_line  = line(".")
8546   let netrw_col   = virtcol(".")
8547   NetrwKeepj norm! H0
8548   let netrw_hline = line(".")
8549   setl ei=all
8550   exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8551   exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8552   let &ei          = eikeep
8553   let netrw_curdir = s:NetrwTreeDir(0)
8554"   call Decho("tabnew",'~'.expand("<slnum>"))
8555   tabnew
8556   let b:netrw_curdir = netrw_curdir
8557   let s:didsplit     = 1
8558   NetrwKeepj call s:RestoreWinVars()
8559   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
8560   if &ft == "netrw"
8561    setl ei=all
8562    exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8563    exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8564    let &ei= eikeep
8565   endif
8566   unlet s:didsplit
8567
8568  elseif a:mode == 5
8569   " local and v
8570   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8571   if winsz == 0|let winsz= ""|endif
8572"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
8573   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8574   let s:didsplit= 1
8575   NetrwKeepj call s:RestoreWinVars()
8576   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8577   "call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8578   unlet s:didsplit
8579
8580  else
8581   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
8582  endif
8583
8584  let @@= ykeep
8585"  call Dret("s:NetrwSplit")
8586endfun
8587
8588" ---------------------------------------------------------------------
8589" s:NetrwTgtMenu: {{{2
8590fun! s:NetrwTgtMenu()
8591  if !exists("s:netrw_menucnt")
8592   return
8593  endif
8594"  call Dfunc("s:NetrwTgtMenu()")
8595
8596  " the following test assures that gvim is running, has menus available, and has menus enabled.
8597  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8598   if exists("g:NetrwTopLvlMenu")
8599"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
8600    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
8601   endif
8602   if !exists("s:netrw_initbookhist")
8603    call s:NetrwBookHistRead()
8604   endif
8605
8606   " try to cull duplicate entries
8607   let tgtdict={}
8608
8609   " target bookmarked places
8610   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
8611"    call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
8612    let cnt= 1
8613    for bmd in g:netrw_bookmarklist
8614     if has_key(tgtdict,bmd)
8615      let cnt= cnt + 1
8616      continue
8617     endif
8618     let tgtdict[bmd]= cnt
8619     let ebmd= escape(bmd,g:netrw_menu_escape)
8620     " show bookmarks for goto menu
8621"     call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
8622     exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd."	:call netrw#MakeTgt('".bmd."')\<cr>"
8623     let cnt= cnt + 1
8624    endfor
8625   endif
8626
8627   " target directory browsing history
8628   if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
8629"    call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
8630    let histcnt = 1
8631    while histcnt <= g:netrw_dirhistmax
8632     let priority = g:netrw_dirhist_cnt + histcnt
8633     if exists("g:netrw_dirhist_{histcnt}")
8634      let histentry  = g:netrw_dirhist_{histcnt}
8635      if has_key(tgtdict,histentry)
8636       let histcnt = histcnt + 1
8637       continue
8638      endif
8639      let tgtdict[histentry] = histcnt
8640      let ehistentry         = escape(histentry,g:netrw_menu_escape)
8641"      call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
8642      exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry."	:call netrw#MakeTgt('".histentry."')\<cr>"
8643     endif
8644     let histcnt = histcnt + 1
8645    endwhile
8646   endif
8647  endif
8648"  call Dret("s:NetrwTgtMenu")
8649endfun
8650
8651" ---------------------------------------------------------------------
8652" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
8653" (full path directory with trailing slash returned)
8654fun! s:NetrwTreeDir(islocal)
8655"  call Dfunc("s:NetrwTreeDir(islocal=".a:islocal.") getline(".line(".").")"."<".getline('.')."> b:netrw_curdir<".b:netrw_curdir."> tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft)
8656
8657  if exists("s:treedir")
8658   " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
8659   let treedir= s:treedir
8660   unlet s:treedir
8661"   call Dret("s:NetrwTreeDir ".treedir)
8662   return treedir
8663  endif
8664
8665  if !exists("b:netrw_curdir") || b:netrw_curdir == ""
8666   let b:netrw_curdir= getcwd()
8667  endif
8668
8669  let treedir = b:netrw_curdir
8670"  call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>"))
8671  let s:treecurpos= netrw#SavePosn()
8672
8673  if w:netrw_liststyle == s:TREELIST
8674"   call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>"))
8675"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
8676
8677   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
8678   let curline= substitute(getline('.'),"\t -->.*$",'','')
8679   if curline =~ '/$'
8680"    call Decho("extract tree subdirectory from current line",'~'.expand("<slnum>"))
8681    let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
8682"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8683   elseif curline =~ '@$'
8684"    call Decho("handle symbolic link from current line",'~'.expand("<slnum>"))
8685    let treedir= resolve(substitute(substitute(getline('.'),'@.*$','','e'),'^|*\s*','','e'))
8686"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8687   else
8688"    call Decho("do not extract tree subdirectory from current line and set treedir to empty",'~'.expand("<slnum>"))
8689    let treedir= ""
8690   endif
8691
8692   " detect user attempting to close treeroot
8693"   call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>"))
8694"   call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
8695"   call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~ '^'.s:treedepthstring)? '=~' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>"))
8696   if curline !~ '^'.s:treedepthstring && getline('.') != '..'
8697"    call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>"))
8698    " now force a refresh
8699"    call Decho(".force refresh: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8700    sil! NetrwKeepj %d _
8701"    call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
8702    return b:netrw_curdir
8703"   else " Decho
8704"    call Decho(".user did not attempt to close treeroot",'~'.expand("<slnum>"))
8705   endif
8706
8707"   call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>"))
8708"   call Decho("after subst<".substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)$','\1','').">",'~'.expand("<slnum>"))
8709   let potentialdir= substitute(curline,'^'.s:treedepthstring.'* \(.*\)@$','\1','')
8710"   call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(s:NetrwFile(potentialdir)),'~'.expand("<slnum>"))
8711
8712   " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
8713"   if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
8714"    let newdir          = w:netrw_treetop.'/'.potentialdir
8715" "   call Decho("apply NetrwTreePath to newdir<".newdir.">",'~'.expand("<slnum>"))
8716"    let treedir         = s:NetrwTreePath(newdir)
8717"    let w:netrw_treetop = newdir
8718" "   call Decho("newdir <".newdir.">",'~'.expand("<slnum>"))
8719"   else
8720"    call Decho("apply NetrwTreePath to treetop<".w:netrw_treetop.">",'~'.expand("<slnum>"))
8721    let treedir = s:NetrwTreePath(w:netrw_treetop)
8722"   endif
8723  endif
8724
8725  " sanity maintenance: keep those //s away...
8726  let treedir= substitute(treedir,'//$','/','')
8727"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8728
8729"  call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
8730  return treedir
8731endfun
8732
8733" ---------------------------------------------------------------------
8734" s:NetrwTreeDisplay: recursive tree display {{{2
8735fun! s:NetrwTreeDisplay(dir,depth)
8736"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
8737
8738  " insure that there are no folds
8739  setl nofen
8740
8741  " install ../ and shortdir
8742  if a:depth == ""
8743   call setline(line("$")+1,'../')
8744"   call Decho("setline#".line("$")." ../ (depth is zero)",'~'.expand("<slnum>"))
8745  endif
8746  if a:dir =~ '^\a\{3,}://'
8747   if a:dir == w:netrw_treetop
8748    let shortdir= a:dir
8749   else
8750    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
8751   endif
8752   call setline(line("$")+1,a:depth.shortdir)
8753  else
8754   let shortdir= substitute(a:dir,'^.*/','','e')
8755   call setline(line("$")+1,a:depth.shortdir.'/')
8756  endif
8757"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">",'~'.expand("<slnum>"))
8758
8759  " append a / to dir if its missing one
8760  let dir= a:dir
8761
8762  " display subtrees (if any)
8763  let depth= s:treedepthstring.a:depth
8764"  call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>"))
8765
8766"  call Decho("w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>"))
8767  for entry in w:netrw_treedict[dir]
8768   let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
8769"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
8770   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
8771"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
8772    NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
8773   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
8774"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
8775    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
8776   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
8777"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
8778    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
8779   else
8780"    call Decho("<".entry."> is not a key in treedict (no subtree)",'~'.expand("<slnum>"))
8781    sil! NetrwKeepj call setline(line("$")+1,depth.entry)
8782   endif
8783  endfor
8784
8785"  call Dret("NetrwTreeDisplay")
8786endfun
8787
8788" ---------------------------------------------------------------------
8789" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
8790"                     Called by s:PerformListing()
8791fun! s:NetrwTreeListing(dirname)
8792  if w:netrw_liststyle == s:TREELIST
8793"   call Dfunc("NetrwTreeListing() bufname<".expand("%").">")
8794"   call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
8795"   call Decho("win#".winnr().": w:netrw_treetop ".(exists("w:netrw_treetop")? "exists" : "doesn't exist")." w:netrw_treedict ".(exists("w:netrw_treedict")? "exists" : "doesn't exit"),'~'.expand("<slnum>"))
8796"   call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
8797
8798   " update the treetop
8799"   call Decho("update the treetop",'~'.expand("<slnum>"))
8800   if !exists("w:netrw_treetop")
8801    let w:netrw_treetop= a:dirname
8802"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>"))
8803   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
8804    let w:netrw_treetop= a:dirname
8805"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
8806   endif
8807
8808   if !exists("w:netrw_treedict")
8809    " insure that we have a treedict, albeit empty
8810"    call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
8811    let w:netrw_treedict= {}
8812   endif
8813
8814   " update the directory listing for the current directory
8815"   call Decho("updating dictionary with ".a:dirname.":[..directory listing..]",'~'.expand("<slnum>"))
8816"   call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
8817   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d'
8818   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
8819"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
8820   exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d"
8821
8822   " if past banner, record word
8823   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
8824    let fname= expand("<cword>")
8825   else
8826    let fname= ""
8827   endif
8828"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
8829"   call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
8830
8831   " display from treetop on down
8832   NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
8833"   call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
8834
8835   " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
8836   while getline(1) =~ '^\s*$' && byte2line(1) > 0
8837"    call Decho("deleting blank line",'~'.expand("<slnum>"))
8838    1d
8839   endwhile
8840
8841   exe "setl ".g:netrw_bufsettings
8842
8843"   call Dret("NetrwTreeListing : bufname<".expand("%").">")
8844   return
8845  endif
8846endfun
8847
8848" ---------------------------------------------------------------------
8849" s:NetrwTreePath: returns path to current file in tree listing {{{2
8850"                  Normally, treetop is w:netrw_treetop, but a
8851"                  user of the function ( netrw#SetTreetop() )
8852"                  wipes that out prior to calling this function
8853fun! s:NetrwTreePath(treetop)
8854"  call Dfunc("s:NetrwTreePath() line#".line(".")."<".getline(".").">")
8855  let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
8856"  call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
8857  let depth = substitute(depth,'^'.s:treedepthstring,'','')
8858"  call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
8859  let curline= getline('.')
8860"  call Decho("curline<".curline.'>','~'.expand("<slnum>"))
8861  if curline =~ '/$'
8862"   call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
8863   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
8864"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8865  elseif curline =~ '@\s\+-->'
8866"   call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
8867   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
8868   let treedir= substitute(treedir,'@\s\+-->.*$','','e')
8869"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8870  else
8871"   call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
8872   let treedir= ""
8873  endif
8874  " construct treedir by searching backwards at correct depth
8875"  call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
8876"  call Decho("initial      treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
8877  while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
8878   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
8879   let treedir= dirname.treedir
8880   let depth  = substitute(depth,'^'.s:treedepthstring,'','')
8881"   call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
8882  endwhile
8883  if a:treetop =~ '/$'
8884   let treedir= a:treetop.treedir
8885  else
8886   let treedir= a:treetop.'/'.treedir
8887  endif
8888  let treedir= substitute(treedir,'//$','/','')
8889"  call Dret("s:NetrwTreePath <".treedir.">")
8890  return treedir
8891endfun
8892
8893" ---------------------------------------------------------------------
8894" s:NetrwWideListing: {{{2
8895fun! s:NetrwWideListing()
8896
8897  if w:netrw_liststyle == s:WIDELIST
8898"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
8899   " look for longest filename (cpf=characters per filename)
8900   " cpf: characters per filename
8901   " fpl: filenames per line
8902   " fpc: filenames per column
8903   setl ma noro
8904"   call Decho("setl ma noro",'~'.expand("<slnum>"))
8905   let b:netrw_cpf= 0
8906   if line("$") >= w:netrw_bannercnt
8907    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
8908    NetrwKeepj call histdel("/",-1)
8909   else
8910"    call Dret("NetrwWideListing")
8911    return
8912   endif
8913   let b:netrw_cpf= b:netrw_cpf + 2
8914"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
8915
8916   " determine qty files per line (fpl)
8917   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
8918   if w:netrw_fpl <= 0
8919    let w:netrw_fpl= 1
8920   endif
8921"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
8922
8923   " make wide display
8924   "   fpc: files per column of wide listing
8925   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
8926   NetrwKeepj call histdel("/",-1)
8927   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
8928   let newcolstart = w:netrw_bannercnt + fpc
8929   let newcolend   = newcolstart + fpc - 1
8930"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
8931   if has("clipboard")
8932    sil! let keepregstar = @*
8933   endif
8934   while line("$") >= newcolstart
8935    if newcolend > line("$") | let newcolend= line("$") | endif
8936    let newcolqty= newcolend - newcolstart
8937    exe newcolstart
8938    if newcolqty == 0
8939     exe "sil! NetrwKeepj norm! 0\<c-v>$hx".w:netrw_bannercnt."G$p"
8940    else
8941     exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$hx'.w:netrw_bannercnt.'G$p'
8942    endif
8943    exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d'
8944    exe 'sil! NetrwKeepj '.w:netrw_bannercnt
8945   endwhile
8946   if has("clipboard")
8947    sil! let @*= keepregstar
8948   endif
8949   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
8950   NetrwKeepj call histdel("/",-1)
8951   exe 'nno <buffer> <silent> w	:call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
8952   exe 'nno <buffer> <silent> b	:call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
8953"   call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
8954   exe "setl ".g:netrw_bufsettings
8955"   call Decho("(NetrwWideListing) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
8956"   call Dret("NetrwWideListing")
8957   return
8958  else
8959   if hasmapto("w","n")
8960    sil! nunmap <buffer> w
8961   endif
8962   if hasmapto("b","n")
8963    sil! nunmap <buffer> b
8964   endif
8965  endif
8966
8967endfun
8968
8969" ---------------------------------------------------------------------
8970" s:PerformListing: {{{2
8971fun! s:PerformListing(islocal)
8972"  call Dfunc("s:PerformListing(islocal=".a:islocal.")")
8973"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
8974"  call Decho("settings: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (enter)",'~'.expand("<slnum>"))
8975
8976  " set up syntax highlighting {{{3
8977"  call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
8978  sil! setl ft=netrw
8979
8980  NetrwKeepj call s:NetrwSafeOptions()
8981  setl noro ma
8982"  call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
8983
8984"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
8985"   call Decho("(netrw) Processing your browsing request...",'~'.expand("<slnum>"))
8986"  endif								" Decho
8987
8988"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
8989  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
8990   " force a refresh for tree listings
8991"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8992   sil! NetrwKeepj %d _
8993  endif
8994
8995  " save current directory on directory history list
8996  NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
8997
8998  " Set up the banner {{{3
8999  if g:netrw_banner
9000"   call Decho("--set up banner",'~'.expand("<slnum>"))
9001   NetrwKeepj call setline(1,'" ============================================================================')
9002   if exists("g:netrw_pchk")
9003    " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9004    " failure detections.
9005    NetrwKeepj call setline(2,'" Netrw Directory Listing')
9006   else
9007    NetrwKeepj call setline(2,'" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')')
9008   endif
9009   if exists("g:netrw_pchk")
9010    let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9011   else
9012    let curdir= b:netrw_curdir
9013   endif
9014   if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9015    NetrwKeepj call setline(3,'"   '.substitute(curdir,'/','\\','g'))
9016   else
9017    NetrwKeepj call setline(3,'"   '.curdir)
9018   endif
9019   let w:netrw_bannercnt= 3
9020   NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
9021  else
9022"   call Decho("--no banner",'~'.expand("<slnum>"))
9023   NetrwKeepj 1
9024   let w:netrw_bannercnt= 1
9025  endif
9026"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9027"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9028
9029  let sortby= g:netrw_sort_by
9030  if g:netrw_sort_direction =~ "^r"
9031   let sortby= sortby." reversed"
9032  endif
9033
9034  " Sorted by... {{{3
9035  if g:netrw_banner
9036"   call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9037   if g:netrw_sort_by =~ "^n"
9038"   call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9039    " sorted by name
9040    NetrwKeepj put ='\"   Sorted by      '.sortby
9041    NetrwKeepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
9042    let w:netrw_bannercnt= w:netrw_bannercnt + 2
9043   else
9044"   call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9045    " sorted by size or date
9046    NetrwKeepj put ='\"   Sorted by '.sortby
9047    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9048   endif
9049   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9050"  else " Decho
9051"   call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9052  endif
9053
9054  " show copy/move target, if any
9055  if g:netrw_banner
9056   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9057"    call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9058    NetrwKeepj put =''
9059    if s:netrwmftgt_islocal
9060     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9061    else
9062     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9063    endif
9064    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9065   else
9066"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
9067   endif
9068   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9069  endif
9070
9071  " Hiding...  -or-  Showing... {{{3
9072  if g:netrw_banner
9073"   call Decho("--handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9074   if g:netrw_list_hide != "" && g:netrw_hide
9075    if g:netrw_hide == 1
9076     NetrwKeepj put ='\"   Hiding:        '.g:netrw_list_hide
9077    else
9078     NetrwKeepj put ='\"   Showing:       '.g:netrw_list_hide
9079    endif
9080    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9081   endif
9082   exe "NetrwKeepj ".w:netrw_bannercnt
9083
9084"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9085   let quickhelp   = g:netrw_quickhelp%len(s:QuickHelp)
9086"   call Decho("quickhelp   =".quickhelp,'~'.expand("<slnum>"))
9087   NetrwKeepj put ='\"   Quick Help: <F1>:help  '.s:QuickHelp[quickhelp]
9088"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9089   NetrwKeepj put ='\" =============================================================================='
9090   let w:netrw_bannercnt= w:netrw_bannercnt + 2
9091"  else " Decho
9092"   call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9093  endif
9094
9095  " bannercnt should index the line just after the banner
9096  if g:netrw_banner
9097   let w:netrw_bannercnt= w:netrw_bannercnt + 1
9098   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9099"   call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9100"  else " Decho
9101"   call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9102  endif
9103
9104  " get list of files
9105"  call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
9106  if a:islocal
9107   NetrwKeepj call s:LocalListing()
9108  else " remote
9109   NetrwKeepj let badresult= s:NetrwRemoteListing()
9110   if badresult
9111"    call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9112"    call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9113    return
9114   endif
9115  endif
9116
9117  " manipulate the directory listing (hide, sort) {{{3
9118  if !exists("w:netrw_bannercnt")
9119   let w:netrw_bannercnt= 0
9120  endif
9121"  call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9122"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9123"  call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9124
9125  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9126"   call Decho("manipulate directory listing (hide)",'~'.expand("<slnum>"))
9127"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9128   if g:netrw_hide && g:netrw_list_hide != ""
9129    NetrwKeepj call s:NetrwListHide()
9130   endif
9131   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9132"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9133
9134    if g:netrw_sort_by =~ "^n"
9135     " sort by name
9136     NetrwKeepj call s:NetrwSetSort()
9137
9138     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9139"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9140      if g:netrw_sort_direction =~ 'n'
9141       " normal direction sorting
9142       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9143      else
9144       " reverse direction sorting
9145       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9146      endif
9147     endif
9148     " remove priority pattern prefix
9149"     call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9150     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9151     NetrwKeepj call histdel("/",-1)
9152
9153    elseif g:netrw_sort_by =~ "^ext"
9154     " sort by extension
9155     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9156     NetrwKeepj call histdel("/",-1)
9157     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9158     NetrwKeepj call histdel("/",-1)
9159     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9160     NetrwKeepj call histdel("/",-1)
9161     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9162"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9163      if g:netrw_sort_direction =~ 'n'
9164       " normal direction sorting
9165       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9166      else
9167       " reverse direction sorting
9168       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9169      endif
9170     endif
9171     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9172     NetrwKeepj call histdel("/",-1)
9173
9174    elseif a:islocal
9175     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9176"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9177      if g:netrw_sort_direction =~ 'n'
9178"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9179       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9180      else
9181"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9182       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9183      endif
9184     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9185     NetrwKeepj call histdel("/",-1)
9186     endif
9187    endif
9188
9189   elseif g:netrw_sort_direction =~ 'r'
9190"    call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9191    if !g:netrw_banner || w:netrw_bannercnt < line('$')
9192     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9193     call histdel("/",-1)
9194    endif
9195   endif
9196  endif
9197"  call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9198
9199  " convert to wide/tree listing {{{3
9200"  call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9201"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#1)",'~'.expand("<slnum>"))
9202  NetrwKeepj call s:NetrwWideListing()
9203"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#2)",'~'.expand("<slnum>"))
9204  NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
9205"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#3)",'~'.expand("<slnum>"))
9206
9207  " resolve symbolic links if local and (thin or tree)
9208  if a:islocal && (w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:TREELIST)
9209"   call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9210   g/@$/call s:ShowLink()
9211  endif
9212
9213  if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
9214   " place cursor on the top-left corner of the file listing
9215"   call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9216   exe 'sil! '.w:netrw_bannercnt
9217   sil! NetrwKeepj norm! 0
9218"   call Decho("  tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9219  else
9220"   call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9221"   call Decho("  w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9222"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
9223"   call Decho("  g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
9224  endif
9225
9226  " record previous current directory
9227  let w:netrw_prvdir= b:netrw_curdir
9228"  call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
9229
9230  " save certain window-oriented variables into buffer-oriented variables {{{3
9231"  call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9232"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#4)",'~'.expand("<slnum>"))
9233  NetrwKeepj call s:SetBufWinVars()
9234"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#5)",'~'.expand("<slnum>"))
9235  NetrwKeepj call s:NetrwOptionRestore("w:")
9236"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#6)",'~'.expand("<slnum>"))
9237
9238  " set display to netrw display settings
9239"  call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
9240  exe "setl ".g:netrw_bufsettings
9241"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#7)",'~'.expand("<slnum>"))
9242  if g:netrw_liststyle == s:LONGLIST
9243"   call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9244   exe "setl ts=".(g:netrw_maxfilenamelen+1)
9245  endif
9246
9247  if exists("s:treecurpos")
9248"   call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
9249"   call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#8)",'~'.expand("<slnum>"))
9250   NetrwKeepj call netrw#RestorePosn(s:treecurpos)
9251   unlet s:treecurpos
9252  endif
9253
9254"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (return)",'~'.expand("<slnum>"))
9255"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9256"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
9257endfun
9258
9259" ---------------------------------------------------------------------
9260" s:SetupNetrwStatusLine: {{{2
9261fun! s:SetupNetrwStatusLine(statline)
9262"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
9263
9264  if !exists("s:netrw_setup_statline")
9265   let s:netrw_setup_statline= 1
9266"   call Decho("do first-time status line setup",'~'.expand("<slnum>"))
9267
9268   if !exists("s:netrw_users_stl")
9269    let s:netrw_users_stl= &stl
9270   endif
9271   if !exists("s:netrw_users_ls")
9272    let s:netrw_users_ls= &laststatus
9273   endif
9274
9275   " set up User9 highlighting as needed
9276   let keepa= @a
9277   redir @a
9278   try
9279    hi User9
9280   catch /^Vim\%((\a\{3,})\)\=:E411/
9281    if &bg == "dark"
9282     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
9283    else
9284     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
9285    endif
9286   endtry
9287   redir END
9288   let @a= keepa
9289  endif
9290
9291  " set up status line (may use User9 highlighting)
9292  " insure that windows have a statusline
9293  " make sure statusline is displayed
9294  let &stl=a:statline
9295  setl laststatus=2
9296"  call Decho("stl=".&stl,'~'.expand("<slnum>"))
9297  redraw
9298
9299"  call Dret("SetupNetrwStatusLine : stl=".&stl)
9300endfun
9301
9302" ---------------------------------------------------------------------
9303"  Remote Directory Browsing Support:    {{{1
9304" ===========================================
9305
9306" ---------------------------------------------------------------------
9307" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
9308"  This function assumes that a long listing will be received.  Size, time,
9309"  and reverse sorts will be requested of the server but not otherwise
9310"  enforced here.
9311fun! s:NetrwRemoteFtpCmd(path,listcmd)
9312"  call Dfunc("NetrwRemoteFtpCmd(path<".a:path."> listcmd<".a:listcmd.">) w:netrw_method=".(exists("w:netrw_method")? w:netrw_method : (exists("b:netrw_method")? b:netrw_method : "???")))
9313"  call Decho("line($)=".line("$")." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9314  " sanity check: {{{3
9315  if !exists("w:netrw_method")
9316   if exists("b:netrw_method")
9317    let w:netrw_method= b:netrw_method
9318   else
9319    call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
9320"    call Dret("NetrwRemoteFtpCmd")
9321    return
9322   endif
9323  endif
9324
9325  " WinXX ftp uses unix style input, so set ff to unix	" {{{3
9326  let ffkeep= &ff
9327  setl ma ff=unix noro
9328"  call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
9329
9330  " clear off any older non-banner lines	" {{{3
9331  " note that w:netrw_bannercnt indexes the line after the banner
9332"  call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d  (clear off old non-banner lines)",'~'.expand("<slnum>"))
9333  exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d"
9334
9335  ".........................................
9336  if w:netrw_method == 2 || w:netrw_method == 5	" {{{3
9337   " ftp + <.netrc>:  Method #2
9338   if a:path != ""
9339    NetrwKeepj put ='cd \"'.a:path.'\"'
9340   endif
9341   if exists("g:netrw_ftpextracmd")
9342    NetrwKeepj put =g:netrw_ftpextracmd
9343"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9344   endif
9345   NetrwKeepj call setline(line("$")+1,a:listcmd)
9346"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9347   if exists("g:netrw_port") && g:netrw_port != ""
9348"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1),'~'.expand("<slnum>"))
9349    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1)
9350   else
9351"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
9352    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
9353   endif
9354
9355  ".........................................
9356  elseif w:netrw_method == 3	" {{{3
9357   " ftp + machine,id,passwd,filename:  Method #3
9358    setl ff=unix
9359    if exists("g:netrw_port") && g:netrw_port != ""
9360     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
9361    else
9362     NetrwKeepj put ='open '.g:netrw_machine
9363    endif
9364
9365    " handle userid and password
9366    let host= substitute(g:netrw_machine,'\..*$','','')
9367"    call Decho("host<".host.">",'~'.expand("<slnum>"))
9368    if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
9369     call NetUserPass("ftp:".host)
9370    endif
9371    if exists("g:netrw_uid") && g:netrw_uid != ""
9372     if exists("g:netrw_ftp") && g:netrw_ftp == 1
9373      NetrwKeepj put =g:netrw_uid
9374      if exists("s:netrw_passwd") && s:netrw_passwd != ""
9375       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
9376      endif
9377     elseif exists("s:netrw_passwd")
9378      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
9379     endif
9380    endif
9381
9382   if a:path != ""
9383    NetrwKeepj put ='cd \"'.a:path.'\"'
9384   endif
9385   if exists("g:netrw_ftpextracmd")
9386    NetrwKeepj put =g:netrw_ftpextracmd
9387"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9388   endif
9389   NetrwKeepj call setline(line("$")+1,a:listcmd)
9390
9391   " perform ftp:
9392   " -i       : turns off interactive prompting from ftp
9393   " -n  unix : DON'T use <.netrc>, even though it exists
9394   " -n  win32: quit being obnoxious about password
9395   if exists("w:netrw_bannercnt")
9396"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9397    call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
9398"   else " Decho
9399"    call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
9400"    g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
9401   endif
9402
9403  ".........................................
9404  elseif w:netrw_method == 9	" {{{3
9405   " sftp username@machine: Method #9
9406   " s:netrw_sftp_cmd
9407   setl ff=unix
9408
9409   " restore settings
9410   let &ff= ffkeep
9411"   call Dret("NetrwRemoteFtpCmd")
9412   return
9413
9414  ".........................................
9415  else	" {{{3
9416   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
9417  endif
9418
9419  " cleanup for Windows " {{{3
9420  if has("win32") || has("win95") || has("win64") || has("win16")
9421   sil! NetrwKeepj %s/\r$//e
9422   NetrwKeepj call histdel("/",-1)
9423  endif
9424  if a:listcmd == "dir"
9425   " infer directory/link based on the file permission string
9426   sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
9427   sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
9428   NetrwKeepj call histdel("/",-1)
9429   NetrwKeepj call histdel("/",-1)
9430   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST
9431    exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
9432    NetrwKeepj call histdel("/",-1)
9433   endif
9434  endif
9435
9436  " ftp's listing doesn't seem to include ./ or ../ " {{{3
9437  if !search('^\.\/$\|\s\.\/$','wn')
9438   exe 'NetrwKeepj '.w:netrw_bannercnt
9439   NetrwKeepj put ='./'
9440  endif
9441  if !search('^\.\.\/$\|\s\.\.\/$','wn')
9442   exe 'NetrwKeepj '.w:netrw_bannercnt
9443   NetrwKeepj put ='../'
9444  endif
9445
9446  " restore settings " {{{3
9447  let &ff= ffkeep
9448"  call Dret("NetrwRemoteFtpCmd")
9449endfun
9450
9451" ---------------------------------------------------------------------
9452" s:NetrwRemoteListing: {{{2
9453fun! s:NetrwRemoteListing()
9454"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">)")
9455
9456  if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
9457   let w:netrw_bannercnt= s:bannercnt
9458  endif
9459  if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
9460   let w:netrw_bannercnt= s:bannercnt
9461  endif
9462
9463  call s:RemotePathAnalysis(b:netrw_curdir)
9464
9465  " sanity check:
9466  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
9467"   call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
9468   if !executable("ftp")
9469"    call Decho("ftp is not executable",'~'.expand("<slnum>"))
9470    if !exists("g:netrw_quiet")
9471     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
9472    endif
9473    call s:NetrwOptionRestore("w:")
9474"    call Dret("s:NetrwRemoteListing -1")
9475    return -1
9476   endif
9477
9478  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
9479"   call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
9480   if !exists("g:netrw_quiet")
9481    if g:netrw_list_cmd == ""
9482     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your g:netrw_list_cmd is empty; perhaps ".g:netrw_ssh_cmd." is not executable on your system",47)
9483    else
9484     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
9485    endif
9486   endif
9487
9488   NetrwKeepj call s:NetrwOptionRestore("w:")
9489"   call Dret("s:NetrwRemoteListing -1")
9490   return -1
9491  endif  " (remote handling sanity check)
9492"  call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
9493
9494  if exists("b:netrw_method")
9495"   call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
9496   let w:netrw_method= b:netrw_method
9497  endif
9498
9499  if s:method == "ftp"
9500   " use ftp to get remote file listing {{{3
9501"   call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
9502   let s:method  = "ftp"
9503   let listcmd = g:netrw_ftp_list_cmd
9504   if g:netrw_sort_by =~ '^t'
9505    let listcmd= g:netrw_ftp_timelist_cmd
9506   elseif g:netrw_sort_by =~ '^s'
9507    let listcmd= g:netrw_ftp_sizelist_cmd
9508   endif
9509"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
9510   call s:NetrwRemoteFtpCmd(s:path,listcmd)
9511"   exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
9512
9513   " report on missing file or directory messages
9514   if search('[Nn]o such file or directory\|Failed to change directory')
9515    let mesg= getline(".")
9516    if exists("w:netrw_bannercnt")
9517     setl ma
9518     exe w:netrw_bannercnt.",$d"
9519     setl noma
9520    endif
9521    NetrwKeepj call s:NetrwOptionRestore("w:")
9522    call netrw#ErrorMsg(s:WARNING,mesg,96)
9523"    call Dret("s:NetrwRemoteListing : -1")
9524    return -1
9525   endif
9526
9527   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST
9528    " shorten the listing
9529"    call Decho("generate short listing",'~'.expand("<slnum>"))
9530    exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
9531
9532    " cleanup
9533    if g:netrw_ftp_browse_reject != ""
9534     exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
9535     NetrwKeepj call histdel("/",-1)
9536    endif
9537    sil! NetrwKeepj %s/\r$//e
9538    NetrwKeepj call histdel("/",-1)
9539
9540    " if there's no ../ listed, then put ../ in
9541    let line1= line(".")
9542    exe "sil! NetrwKeepj ".w:netrw_bannercnt
9543    let line2= search('\.\.\/\%(\s\|$\)','cnW')
9544"    call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2."  w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9545    if line2 == 0
9546"     call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
9547     sil! NetrwKeepj put='../'
9548    endif
9549    exe "sil! NetrwKeepj ".line1
9550    sil! NetrwKeepj norm! 0
9551
9552"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
9553    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9554"     call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
9555     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
9556     NetrwKeepj call histdel("/",-1)
9557    else " normal ftp cleanup
9558"     call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
9559     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
9560     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
9561     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
9562     NetrwKeepj call histdel("/",-1)
9563     NetrwKeepj call histdel("/",-1)
9564     NetrwKeepj call histdel("/",-1)
9565    endif
9566   endif
9567
9568   else
9569   " use ssh to get remote file listing {{{3
9570"   call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
9571   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
9572"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
9573   if g:netrw_scp_cmd =~ '^pscp'
9574"    call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
9575    exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
9576    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
9577    sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
9578    sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
9579    sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
9580    NetrwKeepj call histdel("/",-1)
9581    NetrwKeepj call histdel("/",-1)
9582    NetrwKeepj call histdel("/",-1)
9583    if g:netrw_liststyle != s:LONGLIST
9584     sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
9585     NetrwKeepj call histdel("/",-1)
9586    endif
9587   else
9588    if s:path == ""
9589"     call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
9590     exe "NetrwKeepj keepalt r! ".listcmd
9591    else
9592"     call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
9593     exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
9594"     call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
9595    endif
9596   endif
9597
9598   " cleanup
9599   if g:netrw_ssh_browse_reject != ""
9600"    call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
9601    exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
9602    NetrwKeepj call histdel("/",-1)
9603   endif
9604  endif
9605
9606  if w:netrw_liststyle == s:LONGLIST
9607   " do a long listing; these substitutions need to be done prior to sorting {{{3
9608"   call Decho("fix long listing:",'~'.expand("<slnum>"))
9609
9610   if s:method == "ftp"
9611    " cleanup
9612    exe "sil! NetrwKeepj ".w:netrw_bannercnt
9613    while getline('.') =~ g:netrw_ftp_browse_reject
9614     sil! NetrwKeepj d
9615    endwhile
9616    " if there's no ../ listed, then put ../ in
9617    let line1= line(".")
9618    sil! NetrwKeepj 1
9619    sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
9620    let line2= line(".")
9621    if line2 == 0
9622     if b:netrw_curdir != '/'
9623      exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
9624     endif
9625    endif
9626    exe "sil! NetrwKeepj ".line1
9627    sil! NetrwKeepj norm! 0
9628   endif
9629
9630   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9631"    call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
9632    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+\)\(\w.*\)$/\2\t\1/'
9633   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
9634"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9635    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
9636    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
9637    exe 'sil NetrwKeepj '.w:netrw_bannercnt
9638    NetrwKeepj call histdel("/",-1)
9639    NetrwKeepj call histdel("/",-1)
9640    NetrwKeepj call histdel("/",-1)
9641   endif
9642  endif
9643
9644"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
9645"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
9646"  endif " Decho
9647
9648"  call Dret("s:NetrwRemoteListing 0")
9649  return 0
9650endfun
9651
9652" ---------------------------------------------------------------------
9653" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
9654fun! s:NetrwRemoteRm(usrhost,path) range
9655"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
9656"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
9657  let svpos= netrw#SavePosn()
9658
9659  let all= 0
9660  if exists("s:netrwmarkfilelist_{bufnr('%')}")
9661   " remove all marked files
9662"   call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>"))
9663   for fname in s:netrwmarkfilelist_{bufnr("%")}
9664    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
9665    if ok =~ 'q\%[uit]'
9666     break
9667    elseif ok =~ 'a\%[ll]'
9668     let all= 1
9669    endif
9670   endfor
9671   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
9672
9673  else
9674   " remove files specified by range
9675"   call Decho("remove files specified by range",'~'.expand("<slnum>"))
9676
9677   " preparation for removing multiple files/directories
9678   let keepsol = &l:sol
9679   setl nosol
9680   let ctr    = a:firstline
9681
9682   " remove multiple files and directories
9683   while ctr <= a:lastline
9684    exe "NetrwKeepj ".ctr
9685    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
9686    if ok =~ 'q\%[uit]'
9687     break
9688    elseif ok =~ 'a\%[ll]'
9689     let all= 1
9690    endif
9691    let ctr= ctr + 1
9692   endwhile
9693   let &l:sol = keepsol
9694  endif
9695
9696  " refresh the (remote) directory listing
9697"  call Decho("refresh remote directory listing",'~'.expand("<slnum>"))
9698  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
9699  NetrwKeepj call netrw#RestorePosn(svpos)
9700
9701"  call Dret("s:NetrwRemoteRm")
9702endfun
9703
9704" ---------------------------------------------------------------------
9705" s:NetrwRemoteRmFile: {{{2
9706fun! s:NetrwRemoteRmFile(path,rmfile,all)
9707"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
9708
9709  let all= a:all
9710  let ok = ""
9711
9712  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
9713   " attempt to remove file
9714"    call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
9715   if !all
9716    echohl Statement
9717"    call Decho("case all=0:",'~'.expand("<slnum>"))
9718    call inputsave()
9719    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
9720    call inputrestore()
9721    echohl NONE
9722    if ok == ""
9723     let ok="no"
9724    endif
9725    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
9726    if ok =~ 'a\%[ll]'
9727     let all= 1
9728    endif
9729   endif
9730
9731   if all || ok =~ 'y\%[es]' || ok == ""
9732"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
9733    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9734"     call Decho("case ftp:",'~'.expand("<slnum>"))
9735     let path= a:path
9736     if path =~ '^\a\{3,}://'
9737      let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
9738     endif
9739     sil! NetrwKeepj .,$d
9740     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
9741    else
9742"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
9743     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
9744"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
9745     if !exists("b:netrw_curdir")
9746      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
9747      let ok="q"
9748     else
9749      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
9750"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
9751"      call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
9752"      call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
9753      if remotedir != ""
9754       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
9755      else
9756       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
9757      endif
9758"      call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
9759      let ret= system(netrw_rm_cmd)
9760      if v:shell_error != 0
9761       if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
9762        call netrw#ErrorMsg(s:ERROR,"remove failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",102)
9763       else
9764        call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
9765       endif
9766      else if ret != 0
9767       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
9768      endif
9769"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9770     endif
9771    endif
9772   elseif ok =~ 'q\%[uit]'
9773"    call Decho("ok==".ok,'~'.expand("<slnum>"))
9774   endif
9775
9776  else
9777   " attempt to remove directory
9778"    call Decho("attempt to remove directory",'~'.expand("<slnum>"))
9779   if !all
9780    call inputsave()
9781    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
9782    call inputrestore()
9783    if ok == ""
9784     let ok="no"
9785    endif
9786    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
9787    if ok =~ 'a\%[ll]'
9788     let all= 1
9789    endif
9790   endif
9791
9792   if all || ok =~ 'y\%[es]' || ok == ""
9793    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9794     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
9795    else
9796     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
9797     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
9798"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
9799     let ret= system(netrw_rmdir_cmd)
9800"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9801
9802     if v:shell_error != 0
9803"      call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
9804      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
9805"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
9806      let ret= system(netrw_rmf_cmd)
9807"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9808
9809      if v:shell_error != 0 && !exists("g:netrw_quiet")
9810      	NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
9811      endif
9812     endif
9813    endif
9814
9815   elseif ok =~ 'q\%[uit]'
9816"    call Decho("ok==".ok,'~'.expand("<slnum>"))
9817   endif
9818  endif
9819
9820"  call Dret("s:NetrwRemoteRmFile ".ok)
9821  return ok
9822endfun
9823
9824" ---------------------------------------------------------------------
9825" s:NetrwRemoteRename: rename a remote file or directory {{{2
9826fun! s:NetrwRemoteRename(usrhost,path) range
9827"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
9828
9829  " preparation for removing multiple files/directories
9830  let svpos      = netrw#SavePosn()
9831  let ctr        = a:firstline
9832  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
9833
9834  " rename files given by the markfilelist
9835  if exists("s:netrwmarkfilelist_{bufnr('%')}")
9836   for oldname in s:netrwmarkfilelist_{bufnr("%")}
9837"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
9838    if exists("subfrom")
9839     let newname= substitute(oldname,subfrom,subto,'')
9840"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
9841    else
9842     call inputsave()
9843     let newname= input("Moving ".oldname." to : ",oldname)
9844     call inputrestore()
9845     if newname =~ '^s/'
9846      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
9847      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
9848      let newname = substitute(oldname,subfrom,subto,'')
9849"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
9850     endif
9851    endif
9852
9853    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9854     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
9855    else
9856     let oldname= s:ShellEscape(a:path.oldname)
9857     let newname= s:ShellEscape(a:path.newname)
9858"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
9859     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
9860    endif
9861
9862   endfor
9863   call s:NetrwUnMarkFile(1)
9864
9865  else
9866
9867  " attempt to rename files/directories
9868   let keepsol= &l:sol
9869   setl nosol
9870   while ctr <= a:lastline
9871    exe "NetrwKeepj ".ctr
9872
9873    let oldname= s:NetrwGetWord()
9874"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
9875
9876    call inputsave()
9877    let newname= input("Moving ".oldname." to : ",oldname)
9878    call inputrestore()
9879
9880    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9881     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
9882    else
9883     let oldname= s:ShellEscape(a:path.oldname)
9884     let newname= s:ShellEscape(a:path.newname)
9885"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
9886     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
9887    endif
9888
9889    let ctr= ctr + 1
9890   endwhile
9891   let &l:sol= keepsol
9892  endif
9893
9894  " refresh the directory
9895  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
9896  NetrwKeepj call netrw#RestorePosn(svpos)
9897
9898"  call Dret("NetrwRemoteRename")
9899endfun
9900
9901" ---------------------------------------------------------------------
9902"  Local Directory Browsing Support:    {{{1
9903" ==========================================
9904
9905" ---------------------------------------------------------------------
9906" netrw#FileUrlRead: handles reading file://* files {{{2
9907"   Should accept:   file://localhost/etc/fstab
9908"                    file:///etc/fstab
9909"                    file:///c:/WINDOWS/clock.avi
9910"                    file:///c|/WINDOWS/clock.avi
9911"                    file://localhost/c:/WINDOWS/clock.avi
9912"                    file://localhost/c|/WINDOWS/clock.avi
9913"                    file://c:/foo.txt
9914"                    file:///c:/foo.txt
9915" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
9916fun! netrw#FileUrlRead(fname)
9917"  call Dfunc("netrw#FileUrlRead(fname<".a:fname.">)")
9918  let fname = a:fname
9919  if fname =~ '^file://localhost/'
9920"   call Decho('converting file://localhost/   -to-  file:///','~'.expand("<slnum>"))
9921   let fname= substitute(fname,'^file://localhost/','file:///','')
9922"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9923  endif
9924  if (has("win32") || has("win95") || has("win64") || has("win16"))
9925   if fname  =~ '^file:///\=\a[|:]/'
9926"    call Decho('converting file:///\a|/   -to-  file://\a:/','~'.expand("<slnum>"))
9927    let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
9928"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9929   endif
9930  endif
9931  let fname2396 = netrw#RFC2396(fname)
9932  let fname2396e= fnameescape(fname2396)
9933  let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
9934  if (has("win32") || has("win95") || has("win64") || has("win16"))
9935"   call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
9936   if plainfname =~ '^/\+\a:'
9937"    call Decho('removing leading "/"s','~'.expand("<slnum>"))
9938    let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
9939   endif
9940  endif
9941"  call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
9942"  call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
9943  exe "sil doau BufReadPre ".fname2396e
9944  exe 'NetrwKeepj r '.plainfname
9945  exe 'sil! bdelete '.plainfname
9946  exe 'keepalt file! '.plainfname
9947  NetrwKeepj 1d
9948"  call Decho("setl nomod",'~'.expand("<slnum>"))
9949  setl nomod
9950"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9951"  call Dret("netrw#FileUrlRead")
9952  exe "sil doau BufReadPost ".fname2396e
9953endfun
9954
9955" ---------------------------------------------------------------------
9956" netrw#LocalBrowseCheck: {{{2
9957fun! netrw#LocalBrowseCheck(dirname)
9958  " This function is called by netrwPlugin.vim's s:LocalBrowse() and by s:NetrwRexplore()
9959  " unfortunate interaction -- split window debugging can't be
9960  " used here, must use D-echoRemOn or D-echoTabOn -- the BufEnter
9961  " event triggers another call to LocalBrowseCheck() when attempts
9962  " to write to the DBG buffer are made.
9963  " The &ft == "netrw" test was installed because the BufEnter event
9964  " would hit when re-entering netrw windows, creating unexpected
9965  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
9966"  call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">")
9967"  call Decho("isdir<".a:dirname.">=".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).expand("<slnum>"))
9968"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
9969"  call Dredir("ls!","ls!")
9970"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
9971"  call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
9972
9973  let ykeep= @@
9974  if isdirectory(s:NetrwFile(a:dirname))
9975"   call Decho("is-directory ft<".&ft."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : " doesn't exist")."> dirname<".a:dirname.">"." line($)=".line("$")." ft<".&ft."> g:netrw_fastbrowse=".g:netrw_fastbrowse,'~'.expand("<slnum>"))
9976
9977   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
9978"    call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
9979"    call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
9980    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
9981
9982   elseif &ft == "netrw" && line("$") == 1
9983"    call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
9984    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
9985
9986   elseif exists("s:treeforceredraw")
9987"    call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
9988    unlet s:treeforceredraw
9989    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
9990   endif
9991
9992"   call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
9993"   call Dret("netrw#LocalBrowseCheck")
9994   return
9995  endif
9996
9997  " following code wipes out currently unused netrw buffers
9998  "       IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
9999  "   AND IF the listing style is not a tree listing
10000  if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
10001"   call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10002   let ibuf    = 1
10003   let buflast = bufnr("$")
10004   while ibuf <= buflast
10005    if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10006     exe "sil! keepj keepalt ".ibuf."bw!"
10007    endif
10008    let ibuf= ibuf + 1
10009   endwhile
10010  endif
10011  let @@= ykeep
10012"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
10013"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10014  " not a directory, ignore it
10015"  call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
10016endfun
10017
10018" ---------------------------------------------------------------------
10019" s:LocalBrowseRefresh: this function is called after a user has {{{2
10020" performed any shell command.  The idea is to cause all local-browsing
10021" buffers to be refreshed after a user has executed some shell command,
10022" on the chance that s/he removed/created a file/directory with it.
10023fun! s:LocalBrowseRefresh()
10024"  call Dfunc("s:LocalBrowseRefresh() tabpagenr($)=".tabpagenr("$"))
10025"  call Decho("s:netrw_browselist =".(exists("s:netrw_browselist")?  string(s:netrw_browselist)  : '<n/a>'),'~'.expand("<slnum>"))
10026"  call Decho("w:netrw_bannercnt  =".(exists("w:netrw_bannercnt")?   string(w:netrw_bannercnt)   : '<n/a>'),'~'.expand("<slnum>"))
10027
10028  " determine which buffers currently reside in a tab
10029  if !exists("s:netrw_browselist")
10030"   call Dret("s:LocalBrowseRefresh : browselist is empty")
10031   return
10032  endif
10033  if !exists("w:netrw_bannercnt")
10034"   call Dret("s:LocalBrowseRefresh : don't refresh when focus not on netrw window")
10035   return
10036  endif
10037  if exists("s:netrw_events") && s:netrw_events == 1
10038   " s:LocalFastBrowser gets called (indirectly) from a
10039   let s:netrw_events= 2
10040"   call Dret("s:LocalBrowseRefresh : avoid initial double refresh")
10041   return
10042  endif
10043  let itab       = 1
10044  let buftablist = []
10045  let ykeep      = @@
10046  while itab <= tabpagenr("$")
10047   let buftablist = buftablist + tabpagebuflist()
10048   let itab       = itab + 1
10049   tabn
10050  endwhile
10051"  call Decho("buftablist".string(buftablist),'~'.expand("<slnum>"))
10052"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("<slnum>"))
10053  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10054  "   | refresh any netrw window
10055  "   | wipe out any non-displaying netrw buffer
10056  let curwin = winnr()
10057  let ibl    = 0
10058  for ibuf in s:netrw_browselist
10059"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("<slnum>"))
10060   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10061    " wipe out any non-displaying netrw buffer
10062"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("<slnum>"))
10063    exe "sil! keepj bd ".fnameescape(ibuf)
10064    call remove(s:netrw_browselist,ibl)
10065"    call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10066    continue
10067   elseif index(tabpagebuflist(),ibuf) != -1
10068    " refresh any netrw buffer
10069"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>"))
10070    exe bufwinnr(ibuf)."wincmd w"
10071    if getline(".") =~ 'Quick Help'
10072     " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10073     " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10074     let g:netrw_quickhelp= g:netrw_quickhelp - 1
10075    endif
10076"    call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>"))
10077    NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10078   endif
10079   let ibl= ibl + 1
10080"   call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("<slnum>"))
10081  endfor
10082"  call Decho("restore window: exe ".curwin."wincmd w",'~'.expand("<slnum>"))
10083  exe curwin."wincmd w"
10084  let @@= ykeep
10085
10086"  call Dret("s:LocalBrowseRefresh")
10087endfun
10088
10089" ---------------------------------------------------------------------
10090" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10091"
10092"     g:netrw_    Directory Is
10093"     fastbrowse  Local  Remote
10094"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
10095"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
10096"  fast   2         H      H
10097"
10098"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10099"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
10100"                       (re-using a buffer may not be as accurate)
10101"
10102"  s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds whena med or fast browsing
10103"                   =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10104"                       BufEnter may be first event, then a FocusGained event.  Ignore the first FocusGained event.
10105"                       If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10106"                   =2: autocmds installed (doesn't ignore any FocusGained events)
10107fun! s:LocalFastBrowser()
10108"  call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
10109"  call Decho("s:netrw_events        ".(exists("s:netrw_events")? "exists"    : 'n/a'),'~'.expand("<slnum>"))
10110"  call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")?  "installed" : "not installed"),'~'.expand("<slnum>"))
10111"  call Decho("autocmd: FocusGained  ".(exists("#FocusGained")?   "installed" : "not installed"),'~'.expand("<slnum>"))
10112
10113  " initialize browselist, a list of buffer numbers that the local browser has used
10114  if !exists("s:netrw_browselist")
10115"   call Decho("initialize s:netrw_browselist",'~'.expand("<slnum>"))
10116   let s:netrw_browselist= []
10117  endif
10118
10119  " append current buffer to fastbrowse list
10120  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
10121"   call Decho("appendng current buffer to browselist",'~'.expand("<slnum>"))
10122   call add(s:netrw_browselist,bufnr("%"))
10123"   call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10124  endif
10125
10126  " enable autocmd events to handle refreshing/removing local browser buffers
10127  "    If local browse buffer is currently showing: refresh it
10128  "    If local browse buffer is currently hidden : wipe it
10129  "    g:netrw_fastbrowse=0 : slow   speed, never re-use directory listing
10130  "                      =1 : medium speed, re-use directory listing for remote only
10131  "                      =2 : fast   speed, always re-use directory listing when possible
10132  if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
10133   let s:netrw_events= 1
10134   augroup AuNetrwEvent
10135    au!
10136    if (has("win32") || has("win95") || has("win64") || has("win16"))
10137"     call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
10138     au ShellCmdPost			*	call s:LocalBrowseRefresh()
10139    else
10140"     call Decho("installing autocmds: ShellCmdPost FocusGained",'~'.expand("<slnum>"))
10141     au ShellCmdPost,FocusGained	*	call s:LocalBrowseRefresh()
10142    endif
10143   augroup END
10144
10145  " user must have changed fastbrowse to its fast setting, so remove
10146  " the associated autocmd events
10147  elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
10148"   call Decho("remove AuNetrwEvent autcmd group",'~'.expand("<slnum>"))
10149   unlet s:netrw_events
10150   augroup AuNetrwEvent
10151    au!
10152   augroup END
10153   augroup! AuNetrwEvent
10154  endif
10155
10156"  call Dret("LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
10157endfun
10158
10159" ---------------------------------------------------------------------
10160"  s:LocalListing: does the job of "ls" for local directories {{{2
10161fun! s:LocalListing()
10162"  call Dfunc("s:LocalListing()")
10163"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10164"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
10165"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10166
10167"  if exists("b:netrw_curdir") |call Decho('b:netrw_curdir<'.b:netrw_curdir.">")  |else|call Decho("b:netrw_curdir doesn't exist",'~'.expand("<slnum>")) |endif
10168"  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",'~'.expand("<slnum>"))|endif
10169"  call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
10170
10171  " get the list of files contained in the current directory
10172  let dirname    = b:netrw_curdir
10173  let dirnamelen = strlen(b:netrw_curdir)
10174  if v:version == 704 && has("patch656")
10175"   call Decho("using glob with patch656",'~'.expand("<slnum>"))
10176   let filelist   = glob(s:ComposePath(dirname,"*"),0,1,1)
10177   let filelist   = filelist + glob(s:ComposePath(dirname,".*"),0,1,1)
10178  else
10179"   call Decho("using glob without patch656",'~'.expand("<slnum>"))
10180   let filelist   = glob(s:ComposePath(dirname,"*"),0,1)
10181   let filelist   = filelist + glob(s:ComposePath(dirname,".*"),0,1)
10182  endif
10183"  call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10184
10185  if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
10186"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10187  elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
10188    " include ../ in the glob() entry if its missing
10189"   call Decho("forcibly including on \"..\"",'~'.expand("<slnum>"))
10190   let filelist= filelist+[s:ComposePath(b:netrw_curdir,"../")]
10191"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10192  endif
10193
10194"  call Decho("before while: dirname<".dirname.">",'~'.expand("<slnum>"))
10195"  call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>"))
10196"  call Decho("before while: filelist=".string(filelist),'~'.expand("<slnum>"))
10197
10198  if get(g:, 'netrw_dynamic_maxfilenamelen', 0)
10199   let filelistcopy           = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10200   let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
10201"   call Decho("dynamic_maxfilenamelen: filenames             =".string(filelistcopy),'~'.expand("<slnum>"))
10202"   call Decho("dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen,'~'.expand("<slnum>"))
10203  endif
10204"  call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
10205
10206  for filename in filelist
10207"   call Decho(" ",'~'.expand("<slnum>"))
10208"   call Decho("for filename in filelist: filename<".filename.">",'~'.expand("<slnum>"))
10209
10210   if getftype(filename) == "link"
10211    " indicate a symbolic link
10212"    call Decho("indicate <".filename."> is a symbolic link with trailing @",'~'.expand("<slnum>"))
10213    let pfile= filename."@"
10214
10215   elseif getftype(filename) == "socket"
10216    " indicate a socket
10217"    call Decho("indicate <".filename."> is a socket with trailing =",'~'.expand("<slnum>"))
10218    let pfile= filename."="
10219
10220   elseif getftype(filename) == "fifo"
10221    " indicate a fifo
10222"    call Decho("indicate <".filename."> is a fifo with trailing |",'~'.expand("<slnum>"))
10223    let pfile= filename."|"
10224
10225   elseif isdirectory(s:NetrwFile(filename))
10226    " indicate a directory
10227"    call Decho("indicate <".filename."> is a directory with trailing /",'~'.expand("<slnum>"))
10228    let pfile= filename."/"
10229
10230   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10231    if (has("win32") || has("win95") || has("win64") || has("win16"))
10232     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10233      " indicate an executable
10234"      call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10235      let pfile= filename."*"
10236     else
10237      " normal file
10238      let pfile= filename
10239     endif
10240    elseif executable(filename)
10241     " indicate an executable
10242"     call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10243     let pfile= filename."*"
10244    else
10245     " normal file
10246     let pfile= filename
10247    endif
10248
10249   else
10250    " normal file
10251    let pfile= filename
10252   endif
10253"   call Decho("pfile<".pfile."> (after *@/ appending)",'~'.expand("<slnum>"))
10254
10255   if pfile =~ '//$'
10256    let pfile= substitute(pfile,'//$','/','e')
10257"    call Decho("change // to /: pfile<".pfile.">",'~'.expand("<slnum>"))
10258   endif
10259   let pfile= strpart(pfile,dirnamelen)
10260   let pfile= substitute(pfile,'^[/\\]','','e')
10261"   call Decho("filename<".filename.">",'~'.expand("<slnum>"))
10262"   call Decho("pfile   <".pfile.">",'~'.expand("<slnum>"))
10263
10264   if w:netrw_liststyle == s:LONGLIST
10265    let sz   = getfsize(filename)
10266    let fsz  = strpart("               ",1,15-strlen(sz)).sz
10267    let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
10268"    call Decho("sz=".sz." fsz=".fsz,'~'.expand("<slnum>"))
10269   endif
10270
10271   if     g:netrw_sort_by =~ "^t"
10272    " sort by time (handles time up to 1 quintillion seconds, US)
10273"    call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>"))
10274    let t  = getftime(filename)
10275    let ft = strpart("000000000000000000",1,18-strlen(t)).t
10276"    call Decho("exe NetrwKeepj put ='".ft.'/'.filename."'",'~'.expand("<slnum>"))
10277    let ftpfile= ft.'/'.pfile
10278    sil! NetrwKeepj put=ftpfile
10279
10280   elseif g:netrw_sort_by =~ "^s"
10281    " sort by size (handles file sizes up to 1 quintillion bytes, US)
10282"    call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>"))
10283    let sz   = getfsize(filename)
10284    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
10285"    call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>"))
10286    let fszpfile= fsz.'/'.pfile
10287    sil! NetrwKeepj put =fszpfile
10288
10289   else
10290    " sort by name
10291"    call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("<slnum>"))
10292    sil! NetrwKeepj put=pfile
10293   endif
10294  endfor
10295
10296  " cleanup any windows mess at end-of-line
10297  sil! NetrwKeepj g/^$/d
10298  sil! NetrwKeepj %s/\r$//e
10299  call histdel("/",-1)
10300"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
10301  exe "setl ts=".(g:netrw_maxfilenamelen+1)
10302
10303"  call Dret("s:LocalListing")
10304endfun
10305
10306" ---------------------------------------------------------------------
10307" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
10308fun! s:NetrwLocalExecute(cmd)
10309"  call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
10310  let ykeep= @@
10311  " sanity check
10312  if !executable(a:cmd)
10313   call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
10314   let @@= ykeep
10315"   call Dret("s:NetrwLocalExecute")
10316   return
10317  endif
10318
10319  let optargs= input(":!".a:cmd,"","file")
10320"  call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
10321  let result= system(a:cmd.optargs)
10322"  call Decho("result,'~'.expand("<slnum>"))
10323
10324  " strip any ansi escape sequences off
10325  let result = substitute(result,"\e\\[[0-9;]*m","","g")
10326
10327  " show user the result(s)
10328  echomsg result
10329  let @@= ykeep
10330
10331"  call Dret("s:NetrwLocalExecute")
10332endfun
10333
10334" ---------------------------------------------------------------------
10335" s:NetrwLocalRename: rename a local file or directory {{{2
10336fun! s:NetrwLocalRename(path) range
10337"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
10338
10339  " preparation for removing multiple files/directories
10340  let ykeep    = @@
10341  let ctr      = a:firstline
10342  let svpos    = netrw#SavePosn()
10343
10344  " rename files given by the markfilelist
10345  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10346   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10347"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10348    if exists("subfrom")
10349     let newname= substitute(oldname,subfrom,subto,'')
10350"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10351    else
10352     call inputsave()
10353     let newname= input("Moving ".oldname." to : ",oldname,"file")
10354     call inputrestore()
10355     if newname =~ ''
10356      " two ctrl-x's : ignore all of string preceding the ctrl-x's
10357      let newname = substitute(newname,'^.*','','')
10358     elseif newname =~ ''
10359      " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
10360      let newname = substitute(newname,'[^/]*','','')
10361     endif
10362     if newname =~ '^s/'
10363      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10364      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10365"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10366      let newname = substitute(oldname,subfrom,subto,'')
10367     endif
10368    endif
10369    call rename(oldname,newname)
10370   endfor
10371   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10372
10373  else
10374
10375   " attempt to rename files/directories
10376   while ctr <= a:lastline
10377    exe "NetrwKeepj ".ctr
10378
10379    " sanity checks
10380    if line(".") < w:netrw_bannercnt
10381     let ctr= ctr + 1
10382     continue
10383    endif
10384    let curword= s:NetrwGetWord()
10385    if curword == "./" || curword == "../"
10386     let ctr= ctr + 1
10387     continue
10388    endif
10389
10390    NetrwKeepj norm! 0
10391    let oldname= s:ComposePath(a:path,curword)
10392"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10393
10394    call inputsave()
10395    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
10396    call inputrestore()
10397
10398    call rename(oldname,newname)
10399"   call Decho("renaming <".oldname."> to <".newname.">",'~'.expand("<slnum>"))
10400
10401    let ctr= ctr + 1
10402   endwhile
10403  endif
10404
10405  " refresh the directory
10406"  call Decho("refresh the directory listing",'~'.expand("<slnum>"))
10407  NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10408  NetrwKeepj call netrw#RestorePosn(svpos)
10409  let @@= ykeep
10410
10411"  call Dret("NetrwLocalRename")
10412endfun
10413
10414" ---------------------------------------------------------------------
10415" s:NetrwLocalRm: {{{2
10416fun! s:NetrwLocalRm(path) range
10417"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
10418"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10419
10420  " preparation for removing multiple files/directories
10421  let ykeep = @@
10422  let ret   = 0
10423  let all   = 0
10424  let svpos = netrw#SavePosn()
10425
10426  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10427   " remove all marked files
10428"   call Decho("remove all marked files",'~'.expand("<slnum>"))
10429   for fname in s:netrwmarkfilelist_{bufnr("%")}
10430    let ok= s:NetrwLocalRmFile(a:path,fname,all)
10431    if ok =~ 'q\%[uit]' || ok == "no"
10432     break
10433    elseif ok =~ 'a\%[ll]'
10434     let all= 1
10435    endif
10436   endfor
10437   call s:NetrwUnMarkFile(1)
10438
10439  else
10440  " remove (multiple) files and directories
10441"   call Decho("remove files in range [".a:firstline.",".a:lastline."]",'~'.expand("<slnum>"))
10442
10443   let keepsol= &l:sol
10444   setl nosol
10445   let ctr = a:firstline
10446   while ctr <= a:lastline
10447    exe "NetrwKeepj ".ctr
10448
10449    " sanity checks
10450    if line(".") < w:netrw_bannercnt
10451     let ctr= ctr + 1
10452     continue
10453    endif
10454    let curword= s:NetrwGetWord()
10455    if curword == "./" || curword == "../"
10456     let ctr= ctr + 1
10457     continue
10458    endif
10459    let ok= s:NetrwLocalRmFile(a:path,curword,all)
10460    if ok =~ 'q\%[uit]' || ok == "no"
10461     break
10462    elseif ok =~ 'a\%[ll]'
10463     let all= 1
10464    endif
10465    let ctr= ctr + 1
10466   endwhile
10467   let &l:sol= keepsol
10468  endif
10469
10470  " refresh the directory
10471"  call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>"))
10472  if bufname("%") != "NetrwMessage"
10473   NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10474   NetrwKeepj call netrw#RestorePosn(svpos)
10475  endif
10476  let @@= ykeep
10477
10478"  call Dret("s:NetrwLocalRm")
10479endfun
10480
10481" ---------------------------------------------------------------------
10482" s:NetrwLocalRmFile: remove file fname given the path {{{2
10483"                     Give confirmation prompt unless all==1
10484fun! s:NetrwLocalRmFile(path,fname,all)
10485"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
10486
10487  let all= a:all
10488  let ok = ""
10489  NetrwKeepj norm! 0
10490  let rmfile= s:NetrwFile(s:ComposePath(a:path,a:fname))
10491"  call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
10492
10493  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
10494   " attempt to remove file
10495"   call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
10496   if !all
10497    echohl Statement
10498    call inputsave()
10499    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10500    call inputrestore()
10501    echohl NONE
10502    if ok == ""
10503     let ok="no"
10504    endif
10505"    call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
10506    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10507"    call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
10508    if ok =~ 'a\%[ll]'
10509     let all= 1
10510    endif
10511   endif
10512
10513   if all || ok =~ 'y\%[es]' || ok == ""
10514    let ret= s:NetrwDelete(rmfile)
10515"    call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
10516   endif
10517
10518  else
10519   " attempt to remove directory
10520   if !all
10521    echohl Statement
10522    call inputsave()
10523    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10524    call inputrestore()
10525    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10526    if ok == ""
10527     let ok="no"
10528    endif
10529    if ok =~ 'a\%[ll]'
10530     let all= 1
10531    endif
10532   endif
10533   let rmfile= substitute(rmfile,'[\/]$','','e')
10534
10535   if all || ok =~ 'y\%[es]' || ok == ""
10536"    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>"))
10537    call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile))
10538"    call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>"))
10539
10540    if v:shell_error != 0
10541"     call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
10542     let errcode= s:NetrwDelete(rmfile)
10543"     call Decho("errcode=".errcode,'~'.expand("<slnum>"))
10544
10545     if errcode != 0
10546      if has("unix")
10547"       call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
10548       call system("rm ".s:ShellEscape(rmfile))
10549       if v:shell_error != 0 && !exists("g:netrw_quiet")
10550        call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
10551	let ok="no"
10552       endif
10553      elseif !exists("g:netrw_quiet")
10554       call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
10555       let ok="no"
10556      endif
10557     endif
10558    endif
10559   endif
10560  endif
10561
10562"  call Dret("s:NetrwLocalRmFile ".ok)
10563  return ok
10564endfun
10565
10566" ---------------------------------------------------------------------
10567" Support Functions: {{{1
10568
10569" ---------------------------------------------------------------------
10570" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
10571"   0: marked file list of current buffer
10572"   1: marked file target
10573fun! netrw#Access(ilist)
10574  if     a:ilist == 0
10575   if exists("s:netrwmarkfilelist_".bufnr('%'))
10576    return s:netrwmarkfilelist_{bufnr('%')}
10577   else
10578    return "no-list-buf#".bufnr('%')
10579   endif
10580  elseif a:ilist == 1
10581   return s:netrwmftgt
10582endfun
10583
10584" ---------------------------------------------------------------------
10585" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
10586fun! netrw#Call(funcname,...)
10587"  call Dfunc("netrw#Call(funcname<".a:funcname.">,".string(a:000).")")
10588  if a:0 > 0
10589   exe "call s:".a:funcname."(".string(a:000).")"
10590  else
10591   exe "call s:".a:funcname."()"
10592  endif
10593"  call Dret("netrw#Call")
10594endfun
10595
10596" ------------------------------------------------------------------------
10597" netrw#RestorePosn: restores the cursor and file position as saved by netrw#SavePosn() {{{2
10598fun! netrw#RestorePosn(...)
10599"  call Dfunc("netrw#RestorePosn() 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))
10600  let eikeep= &ei
10601  setl ei=all
10602  if expand("%") == "NetrwMessage"
10603   if exists("s:winBeforeErr")
10604    exe s:winBeforeErr."wincmd w"
10605   endif
10606  endif
10607
10608  if a:0 > 0
10609   exe "keepj ".a:1
10610  endif
10611"  "call Decho("a:1             = ".((a:0 > 0)?              a:1       : 'n/a'),'~'.expand("<slnum>"))
10612"  "call Decho("liststyle       = ".(exists("liststyle")?    liststyle : 'n/a'). " w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
10613  if exists("liststyle") && exists("w:netrw_liststyle") && liststyle != w:netrw_liststyle
10614   let usesrch= 1
10615  else
10616   let usesrch= 0
10617  endif
10618
10619"  "call Decho("winh            = ".(exists("w:netrw_winh")?    w:netrw_winh    : -1),'~'.expand("<slnum>"))
10620"  "call Decho("winw            = ".(exists("w:netrw_winw")?    w:netrw_winw    : -1),'~'.expand("<slnum>"))
10621"  "call Decho("cur    winheight=".winheight(0)." winwidth=".winwidth(0),'~'.expand("<slnum>"))
10622"  "call Decho("w:netrw_winfile = ".(exists("w:netrw_winfile")? w:netrw_winfile : 'n/a'),'~'.expand("<slnum>"))
10623
10624  " restore window
10625  if exists("w:netrw_winnr")
10626"   "call Decho("restore window: exe sil! ".w:netrw_winnr."wincmd w",'~'.expand("<slnum>"))
10627   exe "sil! ".w:netrw_winnr."wincmd w"
10628  endif
10629"  if v:shell_error == 0
10630   " as suggested by Bram M: redraw on no error
10631   " allows protocol error messages to remain visible
10632"   redraw!
10633"  endif
10634
10635  " restore top-of-screen line
10636  if exists("w:netrw_hline")
10637"   "call Decho("restore topofscreen: exe keepj norm! ".w:netrw_hline."G0z",'~'.expand("<slnum>"))
10638   exe "keepj norm! ".w:netrw_hline."G0z\<CR>"
10639  endif
10640
10641  " restore position
10642  " when the window's height x width has changed, the line,col is no longer useful
10643  if w:netrw_winh == winheight(0) && w:netrw_winw == winwidth(0) && exists("w:netrw_line") && exists("w:netrw_col") && !usesrch
10644"   "call Decho("using posn: exe keepj norm! ".w:netrw_line."G0".w:netrw_col."|",'~'.expand("<slnum>"))
10645   exe "keepj norm! ".w:netrw_line."G0".w:netrw_col."\<bar>"
10646
10647  elseif exists("w:netrw_winfile")
10648   if !search('\<'.escape(w:netrw_winfile,g:netrw_fname_escape),'cw')
10649    if exists("w:netrw_bannercnt")
10650"     "call Decho("using bannercnt: win#".winnr()." ".winheight(0)."x".winwidth(0)." w:netrw_winfile<".w:netrw_winfile.">",'~'.expand("<slnum>"))
10651     exe "keepj ".w:netrw_bannercnt
10652     norm! 0
10653    else
10654     " go to upper left corner
10655"     "call Decho("goto ulc: win#".winnr()." ".winheight(0)."x".winwidth(0)." w:netrw_winfile<".w:netrw_winfile.">",'~'.expand("<slnum>"))
10656     keepj 1
10657     norm! 0
10658    endif
10659   else
10660"    "call Decho("used search: w:netrw_winfile<".w:netrw_winfile.">",'~'.expand("<slnum>"))
10661   endif
10662
10663  else
10664"   "call Decho("goto ulc: win#".winnr()." ".winheight(0)."x".winwidth(0),'~'.expand("<slnum>"))
10665   keepj 1
10666   norm! 0
10667  endif
10668
10669  let &ei= eikeep
10670"  call Dret("netrw#RestorePosn : line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol())
10671endfun
10672
10673" ---------------------------------------------------------------------
10674" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
10675"               I expect this function to be used in
10676"                 :PChkAssert netrw#Expose("netrwmarkfilelist")
10677"               for example.
10678fun! netrw#Expose(varname)
10679"   call Dfunc("netrw#Expose(varname<".a:varname.">)")
10680  exe "let retval= s:".a:varname
10681  if exists("g:netrw_pchk")
10682   if type(retval) == 3
10683    let retval = copy(retval)
10684    let i      = 0
10685    while i < len(retval)
10686     let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
10687     let i        = i + 1
10688    endwhile
10689   endif
10690"    call Dret("netrw#Expose ".string(retval))
10691   return string(retval)
10692  endif
10693
10694"  call Dret("netrw#Expose ".string(retval))
10695  return retval
10696endfun
10697
10698" ---------------------------------------------------------------------
10699" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
10700fun! netrw#Modify(varname,newvalue)
10701"  call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
10702  exe "let s:".a:varname."= ".string(a:newvalue)
10703"  call Dret("netrw#Modify")
10704endfun
10705
10706" ---------------------------------------------------------------------
10707"  netrw#RFC2396: converts %xx into characters {{{2
10708fun! netrw#RFC2396(fname)
10709"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
10710  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
10711"  call Dret("netrw#RFC2396 ".fname)
10712  return fname
10713endfun
10714
10715" ---------------------------------------------------------------------
10716" netrw#SavePosn: saves position of cursor on screen {{{2
10717fun! netrw#SavePosn()
10718"  call Dfunc("netrw#SavePosn() win#".winnr()." line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol())
10719  " Save current line and column
10720  let w:netrw_winnr= winnr()
10721  let w:netrw_line = line(".")
10722  let w:netrw_col  = virtcol(".")
10723"  "call Decho("currently, win#".w:netrw_winnr." line#".w:netrw_line." col#".w:netrw_col,'~'.expand("<slnum>"))
10724
10725  " save filename under cursor
10726"  "call Decho("line#".line(".")." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
10727  if exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt && &ft == "netrw"
10728   let winfile = "|let w:netrw_winfile=\"".fnameescape(s:NetrwGetWord())."\""
10729  else
10730   let winfile= ""
10731  endif
10732"  "call Decho("winfile<".winfile.">",'~'.expand("<slnum>"))
10733  if exists("w:netrw_liststyle")
10734   let liststyle = "|let liststyle=".w:netrw_liststyle
10735  else
10736   let liststyle= ""
10737  endif
10738"  "call Decho("liststyle=".liststyle,'~'.expand("<slnum>"))
10739
10740  " Save top-of-screen line
10741  keepj norm! H0
10742  let w:netrw_hline= line(".")
10743
10744  " save up alternate position information
10745  " use this when window height x width has changed
10746  let w:netrw_winh = winheight(0)
10747  let w:netrw_winw = winwidth(0)
10748
10749  " set up string holding position parameters
10750  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."|let w:netrw_winh=".w:netrw_winh."|let w:netrw_winw=".w:netrw_winw.liststyle.winfile
10751
10752  keepj call netrw#RestorePosn()
10753"  call Dret("netrw#SavePosn : win#=".(exists("w:netrw_winnr")? w:netrw_winnr : "n/a")." line=".(exists("w:netrw_line")? w:netrw_line : "n/a")." col=".(exists("w:netrw_col")? w:netrw_col : "n/a")." hline=".(exists("w:netrw_hline")? w:netrw_hline : "n/a"))
10754  return ret
10755endfun
10756
10757" ---------------------------------------------------------------------
10758" netrw#UserMaps: supports user-specified maps {{{2
10759"                 see :help function()
10760"
10761"                 g:Netrw_UserMaps is a List with members such as:
10762"                       [[keymap sequence, function reference],...]
10763"
10764"                 The referenced function may return a string,
10765"                 	refresh : refresh the display
10766"                 	-other- : this string will be executed
10767"                 or it may return a List of strings.
10768"
10769"                 Each keymap-sequence will be set up with a nnoremap
10770"                 to invoke netrw#UserMaps(islocal).
10771"                 Related functions:
10772"                   netrw#Expose(varname)          -- see s:varname variables
10773"                   netrw#Modify(varname,newvalue) -- modify value of s:varname variable
10774"                   netrw#Call(funcname,...)       -- call internal netrw function with optional arguments
10775fun! netrw#UserMaps(islocal)
10776"  call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
10777"  call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
10778
10779   " set up usermaplist
10780   if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
10781"    call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
10782    for umap in g:Netrw_UserMaps
10783"     call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
10784"     call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
10785     " if umap[0] is a string and umap[1] is a string holding a function name
10786     if type(umap[0]) == 1 && type(umap[1]) == 1
10787"      call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
10788      exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
10789      else
10790       call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
10791     endif
10792    endfor
10793   endif
10794"  call Dret("netrw#UserMaps")
10795endfun
10796
10797" ---------------------------------------------------------------------
10798" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
10799fun! netrw#WinPath(path)
10800"  call Dfunc("netrw#WinPath(path<".a:path.">)")
10801  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
10802   " remove cygdrive prefix, if present
10803   let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
10804   " remove trailing slash (Win95)
10805   let path = substitute(path, '\(\\\|/\)$', '', 'g')
10806   " remove escaped spaces
10807   let path = substitute(path, '\ ', ' ', 'g')
10808   " convert slashes to backslashes
10809   let path = substitute(path, '/', '\', 'g')
10810  else
10811   let path= a:path
10812  endif
10813"  call Dret("netrw#WinPath <".path.">")
10814  return path
10815endfun
10816
10817" ---------------------------------------------------------------------
10818"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
10819fun! s:ComposePath(base,subdir)
10820"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
10821
10822  if has("amiga")
10823"   call Decho("amiga",'~'.expand("<slnum>"))
10824   let ec = a:base[s:Strlen(a:base)-1]
10825   if ec != '/' && ec != ':'
10826    let ret = a:base . "/" . a:subdir
10827   else
10828    let ret = a:base . a:subdir
10829   endif
10830
10831  elseif a:subdir =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
10832"   call Decho("windows",'~'.expand("<slnum>"))
10833   let ret= a:subdir
10834
10835  elseif a:base =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
10836"   call Decho("windows",'~'.expand("<slnum>"))
10837   if a:base =~ '[/\\]$'
10838    let ret= a:base.a:subdir
10839   else
10840    let ret= a:base.'/'.a:subdir
10841   endif
10842
10843  elseif a:base =~ '^\a\{3,}://'
10844"   call Decho("remote linux/macos",'~'.expand("<slnum>"))
10845   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
10846   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
10847   if a:subdir == '../'
10848    if curpath =~ '[^/]/[^/]\+/$'
10849     let curpath= substitute(curpath,'[^/]\+/$','','')
10850    else
10851     let curpath=""
10852    endif
10853    let ret= urlbase.curpath
10854   else
10855    let ret= urlbase.curpath.a:subdir
10856   endif
10857"   call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
10858"   call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
10859"   call Decho("ret<".ret.">",'~'.expand("<slnum>"))
10860
10861  else
10862"   call Decho("local linux/macos",'~'.expand("<slnum>"))
10863   let ret = substitute(a:base."/".a:subdir,"//","/","g")
10864   if a:base =~ '^//'
10865    " keeping initial '//' for the benefit of network share listing support
10866    let ret= '/'.ret
10867   endif
10868   let ret= simplify(ret)
10869  endif
10870
10871"  call Dret("s:ComposePath ".ret)
10872  return ret
10873endfun
10874
10875" ---------------------------------------------------------------------
10876" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
10877"   Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
10878fun! s:DeleteBookmark(fname)
10879"  call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
10880  call s:MergeBookmarks()
10881
10882  if exists("g:netrw_bookmarklist")
10883   let indx= index(g:netrw_bookmarklist,a:fname)
10884   if indx == -1
10885    let indx= 0
10886    while indx < len(g:netrw_bookmarklist)
10887     if g:netrw_bookmarklist[indx] =~ a:fname
10888      call remove(g:netrw_bookmarklist,indx)
10889      let indx= indx - 1
10890     endif
10891     let indx= indx + 1
10892    endwhile
10893   else
10894    " remove exact match
10895    call remove(g:netrw_bookmarklist,indx)
10896   endif
10897  endif
10898
10899"  call Dret("s:DeleteBookmark")
10900endfun
10901
10902" ---------------------------------------------------------------------
10903" s:FileReadable: o/s independent filereadable {{{2
10904fun! s:FileReadable(fname)
10905"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
10906
10907  if g:netrw_cygwin
10908   let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
10909  else
10910   let ret= filereadable(s:NetrwFile(a:fname))
10911  endif
10912
10913"  call Dret("s:FileReadable ".ret)
10914  return ret
10915endfun
10916
10917" ---------------------------------------------------------------------
10918"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
10919"                 Places correct suffix on end of temporary filename,
10920"                 using the suffix provided with fname
10921fun! s:GetTempfile(fname)
10922"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
10923
10924  if !exists("b:netrw_tmpfile")
10925   " get a brand new temporary filename
10926   let tmpfile= tempname()
10927"   call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
10928
10929   let tmpfile= substitute(tmpfile,'\','/','ge')
10930"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
10931
10932   " sanity check -- does the temporary file's directory exist?
10933   if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
10934"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10935    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
10936"    call Dret("s:GetTempfile getcwd<".getcwd().">")
10937    return ""
10938   endif
10939
10940   " let netrw#NetSource() know about the tmpfile
10941   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
10942"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
10943
10944   " o/s dependencies
10945   if g:netrw_cygwin != 0
10946    let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
10947   elseif has("win32") || has("win95") || has("win64") || has("win16")
10948    if !exists("+shellslash") || !&ssl
10949     let tmpfile = substitute(tmpfile,'/','\','g')
10950    endif
10951   else
10952    let tmpfile = tmpfile
10953   endif
10954   let b:netrw_tmpfile= tmpfile
10955"   call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
10956  else
10957   " re-use temporary filename
10958   let tmpfile= b:netrw_tmpfile
10959"   call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
10960  endif
10961
10962  " use fname's suffix for the temporary file
10963  if a:fname != ""
10964   if a:fname =~ '\.[^./]\+$'
10965"    call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
10966    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
10967     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
10968    elseif a:fname =~ '.txz$'
10969     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
10970    else
10971     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
10972    endif
10973"    call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
10974    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
10975"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
10976    let tmpfile .= suffix
10977"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
10978    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
10979   endif
10980  endif
10981
10982"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10983"  call Dret("s:GetTempfile <".tmpfile.">")
10984  return tmpfile
10985endfun
10986
10987" ---------------------------------------------------------------------
10988" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
10989"               a correct command for use with a system() call
10990fun! s:MakeSshCmd(sshcmd)
10991"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
10992  if s:user == ""
10993   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
10994  else
10995   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
10996  endif
10997  if exists("g:netrw_port") && g:netrw_port != ""
10998   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
10999  elseif exists("s:port") && s:port != ""
11000   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
11001  else
11002   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
11003  endif
11004"  call Dret("s:MakeSshCmd <".sshcmd.">")
11005  return sshcmd
11006endfun
11007
11008" ---------------------------------------------------------------------
11009" s:MakeBookmark: enters a bookmark into Netrw's bookmark system   {{{2
11010fun! s:MakeBookmark(fname)
11011"  call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
11012
11013  if !exists("g:netrw_bookmarklist")
11014   let g:netrw_bookmarklist= []
11015  endif
11016
11017  if index(g:netrw_bookmarklist,a:fname) == -1
11018   " curdir not currently in g:netrw_bookmarklist, so include it
11019   if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11020    call add(g:netrw_bookmarklist,a:fname.'/')
11021   elseif a:fname !~ '/'
11022    call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11023   else
11024    call add(g:netrw_bookmarklist,a:fname)
11025   endif
11026   call sort(g:netrw_bookmarklist)
11027  endif
11028
11029"  call Dret("s:MakeBookmark")
11030endfun
11031
11032" ---------------------------------------------------------------------
11033" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11034fun! s:MergeBookmarks()
11035"  call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
11036  " get bookmarks from .netrwbook file
11037  let savefile= s:NetrwHome()."/.netrwbook"
11038  if filereadable(s:NetrwFile(savefile))
11039"   call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11040   NetrwKeepj call s:NetrwBookHistSave()
11041"   call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11042   NetrwKeepj call delete(savefile)
11043  endif
11044"  call Dret("s:MergeBookmarks")
11045endfun
11046
11047" ---------------------------------------------------------------------
11048" s:NetrwBMShow: {{{2
11049fun! s:NetrwBMShow()
11050"  call Dfunc("s:NetrwBMShow()")
11051  redir => bmshowraw
11052   menu
11053  redir END
11054  let bmshowlist = split(bmshowraw,'\n')
11055  if bmshowlist != []
11056   let bmshowfuncs= filter(bmshowlist,'v:val =~ "<SNR>\\d\\+_BMShow()"')
11057   if bmshowfuncs != []
11058    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11059    if bmshowfunc =~ '^call.*BMShow()'
11060     exe "sil! NetrwKeepj ".bmshowfunc
11061    endif
11062   endif
11063  endif
11064"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
11065endfun
11066
11067" ---------------------------------------------------------------------
11068" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
11069fun! s:NetrwCursor()
11070  if !exists("w:netrw_liststyle")
11071   let w:netrw_liststyle= g:netrw_liststyle
11072  endif
11073"  call Dfunc("s:NetrwCursor() ft<".&ft."> liststyle=".w:netrw_liststyle." g:netrw_cursor=".g:netrw_cursor." s:netrw_usercuc=".s:netrw_usercuc." s:netrw_usercul=".s:netrw_usercul)
11074
11075  if &ft != "netrw"
11076   " if the current window isn't a netrw directory listing window, then use user cursorline/column
11077   " settings.  Affects when netrw is used to read/write a file using scp/ftp/etc.
11078"   call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
11079   let &l:cursorline   = s:netrw_usercul
11080   let &l:cursorcolumn = s:netrw_usercuc
11081
11082  elseif g:netrw_cursor == 4
11083   " all styles: cursorline, cursorcolumn
11084"   call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
11085   setl cursorline
11086   setl cursorcolumn
11087
11088  elseif g:netrw_cursor == 3
11089   " thin-long-tree: cursorline, user's cursorcolumn
11090   " wide          : cursorline, cursorcolumn
11091   if w:netrw_liststyle == s:WIDELIST
11092"    call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11093    setl cursorline
11094    setl cursorcolumn
11095   else
11096"    call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11097    setl cursorline
11098    let &l:cursorcolumn   = s:netrw_usercuc
11099   endif
11100
11101  elseif g:netrw_cursor == 2
11102   " thin-long-tree: cursorline, user's cursorcolumn
11103   " wide          : cursorline, user's cursorcolumn
11104"   call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11105   let &l:cursorcolumn = s:netrw_usercuc
11106   setl cursorline
11107
11108  elseif g:netrw_cursor == 1
11109   " thin-long-tree: user's cursorline, user's cursorcolumn
11110   " wide          : cursorline,        user's cursorcolumn
11111   let &l:cursorcolumn = s:netrw_usercuc
11112   if w:netrw_liststyle == s:WIDELIST
11113"    call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11114    setl cursorline
11115   else
11116"    call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11117    let &l:cursorline   = s:netrw_usercul
11118   endif
11119
11120  else
11121   " all styles: user's cursorline, user's cursorcolumn
11122"   call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11123   let &l:cursorline   = s:netrw_usercul
11124   let &l:cursorcolumn = s:netrw_usercuc
11125  endif
11126
11127"  call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
11128endfun
11129
11130" ---------------------------------------------------------------------
11131" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11132fun! s:RestoreCursorline()
11133"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
11134  if exists("s:netrw_usercul")
11135   let &l:cursorline   = s:netrw_usercul
11136  endif
11137  if exists("s:netrw_usercuc")
11138   let &l:cursorcolumn = s:netrw_usercuc
11139  endif
11140"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
11141endfun
11142
11143" ---------------------------------------------------------------------
11144" s:NetrwDelete: Deletes a file. {{{2
11145"           Uses Steve Hall's idea to insure that Windows paths stay
11146"           acceptable.  No effect on Unix paths.
11147"  Examples of use:  let result= s:NetrwDelete(path)
11148fun! s:NetrwDelete(path)
11149"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
11150
11151  let path = netrw#WinPath(a:path)
11152  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
11153   if exists("+shellslash")
11154    let sskeep= &shellslash
11155    setl noshellslash
11156    let result      = delete(path)
11157    let &shellslash = sskeep
11158   else
11159"    call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11160    let result= delete(path)
11161   endif
11162  else
11163"   call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11164   let result= delete(path)
11165  endif
11166  if result < 0
11167   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
11168  endif
11169
11170"  call Dret("s:NetrwDelete ".result)
11171  return result
11172endfun
11173
11174" ---------------------------------------------------------------------
11175" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
11176fun! s:NetrwEnew(...)
11177"  call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$"))
11178"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
11179
11180  " grab a function-local-variable copy of buffer variables
11181"  call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
11182  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
11183  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
11184  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
11185  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
11186  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11187  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
11188  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
11189  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
11190  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11191  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11192  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
11193  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
11194  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
11195  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
11196  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
11197  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
11198
11199  NetrwKeepj call s:NetrwOptionRestore("w:")
11200"  call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>"))
11201  let netrw_keepdiff= &l:diff
11202  noswapfile NetrwKeepj keepalt enew!
11203  let &l:diff= netrw_keepdiff
11204"  call Decho("bufnr($)=".bufnr("$")." winnr($)=".winnr("$"),'~'.expand("<slnum>"))
11205  NetrwKeepj call s:NetrwOptionSave("w:")
11206
11207  " copy function-local-variables to buffer variable equivalents
11208"  call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
11209  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
11210  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
11211  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
11212  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
11213  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
11214  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
11215  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
11216  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
11217  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11218  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11219  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
11220  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
11221  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
11222  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
11223  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
11224  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
11225
11226  if a:0 > 0
11227   let b:netrw_curdir= a:1
11228   if b:netrw_curdir =~ '/$'
11229    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11230     file NetrwTreeListing
11231     setl bt=nowrite noswf bh=hide
11232     nno <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
11233     nno <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
11234    else
11235     exe "sil! keepalt file ".fnameescape(b:netrw_curdir)
11236    endif
11237   endif
11238  endif
11239
11240"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
11241endfun
11242
11243" ---------------------------------------------------------------------
11244" s:NetrwExe: executes a string using "!" {{{2
11245fun! s:NetrwExe(cmd)
11246"  call Dfunc("s:NetrwExe(a:cmd)")
11247  if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin
11248    let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
11249    set shell& shellcmdflag& shellxquote& shellxescape&
11250    set shellquote& shellpipe& shellredir& shellslash&
11251    exe a:cmd
11252    let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
11253  else
11254   exe a:cmd
11255  endif
11256"  call Dret("s:NetrwExe")
11257endfun
11258
11259" ---------------------------------------------------------------------
11260" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
11261fun! s:NetrwInsureWinVars()
11262"  call Dfunc("s:NetrwInsureWinVars() win#".winnr())
11263  if !exists("w:netrw_liststyle")
11264   let curbuf = bufnr("%")
11265   let curwin = winnr()
11266   let iwin   = 1
11267   while iwin <= winnr("$")
11268    exe iwin."wincmd w"
11269    if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
11270     " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
11271     let winvars= w:
11272     break
11273    endif
11274    let iwin= iwin + 1
11275   endwhile
11276   exe "keepalt ".curwin."wincmd w"
11277   if exists("winvars")
11278"    call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
11279    for k in keys(winvars)
11280     let w:{k}= winvars[k]
11281    endfor
11282   endif
11283  endif
11284"  call Dret("s:NetrwInsureWinVars win#".winnr())
11285endfun
11286
11287" ---------------------------------------------------------------------
11288" s:NetrwLcd: handles changing the (local) directory {{{2
11289fun! s:NetrwLcd(newdir)
11290"  call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
11291
11292  try
11293   exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
11294  catch /^Vim\%((\a\+)\)\=:E344/
11295     " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
11296     " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
11297     " 'root' (ie. '\').  The share name may start with either backslashes ('\\Foo') or
11298     " forward slashes ('//Foo'), depending on whether backslashes have been converted to
11299     " forward slashes by earlier code; so check for both.
11300     if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
11301       if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
11302         let dirname = '\'
11303	 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
11304       endif
11305     endif
11306  catch /^Vim\%((\a\+)\)\=:E472/
11307   call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
11308   if exists("w:netrw_prvdir")
11309    let a:newdir= w:netrw_prvdir
11310   else
11311    call s:NetrwOptionRestore("w:")
11312"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
11313    exe "setl ".g:netrw_bufsettings
11314"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11315    let a:newdir= dirname
11316"    call Dret("s:NetrwBrowse : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
11317    return
11318   endif
11319  endtry
11320
11321"  call Dret("s:NetrwLcd")
11322endfun
11323
11324" ------------------------------------------------------------------------
11325" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
11326" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
11327fun! s:NetrwSaveWordPosn()
11328"  call Dfunc("NetrwSaveWordPosn()")
11329  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
11330"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
11331endfun
11332
11333" ---------------------------------------------------------------------
11334" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
11335"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
11336fun! s:NetrwRestoreWordPosn()
11337"  call Dfunc("NetrwRestoreWordPosn()")
11338  sil! call search(s:netrw_saveword,'w')
11339"  call Dret("NetrwRestoreWordPosn")
11340endfun
11341
11342" ---------------------------------------------------------------------
11343" s:RestoreBufVars: {{{2
11344fun! s:RestoreBufVars()
11345"  call Dfunc("s:RestoreBufVars()")
11346
11347  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
11348  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
11349  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
11350  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
11351  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
11352  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
11353
11354"  call Dret("s:RestoreBufVars")
11355endfun
11356
11357" ---------------------------------------------------------------------
11358" s:RemotePathAnalysis: {{{2
11359fun! s:RemotePathAnalysis(dirname)
11360"  call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
11361
11362  "                method   ://    user  @      machine      :port            /path
11363  let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
11364  let s:method  = substitute(a:dirname,dirpat,'\1','')
11365  let s:user    = substitute(a:dirname,dirpat,'\3','')
11366  let s:machine = substitute(a:dirname,dirpat,'\4','')
11367  let s:port    = substitute(a:dirname,dirpat,'\5','')
11368  let s:path    = substitute(a:dirname,dirpat,'\6','')
11369  let s:fname   = substitute(s:path,'^.*/\ze.','','')
11370  if s:machine =~ '@'
11371   let dirpat    = '^\(.*\)@\(.\{-}\)$'
11372   let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')
11373   let s:machine = substitute(s:machine,dirpat,'\2','')
11374  endif
11375
11376"  call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
11377"  call Decho("set up s:user   <".s:user   .">",'~'.expand("<slnum>"))
11378"  call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
11379"  call Decho("set up s:port   <".s:port.">",'~'.expand("<slnum>"))
11380"  call Decho("set up s:path   <".s:path   .">",'~'.expand("<slnum>"))
11381"  call Decho("set up s:fname  <".s:fname  .">",'~'.expand("<slnum>"))
11382
11383"  call Dret("s:RemotePathAnalysis")
11384endfun
11385
11386" ---------------------------------------------------------------------
11387" s:RemoteSystem: runs a command on a remote host using ssh {{{2
11388"                 Returns status
11389" Runs system() on
11390"    [cd REMOTEDIRPATH;] a:cmd
11391" Note that it doesn't do s:ShellEscape(a:cmd)!
11392fun! s:RemoteSystem(cmd)
11393"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
11394  if !executable(g:netrw_ssh_cmd)
11395   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
11396  elseif !exists("b:netrw_curdir")
11397   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
11398  else
11399   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
11400   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
11401   if remotedir != ""
11402    let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
11403   else
11404    let cmd= cmd.' '
11405   endif
11406   let cmd= cmd.a:cmd
11407"   call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
11408   let ret= system(cmd)
11409  endif
11410"  call Dret("s:RemoteSystem ".ret)
11411  return ret
11412endfun
11413
11414" ---------------------------------------------------------------------
11415" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
11416fun! s:RestoreWinVars()
11417"  call Dfunc("s:RestoreWinVars()")
11418  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
11419  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
11420  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
11421  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
11422  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
11423  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
11424  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
11425  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
11426  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
11427  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
11428  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
11429  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
11430  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
11431  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
11432  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
11433  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
11434  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
11435  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
11436"  call Dret("s:RestoreWinVars")
11437endfun
11438
11439" ---------------------------------------------------------------------
11440" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
11441"
11442"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
11443"             is true) and a command, :Rexplore, which call this function.
11444"
11445"             s:nbcd_curpos_{bufnr('%')} is set up by s:NetrwBrowseChgDir()
11446"
11447"             s:rexposn_BUFNR used to save/restore cursor position
11448fun! s:NetrwRexplore(islocal,dirname)
11449  if exists("s:netrwdrag")
11450   return
11451  endif
11452"  call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir.">")
11453"  call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
11454"  call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
11455
11456  if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
11457   " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
11458"   call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
11459   exe "NetrwKeepj e ".w:netrw_rexfile
11460   unlet w:netrw_rexfile
11461"   call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%").">  (ft=".&ft.")")
11462   return
11463"  else " Decho
11464"   call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
11465"   call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
11466  endif
11467
11468  " ---------------------------
11469  " :Rex issued while in a file
11470  " ---------------------------
11471
11472  " record current file so :Rex can return to it from netrw
11473  let w:netrw_rexfile= expand("%")
11474"  call Decho("set w:netrw_rexfile<".w:netrw_rexfile.">  (win#".winnr().")",'~'.expand("<slnum>"))
11475
11476  if !exists("w:netrw_rexlocal")
11477"   call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft.")")
11478   return
11479  endif
11480"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
11481  if w:netrw_rexlocal
11482   NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
11483  else
11484   NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
11485  endif
11486  if exists("s:initbeval")
11487   setl beval
11488  endif
11489  if exists("s:rexposn_".bufnr("%"))
11490"   call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
11491   " restore position in directory listing
11492   NetrwKeepj call netrw#RestorePosn(s:rexposn_{bufnr('%')})
11493   if exists("s:rexposn_".bufnr('%'))
11494    unlet s:rexposn_{bufnr('%')}
11495   endif
11496  else
11497"   call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
11498  endif
11499
11500  if exists("s:explore_match")
11501   exe "2match netrwMarkFile /".s:explore_match."/"
11502  endif
11503
11504"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
11505"  call Dret("s:NetrwRexplore : ft=".&ft)
11506endfun
11507
11508" ---------------------------------------------------------------------
11509" s:SaveBufVars: save selected b: variables to s: variables {{{2
11510"                use s:RestoreBufVars() to restore b: variables from s: variables
11511fun! s:SaveBufVars()
11512"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
11513
11514  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
11515  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
11516  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
11517  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
11518  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
11519  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
11520
11521"  call Dret("s:SaveBufVars")
11522endfun
11523
11524" ---------------------------------------------------------------------
11525" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
11526fun! s:SaveWinVars()
11527"  call Dfunc("s:SaveWinVars() win#".winnr())
11528  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
11529  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
11530  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
11531  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
11532  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
11533  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
11534  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
11535  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
11536  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
11537  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
11538  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
11539  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
11540  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
11541  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
11542  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
11543  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
11544  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
11545  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
11546"  call Dret("s:SaveWinVars")
11547endfun
11548
11549" ---------------------------------------------------------------------
11550" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
11551"   To allow separate windows to have their own activities, such as
11552"   Explore **/pattern, several variables have been made window-oriented.
11553"   However, when the user splits a browser window (ex: ctrl-w s), these
11554"   variables are not inherited by the new window.  SetBufWinVars() and
11555"   UseBufWinVars() get around that.
11556fun! s:SetBufWinVars()
11557"  call Dfunc("s:SetBufWinVars() win#".winnr())
11558  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
11559  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
11560  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
11561  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
11562  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
11563  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
11564  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
11565  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
11566  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
11567  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
11568"  call Dret("s:SetBufWinVars")
11569endfun
11570
11571" ---------------------------------------------------------------------
11572" s:SetRexDir: set directory for :Rexplore {{{2
11573fun! s:SetRexDir(islocal,dirname)
11574"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">)")
11575  let w:netrw_rexdir         = a:dirname
11576  let w:netrw_rexlocal       = a:islocal
11577  let s:rexposn_{bufnr("%")} = netrw#SavePosn()
11578"  call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to SavePosn",'~'.expand("<slnum>"))
11579"  call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
11580endfun
11581
11582" ---------------------------------------------------------------------
11583" s:ShowLink: used to modify thin and tree listings to show links {{{2
11584fun! s:ShowLink()
11585" "  call Dfunc("s:ShowLink()")
11586" "  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
11587" "  call Decho(printf("line#%4d: %s",line("."),getline(".")),'~'.expand("<slnum>"))
11588  if exists("b:netrw_curdir")
11589   norm! $?\a
11590   let fname   = b:netrw_curdir.'/'.s:NetrwGetWord()
11591   let resname = resolve(fname)
11592" "   call Decho("fname         <".fname.">",'~'.expand("<slnum>"))
11593" "   call Decho("resname       <".resname.">",'~'.expand("<slnum>"))
11594" "   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
11595   if resname =~ '^\M'.b:netrw_curdir.'/'
11596    let dirlen  = strlen(b:netrw_curdir)
11597    let resname = strpart(resname,dirlen+1)
11598" "    call Decho("resname<".resname.">  (b:netrw_curdir elided)",'~'.expand("<slnum>"))
11599   endif
11600   let modline = getline(".")."\t --> ".resname
11601" "   call Decho("fname  <".fname.">",'~'.expand("<slnum>"))
11602" "   call Decho("modline<".modline.">",'~'.expand("<slnum>"))
11603   setl noro ma
11604   call setline(".",modline)
11605   setl ro noma nomod
11606  endif
11607" "  call Dret("s:ShowLink".((exists("fname")? ' : '.fname : 'n/a')))
11608endfun
11609
11610" ---------------------------------------------------------------------
11611" s:ShowStyle: {{{2
11612fun! s:ShowStyle()
11613  if !exists("w:netrw_liststyle")
11614   let liststyle= g:netrw_liststyle
11615  else
11616   let liststyle= w:netrw_liststyle
11617  endif
11618  if     liststyle == s:THINLIST
11619   return s:THINLIST.":thin"
11620  elseif liststyle == s:LONGLIST
11621   return s:LONGLIST.":long"
11622  elseif liststyle == s:WIDELIST
11623   return s:WIDELIST.":wide"
11624  elseif liststyle == s:TREELIST
11625   return s:TREELIST.":tree"
11626  else
11627   return 'n/a'
11628  endif
11629endfun
11630
11631" ---------------------------------------------------------------------
11632" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
11633"           Solution from Nicolai Weibull, vim docs (:help strlen()),
11634"           Tony Mechelynck, and my own invention.
11635fun! s:Strlen(x)
11636"  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
11637
11638  if v:version >= 703 && exists("*strdisplaywidth")
11639   let ret= strdisplaywidth(a:x)
11640
11641  elseif type(g:Align_xstrlen) == 1
11642   " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
11643   exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
11644
11645  elseif g:Align_xstrlen == 1
11646   " number of codepoints (Latin a + combining circumflex is two codepoints)
11647   " (comment from TM, solution from NW)
11648   let ret= strlen(substitute(a:x,'.','c','g'))
11649
11650  elseif g:Align_xstrlen == 2
11651   " number of spacing codepoints (Latin a + combining circumflex is one spacing
11652   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
11653   " (comment from TM, solution from TM)
11654   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
11655
11656  elseif g:Align_xstrlen == 3
11657   " virtual length (counting, for instance, tabs as anything between 1 and
11658   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
11659   " preceded by lam, one otherwise, etc.)
11660   " (comment from TM, solution from me)
11661   let modkeep= &l:mod
11662   exe "norm! o\<esc>"
11663   call setline(line("."),a:x)
11664   let ret= virtcol("$") - 1
11665   d
11666   NetrwKeepj norm! k
11667   let &l:mod= modkeep
11668
11669  else
11670   " at least give a decent default
11671    let ret= strlen(a:x)
11672  endif
11673"  "" call Dret("s:Strlen ".ret)
11674  return ret
11675endfun
11676
11677" ---------------------------------------------------------------------
11678" s:ShellEscape: shellescape(), or special windows handling {{{2
11679fun! s:ShellEscape(s, ...)
11680  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
11681    return printf('"%s"', substitute(a:s, '"', '""', 'g'))
11682  endif
11683  let f = a:0 > 0 ? a:1 : 0
11684  return shellescape(a:s, f)
11685endfun
11686
11687" ---------------------------------------------------------------------
11688" s:TreeListMove: {{{2
11689fun! s:TreeListMove(dir)
11690"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
11691  let curline  = getline('.')
11692  let prvline  = (line(".") > 1)?         getline(line(".")-1) : ''
11693  let nxtline  = (line(".") < line("$"))? getline(line(".")+1) : ''
11694  let curindent= substitute(curline,'^\([| ]*\).\{-}$','\1','')
11695  let indentm1 = substitute(curindent,'^'.s:treedepthstring.' ','','')
11696"  call Decho("prvline  <".prvline."> #".line(".")-1,'~'.expand("<slnum>"))
11697"  call Decho("curline  <".curline."> #".line("."),'~'.expand("<slnum>"))
11698"  call Decho("nxtline  <".nxtline."> #".line(".")+1,'~'.expand("<slnum>"))
11699"  call Decho("curindent<".curindent.">",'~'.expand("<slnum>"))
11700"  call Decho("indentm1 <".indentm1.">",'~'.expand("<slnum>"))
11701
11702  if curline !~ '/$'
11703"   call Decho('regfile','~'.expand("<slnum>"))
11704   if     a:dir == '[' && prvline != ''
11705    NetrwKeepj norm! 0
11706    let nl = search('^'.indentm1.'[^'.s:treedepthstring.']','bWe')    " search backwards from regular file
11707"    call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
11708   elseif a:dir == ']' && nxtline != ''
11709    NetrwKeepj norm! $
11710    let nl = search('^'.indentm1.'[^'.s:treedepthstring.']','We')     " search forwards from regular file
11711"    call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
11712   endif
11713
11714  elseif a:dir == '[' && prvline != ''
11715   NetrwKeepj norm! 0
11716   let curline= line(".")
11717   let nl     = search('^'.curindent.'[^'.s:treedepthstring.']','bWe') " search backwards From directory, same indentation
11718"   call Decho("dir srch back ind: ".nl,'~'.expand("<slnum>"))
11719   if nl != 0
11720    if line(".") == curline-1
11721     let nl= search('^'.indentm1.'[^'.s:treedepthstring.']','bWe')     " search backwards from directory, indentation - 1
11722"     call Decho("dir srch back ind-1: ".nl,'~'.expand("<slnum>"))
11723    endif
11724   endif
11725
11726  elseif a:dir == ']' && nxtline != ''
11727   NetrwKeepj norm! $
11728   let curline = line(".")
11729   let nl      = search('^'.curindent.'[^'.s:treedepthstring.']','We') " search forwards from directory, same indentation
11730"   call Decho("dir srch fwd ind: ".nl,'~'.expand("<slnum>"))
11731   if nl != 0
11732    if line(".") == curline+1
11733     let nl= search('^'.indentm1.'[^'.s:treedepthstring.']','We')         " search forwards from directory, indentation - 1
11734"     call Decho("dir srch fwd ind-1: ".nl,'~'.expand("<slnum>"))
11735    endif
11736   endif
11737
11738  endif
11739
11740"  call Dret("s:TreeListMove")
11741endfun
11742
11743" ---------------------------------------------------------------------
11744" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
11745"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
11746"                      can't be called except via emenu.  But due to locale, that menu line may not be called
11747"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
11748fun! s:UpdateBuffersMenu()
11749"  call Dfunc("s:UpdateBuffersMenu()")
11750  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
11751   try
11752    sil emenu Buffers.Refresh\ menu
11753   catch /^Vim\%((\a\+)\)\=:E/
11754    let v:errmsg= ""
11755    sil NetrwKeepj call s:NetrwBMShow()
11756   endtry
11757  endif
11758"  call Dret("s:UpdateBuffersMenu")
11759endfun
11760
11761" ---------------------------------------------------------------------
11762" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
11763"              Matching function to s:SetBufWinVars()
11764fun! s:UseBufWinVars()
11765"  call Dfunc("s:UseBufWinVars()")
11766  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
11767  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
11768  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
11769  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
11770  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
11771  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
11772  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11773  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11774  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
11775  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
11776"  call Dret("s:UseBufWinVars")
11777endfun
11778
11779" ---------------------------------------------------------------------
11780" s:UserMaps: supports user-defined UserMaps {{{2
11781"               * calls a user-supplied funcref(islocal,curdir)
11782"               * interprets result
11783"             See netrw#UserMaps()
11784fun! s:UserMaps(islocal,funcname)
11785"  call Dfunc("s:UserMaps(islocal=".a:islocal.",funcname<".a:funcname.">)")
11786
11787  if !exists("b:netrw_curdir")
11788   let b:netrw_curdir= getcwd()
11789  endif
11790  let Funcref = function(a:funcname)
11791  let result  = Funcref(a:islocal)
11792
11793  if     type(result) == 1
11794   " if result from user's funcref is a string...
11795"   call Decho("result string from user funcref<".result.">",'~'.expand("<slnum>"))
11796   if result == "refresh"
11797"    call Decho("refreshing display",'~'.expand("<slnum>"))
11798    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
11799   elseif result != ""
11800"    call Decho("executing result<".result.">",'~'.expand("<slnum>"))
11801    exe result
11802   endif
11803
11804  elseif type(result) == 3
11805   " if result from user's funcref is a List...
11806"   call Decho("result List from user funcref<".string(result).">",'~'.expand("<slnum>"))
11807   for action in result
11808    if action == "refresh"
11809"     call Decho("refreshing display",'~'.expand("<slnum>"))
11810     call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
11811    elseif action != ""
11812"     call Decho("executing action<".action.">",'~'.expand("<slnum>"))
11813     exe action
11814    endif
11815   endfor
11816  endif
11817
11818"  call Dret("s:UserMaps")
11819endfun
11820
11821" ---------------------------------------------------------------------
11822" Settings Restoration: {{{1
11823let &cpo= s:keepcpo
11824unlet s:keepcpo
11825
11826" ------------------------------------------------------------------------
11827" Modelines: {{{1
11828" vim:ts=8 fdm=marker
11829