xref: /vim-8.2.3635/runtime/autoload/netrw.vim (revision a0122dcd)
1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		Sep 18, 2020
4" Version:	170
5" Maintainer:	Charles E Campbell <[email protected]>
6" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
7" Copyright:    Copyright (C) 2016 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"
17" Note: the code here was started in 1999 under a much earlier version of vim.  The directory browsing
18"       code was written using vim v6, which did not have Lists (Lists were first offered with vim-v7).
19"
20"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
21"
22"  But be doers of the Word, and not only hearers, deluding your own selves {{{1
23"  (James 1:22 RSV)
24" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
25" Load Once: {{{1
26if &cp || exists("g:loaded_netrw")
27  finish
28endif
29
30" Check that vim has patches that netrw requires.
31" Patches needed for v7.4: 1557, and 213.
32" (netrw will benefit from vim's having patch#656, too)
33let s:needspatches=[1557,213]
34if exists("s:needspatches")
35 for ptch in s:needspatches
36  if v:version < 704 || (v:version == 704 && !has("patch".ptch))
37   if !exists("s:needpatch{ptch}")
38    unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch#".ptch
39   endif
40   let s:needpatch{ptch}= 1
41   finish
42  endif
43 endfor
44endif
45
46let g:loaded_netrw = "v170"
47if !exists("s:NOTE")
48 let s:NOTE    = 0
49 let s:WARNING = 1
50 let s:ERROR   = 2
51endif
52
53let s:keepcpo= &cpo
54setl cpo&vim
55"DechoFuncName 1
56"DechoRemOn
57"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw,'~'.expand("<slnum>"))
58
59" ======================
60"  Netrw Variables: {{{1
61" ======================
62
63" ---------------------------------------------------------------------
64" netrw#ErrorMsg: {{{2
65"   0=note     = s:NOTE
66"   1=warning  = s:WARNING
67"   2=error    = s:ERROR
68"   Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number)
69"          netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number)
70"          (this function can optionally take a list of messages)
71"  Dec 2, 2019 : max errnum currently is 106
72fun! netrw#ErrorMsg(level,msg,errnum)
73"  call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
74
75  if a:level < g:netrw_errorlvl
76"   call Dret("netrw#ErrorMsg : suppressing level=".a:level." since g:netrw_errorlvl=".g:netrw_errorlvl)
77   return
78  endif
79
80  if a:level == 1
81   let level= "**warning** (netrw) "
82  elseif a:level == 2
83   let level= "**error** (netrw) "
84  else
85   let level= "**note** (netrw) "
86  endif
87"  call Decho("level=".level,'~'.expand("<slnum>"))
88
89  if g:netrw_use_errorwindow == 2 && (v:version > 802 || (v:version == 802 && has("patch486")))
90   " use popup window
91   if type(a:msg) == 3
92    let msg = [level]+a:msg
93   else
94    let msg= level.a:msg
95   endif
96   let s:popuperr_id  = popup_beval(msg,{})
97   let s:popuperr_text= ""
98 elseif g:netrw_use_errorwindow
99   " (default) netrw creates a one-line window to show error/warning
100   " messages (reliably displayed)
101
102   " record current window number
103   let s:winBeforeErr= winnr()
104"   call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>"))
105
106   " getting messages out reliably is just plain difficult!
107   " This attempt splits the current window, creating a one line window.
108   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
109"    call Decho("write to NetrwMessage buffer",'~'.expand("<slnum>"))
110    exe bufwinnr("NetrwMessage")."wincmd w"
111"    call Decho("setl ma noro",'~'.expand("<slnum>"))
112    setl ma noro
113    if type(a:msg) == 3
114     for msg in a:msg
115      NetrwKeepj call setline(line("$")+1,level.msg)
116     endfor
117    else
118     NetrwKeepj call setline(line("$")+1,level.a:msg)
119    endif
120    NetrwKeepj $
121   else
122"    call Decho("create a NetrwMessage buffer window",'~'.expand("<slnum>"))
123    bo 1split
124    sil! call s:NetrwEnew()
125    sil! NetrwKeepj call s:NetrwOptionsSafe(1)
126    setl bt=nofile
127    NetrwKeepj file NetrwMessage
128"    call Decho("setl ma noro",'~'.expand("<slnum>"))
129    setl ma noro
130    if type(a:msg) == 3
131     for msg in a:msg
132      NetrwKeepj call setline(line("$")+1,level.msg)
133     endfor
134    else
135     NetrwKeepj call setline(line("$"),level.a:msg)
136    endif
137    NetrwKeepj $
138   endif
139"   call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr(),'~'.expand("<slnum>"))
140   if &fo !~ '[ta]'
141    syn clear
142    syn match netrwMesgNote	"^\*\*note\*\*"
143    syn match netrwMesgWarning	"^\*\*warning\*\*"
144    syn match netrwMesgError	"^\*\*error\*\*"
145    hi link netrwMesgWarning WarningMsg
146    hi link netrwMesgError   Error
147   endif
148"   call Decho("setl noma ro bh=wipe",'~'.expand("<slnum>"))
149   setl ro nomod noma bh=wipe
150
151  else
152   " (optional) netrw will show messages using echomsg.  Even if the
153   " message doesn't appear, at least it'll be recallable via :messages
154"   redraw!
155   if a:level == s:WARNING
156    echohl WarningMsg
157   elseif a:level == s:ERROR
158    echohl Error
159   endif
160
161   if type(a:msg) == 3
162     for msg in a:msg
163      unsilent echomsg level.msg
164     endfor
165   else
166    unsilent echomsg level.a:msg
167   endif
168
169"   call Decho("echomsg ***netrw*** ".a:msg,'~'.expand("<slnum>"))
170   echohl None
171  endif
172
173"  call Dret("netrw#ErrorMsg")
174endfun
175
176" ---------------------------------------------------------------------
177" s:NetrwInit: initializes variables if they haven't been defined {{{2
178"            Loosely,  varname = value.
179fun s:NetrwInit(varname,value)
180" call Decho("varname<".a:varname."> value=".a:value,'~'.expand("<slnum>"))
181  if !exists(a:varname)
182   if type(a:value) == 0
183    exe "let ".a:varname."=".a:value
184   elseif type(a:value) == 1 && a:value =~ '^[{[]'
185    exe "let ".a:varname."=".a:value
186   elseif type(a:value) == 1
187    exe "let ".a:varname."="."'".a:value."'"
188   else
189    exe "let ".a:varname."=".a:value
190   endif
191  endif
192endfun
193
194" ---------------------------------------------------------------------
195"  Netrw Constants: {{{2
196call s:NetrwInit("g:netrw_dirhistcnt",0)
197if !exists("s:LONGLIST")
198 call s:NetrwInit("s:THINLIST",0)
199 call s:NetrwInit("s:LONGLIST",1)
200 call s:NetrwInit("s:WIDELIST",2)
201 call s:NetrwInit("s:TREELIST",3)
202 call s:NetrwInit("s:MAXLIST" ,4)
203endif
204
205" ---------------------------------------------------------------------
206" Default option values: {{{2
207let g:netrw_localcopycmdopt    = ""
208let g:netrw_localcopydircmdopt = ""
209let g:netrw_localmkdiropt      = ""
210let g:netrw_localmovecmdopt    = ""
211let g:netrw_localrmdiropt      = ""
212
213" ---------------------------------------------------------------------
214" Default values for netrw's global protocol variables {{{2
215if (v:version > 802 || (v:version == 802 && has("patch486"))) && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on") && has("mouse")
216  call s:NetrwInit("g:netrw_use_errorwindow",2)
217else
218  call s:NetrwInit("g:netrw_use_errorwindow",1)
219endif
220
221if !exists("g:netrw_dav_cmd")
222 if executable("cadaver")
223  let g:netrw_dav_cmd	= "cadaver"
224 elseif executable("curl")
225  let g:netrw_dav_cmd	= "curl"
226 else
227  let g:netrw_dav_cmd   = ""
228 endif
229endif
230if !exists("g:netrw_fetch_cmd")
231 if executable("fetch")
232  let g:netrw_fetch_cmd	= "fetch -o"
233 else
234  let g:netrw_fetch_cmd	= ""
235 endif
236endif
237if !exists("g:netrw_file_cmd")
238 if executable("elinks")
239  call s:NetrwInit("g:netrw_file_cmd","elinks")
240 elseif executable("links")
241  call s:NetrwInit("g:netrw_file_cmd","links")
242 endif
243endif
244if !exists("g:netrw_ftp_cmd")
245  let g:netrw_ftp_cmd	= "ftp"
246endif
247let s:netrw_ftp_cmd= g:netrw_ftp_cmd
248if !exists("g:netrw_ftp_options")
249 let g:netrw_ftp_options= "-i -n"
250endif
251if !exists("g:netrw_http_cmd")
252 if executable("wget")
253  let g:netrw_http_cmd	= "wget"
254  call s:NetrwInit("g:netrw_http_xcmd","-q -O")
255 elseif executable("curl")
256  let g:netrw_http_cmd	= "curl"
257  call s:NetrwInit("g:netrw_http_xcmd","-L -o")
258 elseif executable("elinks")
259  let g:netrw_http_cmd = "elinks"
260  call s:NetrwInit("g:netrw_http_xcmd","-source >")
261 elseif executable("fetch")
262  let g:netrw_http_cmd	= "fetch"
263  call s:NetrwInit("g:netrw_http_xcmd","-o")
264 elseif executable("links")
265  let g:netrw_http_cmd = "links"
266  call s:NetrwInit("g:netrw_http_xcmd","-http.extra-header ".shellescape("Accept-Encoding: identity", 1)." -source >")
267 else
268  let g:netrw_http_cmd	= ""
269 endif
270endif
271call s:NetrwInit("g:netrw_http_put_cmd","curl -T")
272call s:NetrwInit("g:netrw_keepj","keepj")
273call s:NetrwInit("g:netrw_rcp_cmd"  , "rcp")
274call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
275call s:NetrwInit("g:netrw_rsync_sep", "/")
276if !exists("g:netrw_scp_cmd")
277 if executable("scp")
278  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
279 elseif executable("pscp")
280  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable('c:\private.ppk')
281   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -i c:\private.ppk')
282  else
283   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
284  endif
285 else
286  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
287 endif
288endif
289
290call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
291call s:NetrwInit("g:netrw_ssh_cmd"  , "ssh")
292
293if (has("win32") || has("win95") || has("win64") || has("win16"))
294  \ && exists("g:netrw_use_nt_rcp")
295  \ && g:netrw_use_nt_rcp
296  \ && executable( $SystemRoot .'/system32/rcp.exe')
297 let s:netrw_has_nt_rcp = 1
298 let s:netrw_rcpmode    = '-b'
299else
300 let s:netrw_has_nt_rcp = 0
301 let s:netrw_rcpmode    = ''
302endif
303
304" ---------------------------------------------------------------------
305" Default values for netrw's global variables {{{2
306" Cygwin Detection ------- {{{3
307if !exists("g:netrw_cygwin")
308 if has("win32") || has("win95") || has("win64") || has("win16")
309  if  has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
310   let g:netrw_cygwin= 1
311  else
312   let g:netrw_cygwin= 0
313  endif
314 else
315  let g:netrw_cygwin= 0
316 endif
317endif
318" Default values - a-c ---------- {{{3
319call s:NetrwInit("g:netrw_alto"        , &sb)
320call s:NetrwInit("g:netrw_altv"        , &spr)
321call s:NetrwInit("g:netrw_banner"      , 1)
322call s:NetrwInit("g:netrw_browse_split", 0)
323call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro nornu")
324call s:NetrwInit("g:netrw_chgwin"      , -1)
325call s:NetrwInit("g:netrw_compress"    , "gzip")
326call s:NetrwInit("g:netrw_ctags"       , "ctags")
327if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
328 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
329 let g:netrw_cursor= g:netrw_cursorline
330endif
331call s:NetrwInit("g:netrw_cursor"      , 2)
332let s:netrw_usercul = &cursorline
333let s:netrw_usercuc = &cursorcolumn
334call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
335" Default values - d-g ---------- {{{3
336call s:NetrwInit("s:didstarstar",0)
337call s:NetrwInit("g:netrw_dirhistcnt"      , 0)
338call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }')
339call s:NetrwInit("g:netrw_dirhistmax"       , 10)
340call s:NetrwInit("g:netrw_errorlvl"  , s:NOTE)
341call s:NetrwInit("g:netrw_fastbrowse"       , 1)
342call 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$')
343if !exists("g:netrw_ftp_list_cmd")
344 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
345  let g:netrw_ftp_list_cmd     = "ls -lF"
346  let g:netrw_ftp_timelist_cmd = "ls -tlF"
347  let g:netrw_ftp_sizelist_cmd = "ls -slF"
348 else
349  let g:netrw_ftp_list_cmd     = "dir"
350  let g:netrw_ftp_timelist_cmd = "dir"
351  let g:netrw_ftp_sizelist_cmd = "dir"
352 endif
353endif
354call s:NetrwInit("g:netrw_ftpmode",'binary')
355" Default values - h-lh ---------- {{{3
356call s:NetrwInit("g:netrw_hide",1)
357if !exists("g:netrw_ignorenetrc")
358 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
359  let g:netrw_ignorenetrc= 1
360 else
361  let g:netrw_ignorenetrc= 0
362 endif
363endif
364call s:NetrwInit("g:netrw_keepdir",1)
365if !exists("g:netrw_list_cmd")
366 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
367  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
368   " provide a pscp-based listing command
369   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
370  endif
371  if exists("g:netrw_list_cmd_options")
372   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
373  else
374   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
375  endif
376 elseif executable(g:netrw_ssh_cmd)
377  " provide a scp-based default listing command
378  if exists("g:netrw_list_cmd_options")
379   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
380  else
381   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
382  endif
383 else
384"  call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
385  let g:netrw_list_cmd= ""
386 endif
387endif
388call s:NetrwInit("g:netrw_list_hide","")
389" Default values - lh-lz ---------- {{{3
390if exists("g:netrw_local_copycmd")
391 let g:netrw_localcopycmd= g:netrw_local_copycmd
392 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_copycmd is deprecated in favor of g:netrw_localcopycmd",84)
393endif
394if !exists("g:netrw_localcmdshell")
395 let g:netrw_localcmdshell= ""
396endif
397if !exists("g:netrw_localcopycmd")
398 if has("win32") || has("win95") || has("win64") || has("win16")
399  if g:netrw_cygwin
400   let g:netrw_localcopycmd= "cp"
401  else
402   let g:netrw_localcopycmd   = expand("$COMSPEC")
403   let g:netrw_localcopycmdopt= " /c copy"
404  endif
405 elseif has("unix") || has("macunix")
406  let g:netrw_localcopycmd= "cp"
407 else
408  let g:netrw_localcopycmd= ""
409 endif
410endif
411if !exists("g:netrw_localcopydircmd")
412 if has("win32") || has("win95") || has("win64") || has("win16")
413  if g:netrw_cygwin
414   let g:netrw_localcopydircmd   = "cp"
415   let g:netrw_localcopydircmdopt= " -R"
416  else
417   let g:netrw_localcopydircmd   = expand("$COMSPEC")
418   let g:netrw_localcopydircmdopt= " /c xcopy /e /c /h /i /k"
419  endif
420 elseif has("unix")
421  let g:netrw_localcopydircmd   = "cp"
422  let g:netrw_localcopydircmdopt= " -R"
423 elseif has("macunix")
424  let g:netrw_localcopydircmd   = "cp"
425  let g:netrw_localcopydircmdopt= " -R"
426 else
427  let g:netrw_localcopydircmd= ""
428 endif
429endif
430if exists("g:netrw_local_mkdir")
431 let g:netrw_localmkdir= g:netrw_local_mkdir
432 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
433endif
434if has("win32") || has("win95") || has("win64") || has("win16")
435  if g:netrw_cygwin
436   call s:NetrwInit("g:netrw_localmkdir","mkdir")
437  else
438   let g:netrw_localmkdir   = expand("$COMSPEC")
439   let g:netrw_localmkdiropt= " /c mkdir"
440  endif
441else
442 call s:NetrwInit("g:netrw_localmkdir","mkdir")
443endif
444call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
445if exists("g:netrw_local_movecmd")
446 let g:netrw_localmovecmd= g:netrw_local_movecmd
447 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
448endif
449if !exists("g:netrw_localmovecmd")
450 if has("win32") || has("win95") || has("win64") || has("win16")
451  if g:netrw_cygwin
452   let g:netrw_localmovecmd= "mv"
453  else
454   let g:netrw_localmovecmd   = expand("$COMSPEC")
455   let g:netrw_localmovecmdopt= " /c move"
456  endif
457 elseif has("unix") || has("macunix")
458  let g:netrw_localmovecmd= "mv"
459 else
460  let g:netrw_localmovecmd= ""
461 endif
462endif
463" following serves as an example for how to insert a version&patch specific test
464"if v:version < 704 || (v:version == 704 && !has("patch1107"))
465"endif
466call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
467" sanity checks
468if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
469 let g:netrw_liststyle= s:THINLIST
470endif
471if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
472 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
473endif
474" Default values - m-r ---------- {{{3
475call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
476call s:NetrwInit("g:netrw_maxfilenamelen", 32)
477call s:NetrwInit("g:netrw_menu"          , 1)
478call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
479call s:NetrwInit("g:netrw_mousemaps"     , (exists("+mouse") && &mouse =~# '[anh]'))
480call s:NetrwInit("g:netrw_retmap"        , 0)
481if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
482 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
483elseif has("win32") || has("win95") || has("win64") || has("win16")
484 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
485else
486 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
487endif
488call s:NetrwInit("g:netrw_preview"       , 0)
489call s:NetrwInit("g:netrw_scpport"       , "-P")
490call s:NetrwInit("g:netrw_servername"    , "NETRWSERVER")
491call s:NetrwInit("g:netrw_sshport"       , "-p")
492call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
493call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
494call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
495call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
496" Default values - q-s ---------- {{{3
497call s:NetrwInit("g:netrw_quickhelp",0)
498let s:QuickHelp= ["-:go up dir  D:delete  R:rename  s:sort-by  x:special",
499   \              "(create new)  %:file  d:directory",
500   \              "(windows split&open) o:horz  v:vert  p:preview",
501   \              "i:style  qf:file info  O:obtain  r:reverse",
502   \              "(marks)  mf:mark file  mt:set target  mm:move  mc:copy",
503   \              "(bookmarks)  mb:make  mB:delete  qb:list  gb:go to",
504   \              "(history)  qb:list  u:go up  U:go down",
505   \              "(targets)  mt:target Tb:use bookmark  Th:use history"]
506" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
507call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
508if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
509 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
510else
511 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
512endif
513call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
514call s:NetrwInit("g:netrw_sort_options"  , "")
515call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
516if !exists("g:netrw_sort_sequence")
517 if has("unix")
518  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
519 else
520  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
521 endif
522endif
523call s:NetrwInit("g:netrw_special_syntax"   , 0)
524call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
525call s:NetrwInit("g:netrw_suppress_gx_mesg",  1)
526call s:NetrwInit("g:netrw_use_noswf"        , 1)
527call s:NetrwInit("g:netrw_sizestyle"        ,"b")
528" Default values - t-w ---------- {{{3
529call s:NetrwInit("g:netrw_timefmt","%c")
530if !exists("g:netrw_xstrlen")
531 if exists("g:Align_xstrlen")
532  let g:netrw_xstrlen= g:Align_xstrlen
533 elseif exists("g:drawit_xstrlen")
534  let g:netrw_xstrlen= g:drawit_xstrlen
535 elseif &enc == "latin1" || !has("multi_byte")
536  let g:netrw_xstrlen= 0
537 else
538  let g:netrw_xstrlen= 1
539 endif
540endif
541call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
542call s:NetrwInit("g:netrw_win95ftp",1)
543call s:NetrwInit("g:netrw_winsize",50)
544call s:NetrwInit("g:netrw_wiw",1)
545if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
546" ---------------------------------------------------------------------
547" Default values for netrw's script variables: {{{2
548call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
549if has("win32") || has("win95") || has("win64") || has("win16")
550 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
551else
552 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
553endif
554call s:NetrwInit("g:netrw_menu_escape",'.&? \')
555call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
556call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
557if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
558 let s:treedepthstring= "│ "
559else
560 let s:treedepthstring= "| "
561endif
562call s:NetrwInit("s:netrw_posn",'{}')
563
564" BufEnter event ignored by decho when following variable is true
565"  Has a side effect that doau BufReadPost doesn't work, so
566"  files read by network transfer aren't appropriately highlighted.
567"let g:decho_bufenter = 1	"Decho
568
569" ======================
570"  Netrw Initialization: {{{1
571" ======================
572if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
573" call Decho("installed beval events",'~'.expand("<slnum>"))
574 let &l:bexpr = "netrw#BalloonHelp()"
575" call Decho("&l:bexpr<".&l:bexpr."> buf#".bufnr())
576 au FileType netrw	setl beval
577 au WinLeave *		if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
578 au VimEnter * 		let s:initbeval= &beval
579"else " Decho
580" if v:version < 700           | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>"))     | endif
581" if !has("balloon_eval")      | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>"))        | endif
582" if exists("s:initbeval")     | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>"))                | endif
583" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>"))            | endif
584" if !has("syntax")            | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
585" if exists("g:syntax_on")     | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>"))                | endif
586endif
587au WinEnter *	if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
588
589if g:netrw_keepj =~# "keepj"
590 com! -nargs=*	NetrwKeepj	keepj <args>
591else
592 let g:netrw_keepj= ""
593 com! -nargs=*	NetrwKeepj	<args>
594endif
595
596" ==============================
597"  Netrw Utility Functions: {{{1
598" ==============================
599
600" ---------------------------------------------------------------------
601" netrw#BalloonHelp: {{{2
602if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
603" call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
604 fun! netrw#BalloonHelp()
605   if &ft != "netrw"
606    return ""
607   endif
608   if exists("s:popuperr_id") && popup_getpos(s:popuperr_id) != {}
609    " popup error window is still showing
610    " s:pouperr_id and s:popuperr_text are set up in netrw#ErrorMsg()
611    if exists("s:popuperr_text") && s:popuperr_text != "" && v:beval_text != s:popuperr_text
612     " text under mouse hasn't changed; only close window when it changes
613     call popup_close(s:popuperr_id)
614     unlet s:popuperr_text
615    else
616     let s:popuperr_text= v:beval_text
617    endif
618    let mesg= ""
619   elseif !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
620    let mesg= ""
621   elseif     v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
622    let mesg = "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
623   elseif     getline(v:beval_lnum) =~ '^"\s*/'
624    let mesg = "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
625   elseif     v:beval_text == "Sorted" || v:beval_text == "by"
626    let mesg = 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
627   elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
628    let mesg = "S: edit sorting sequence"
629   elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
630    let mesg = "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
631   elseif v:beval_text == "Quick" || v:beval_text == "Help"
632    let mesg = "Help: press <F1>"
633   elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
634    let mesg = "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
635   else
636    let mesg= ""
637   endif
638   return mesg
639 endfun
640"else " Decho
641" if v:version < 700            |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
642" if !has("balloon_eval")       |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>"))       |endif
643" if !has("syntax")             |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>"))                  |endif
644" if !exists("g:syntax_on")     |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>"))                  |endif
645" if  exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>"))           |endif
646endif
647
648" ------------------------------------------------------------------------
649" netrw#Explore: launch the local browser in the directory of the current file {{{2
650"          indx:  == -1: Nexplore
651"                 == -2: Pexplore
652"                 ==  +: this is overloaded:
653"                      * If Nexplore/Pexplore is in use, then this refers to the
654"                        indx'th item in the w:netrw_explore_list[] of items which
655"                        matched the */pattern **/pattern *//pattern **//pattern
656"                      * If Hexplore or Vexplore, then this will override
657"                        g:netrw_winsize to specify the qty of rows or columns the
658"                        newly split window should have.
659"          dosplit==0: the window will be split iff the current file has been modified and hidden not set
660"          dosplit==1: the window will be split before running the local browser
661"          style == 0: Explore     style == 1: Explore!
662"                == 2: Hexplore    style == 3: Hexplore!
663"                == 4: Vexplore    style == 5: Vexplore!
664"                == 6: Texplore
665fun! netrw#Explore(indx,dosplit,style,...)
666"  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("%")." ft=".&ft)
667"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
668  if !exists("b:netrw_curdir")
669   let b:netrw_curdir= getcwd()
670"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
671  endif
672
673  " record current file for Rexplore's benefit
674  if &ft != "netrw"
675   let w:netrw_rexfile= expand("%:p")
676  endif
677
678  " record current directory
679  let curdir     = simplify(b:netrw_curdir)
680  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
681  if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
682   let curdir= substitute(curdir,'\','/','g')
683  endif
684"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">",'~'.expand("<slnum>"))
685
686  " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
687  " will end up with backslashes here.  Solution: strip off backslashes that precede white space and
688  " try Explore again.
689  if a:0 > 0
690"   call Decho('considering retry: a:1<'.a:1.'>: '.
691     \ ((a:1 =~ "\\\s")?                   'has backslash whitespace' : 'does not have backslash whitespace').', '.
692     \ ((filereadable(s:NetrwFile(a:1)))?  'is readable'              : 'is not readable').', '.
693     \ ((isdirectory(s:NetrwFile(a:1))))?  'is a directory'           : 'is not a directory',
694     \ '~'.expand("<slnum>"))
695   if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
696"    call Decho("re-trying Explore with <".substitute(a:1,'\\\(\s\)','\1','g').">",'~'.expand("<slnum>"))
697    call netrw#Explore(a:indx,a:dosplit,a:style,substitute(a:1,'\\\(\s\)','\1','g'))
698"    call Dret("netrw#Explore : returning from retry")
699    return
700"   else " Decho
701"    call Decho("retry not needed",'~'.expand("<slnum>"))
702   endif
703  endif
704
705  " save registers
706  if has("clipboard")
707"   call Decho("(netrw#Explore) save @* and @+",'~'.expand("<slnum>"))
708   sil! let keepregstar = @*
709   sil! let keepregplus = @+
710  endif
711  sil! let keepregslash= @/
712
713  " if   dosplit
714  " -or- file has been modified AND file not hidden when abandoned
715  " -or- Texplore used
716  if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
717"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified",'~'.expand("<slnum>"))
718   call s:SaveWinVars()
719   let winsz= g:netrw_winsize
720   if a:indx > 0
721    let winsz= a:indx
722   endif
723
724   if a:style == 0      " Explore, Sexplore
725"    call Decho("style=0: Explore or Sexplore",'~'.expand("<slnum>"))
726    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
727    if winsz == 0|let winsz= ""|endif
728    exe "noswapfile ".winsz."wincmd s"
729"    call Decho("exe noswapfile ".winsz."wincmd s",'~'.expand("<slnum>"))
730
731   elseif a:style == 1  "Explore!, Sexplore!
732"    call Decho("style=1: Explore! or Sexplore!",'~'.expand("<slnum>"))
733    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
734    if winsz == 0|let winsz= ""|endif
735    exe "keepalt noswapfile ".winsz."wincmd v"
736"    call Decho("exe keepalt noswapfile ".winsz."wincmd v",'~'.expand("<slnum>"))
737
738   elseif a:style == 2  " Hexplore
739"    call Decho("style=2: Hexplore",'~'.expand("<slnum>"))
740    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
741    if winsz == 0|let winsz= ""|endif
742    exe "keepalt noswapfile bel ".winsz."wincmd s"
743"    call Decho("exe keepalt noswapfile bel ".winsz."wincmd s",'~'.expand("<slnum>"))
744
745   elseif a:style == 3  " Hexplore!
746"    call Decho("style=3: Hexplore!",'~'.expand("<slnum>"))
747    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
748    if winsz == 0|let winsz= ""|endif
749    exe "keepalt noswapfile abo ".winsz."wincmd s"
750"    call Decho("exe keepalt noswapfile abo ".winsz."wincmd s",'~'.expand("<slnum>"))
751
752   elseif a:style == 4  " Vexplore
753"    call Decho("style=4: Vexplore",'~'.expand("<slnum>"))
754    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
755    if winsz == 0|let winsz= ""|endif
756    exe "keepalt noswapfile lefta ".winsz."wincmd v"
757"    call Decho("exe keepalt noswapfile lefta ".winsz."wincmd v",'~'.expand("<slnum>"))
758
759   elseif a:style == 5  " Vexplore!
760"    call Decho("style=5: Vexplore!",'~'.expand("<slnum>"))
761    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
762    if winsz == 0|let winsz= ""|endif
763    exe "keepalt noswapfile rightb ".winsz."wincmd v"
764"    call Decho("exe keepalt noswapfile rightb ".winsz."wincmd v",'~'.expand("<slnum>"))
765
766   elseif a:style == 6  " Texplore
767    call s:SaveBufVars()
768"    call Decho("style  = 6: Texplore",'~'.expand("<slnum>"))
769    exe "keepalt tabnew ".fnameescape(curdir)
770"    call Decho("exe keepalt tabnew ".fnameescape(curdir),'~'.expand("<slnum>"))
771    call s:RestoreBufVars()
772   endif
773   call s:RestoreWinVars()
774"  else " Decho
775"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6",'~'.expand("<slnum>"))
776  endif
777  NetrwKeepj norm! 0
778
779  if a:0 > 0
780"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">",'~'.expand("<slnum>"))
781   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
782"    call Decho("..case a:1<".a:1.">: starts with ~ and unix or cygwin",'~'.expand("<slnum>"))
783    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
784"    call Decho("..using dirname<".dirname.">  (case: ~ && unix||cygwin)",'~'.expand("<slnum>"))
785   elseif a:1 == '.'
786"    call Decho("..case a:1<".a:1.">: matches .",'~'.expand("<slnum>"))
787    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
788    if dirname !~ '/$'
789     let dirname= dirname."/"
790    endif
791"    call Decho("..using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")",'~'.expand("<slnum>"))
792   elseif a:1 =~ '\$'
793"    call Decho("..case a:1<".a:1.">: matches ending $",'~'.expand("<slnum>"))
794    let dirname= simplify(expand(a:1))
795"    call Decho("..using user-specified dirname<".dirname."> with $env-var",'~'.expand("<slnum>"))
796   elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
797"    call Decho("..case a:1<".a:1.">: other, not pattern or filepattern",'~'.expand("<slnum>"))
798    let dirname= simplify(a:1)
799"    call Decho("..using user-specified dirname<".dirname.">",'~'.expand("<slnum>"))
800   else
801"    call Decho("..case a:1: pattern or filepattern",'~'.expand("<slnum>"))
802    let dirname= a:1
803   endif
804  else
805   " clear explore
806"   call Decho("case a:0=".a:0.": clearing Explore list",'~'.expand("<slnum>"))
807   call s:NetrwClearExplore()
808"   call Dret("netrw#Explore : cleared list")
809   return
810  endif
811
812"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
813  if dirname =~ '\.\./\=$'
814   let dirname= simplify(fnamemodify(dirname,':p:h'))
815  elseif dirname =~ '\.\.' || dirname == '.'
816   let dirname= simplify(fnamemodify(dirname,':p'))
817  endif
818"  call Decho("dirname<".dirname.">  (after simplify)",'~'.expand("<slnum>"))
819
820  if dirname =~ '^\*//'
821   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
822"   call Decho("case starpat=1: Explore *//pattern",'~'.expand("<slnum>"))
823   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
824   let starpat= 1
825"   call Decho("..Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
826   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
827
828  elseif dirname =~ '^\*\*//'
829   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
830"   call Decho("case starpat=2: Explore **//pattern",'~'.expand("<slnum>"))
831   let pattern= substitute(dirname,'^\*\*//','','')
832   let starpat= 2
833"   call Decho("..Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
834
835  elseif dirname =~ '/\*\*/'
836   " handle .../**/.../filepat
837"   call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
838   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
839   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
840    let b:netrw_curdir = prefixdir
841   else
842    let b:netrw_curdir= getcwd().'/'.prefixdir
843   endif
844   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
845   let starpat= 4
846"   call Decho("..pwd<".getcwd()."> dirname<".dirname.">",'~'.expand("<slnum>"))
847"   call Decho("..case Explore ../**/../filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
848
849  elseif dirname =~ '^\*/'
850   " case starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
851   let starpat= 3
852"   call Decho("case starpat=3: Explore */filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
853
854  elseif dirname=~ '^\*\*/'
855   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
856   let starpat= 4
857"   call Decho("case starpat=4: Explore **/filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
858
859  else
860   let starpat= 0
861"   call Decho("case starpat=0: default",'~'.expand("<slnum>"))
862  endif
863
864  if starpat == 0 && a:indx >= 0
865   " [Explore Hexplore Vexplore Sexplore] [dirname]
866"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname.">, handles Explore Hexplore Vexplore Sexplore",'~'.expand("<slnum>"))
867   if dirname == ""
868    let dirname= curfiledir
869"    call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>"))
870   endif
871   if dirname =~# '^scp://' || dirname =~ '^ftp://'
872    call netrw#Nread(2,dirname)
873   else
874    if dirname == ""
875     let dirname= getcwd()
876    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
877     " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
878     " depending on whether backslashes have been converted to forward slashes by earlier code).
879     if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
880      let dirname= b:netrw_curdir."/".dirname
881     endif
882    elseif dirname !~ '^/'
883     let dirname= b:netrw_curdir."/".dirname
884    endif
885"    call Decho("..calling LocalBrowseCheck(dirname<".dirname.">)",'~'.expand("<slnum>"))
886    call netrw#LocalBrowseCheck(dirname)
887"    call Decho(" modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
888"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
889   endif
890   if exists("w:netrw_bannercnt")
891    " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
892    " If one wants to return the same place in the netrw window, use :Rex instead.
893    exe w:netrw_bannercnt
894   endif
895
896"   call Decho("curdir<".curdir.">",'~'.expand("<slnum>"))
897   " ---------------------------------------------------------------------
898   " Jan 24, 2013: not sure why the following was present.  See P08-Ingelrest
899"   if has("win32") || has("win95") || has("win64") || has("win16")
900"    NetrwKeepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
901"   else
902"    NetrwKeepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
903"   endif
904   " ---------------------------------------------------------------------
905
906  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
907  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
908  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
909  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
910  elseif a:indx <= 0
911   " Nexplore, Pexplore, Explore: handle starpat
912"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx,'~'.expand("<slnum>"))
913   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
914"    call Decho("..set up <s-up> and <s-down> maps",'~'.expand("<slnum>"))
915    let s:didstarstar= 1
916    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
917    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
918   endif
919
920   if has("path_extra")
921"    call Decho("..starpat=".starpat.": has +path_extra",'~'.expand("<slnum>"))
922    if !exists("w:netrw_explore_indx")
923     let w:netrw_explore_indx= 0
924    endif
925
926    let indx = a:indx
927"    call Decho("..starpat=".starpat.": set indx= [a:indx=".indx."]",'~'.expand("<slnum>"))
928
929    if indx == -1
930     " Nexplore
931"     call Decho("..case Nexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
932     if !exists("w:netrw_explore_list") " sanity check
933      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
934      if has("clipboard")
935"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
936       if @* != keepregstar | sil! let @* = keepregstar | endif
937       if @+ != keepregplus | sil! let @+ = keepregplus | endif
938      endif
939      sil! let @/ = keepregslash
940"      call Dret("netrw#Explore")
941      return
942     endif
943     let indx= w:netrw_explore_indx
944     if indx < 0                        | let indx= 0                           | endif
945     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
946     let curfile= w:netrw_explore_list[indx]
947"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
948     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
949      let indx= indx + 1
950"      call Decho("....indx=".indx." (Nexplore while loop)",'~'.expand("<slnum>"))
951     endwhile
952     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
953"     call Decho("....Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
954
955    elseif indx == -2
956     " Pexplore
957"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
958     if !exists("w:netrw_explore_list") " sanity check
959      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
960      if has("clipboard")
961"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
962       if @* != keepregstar | sil! let @* = keepregstar | endif
963       if @+ != keepregplus | sil! let @+ = keepregplus | endif
964      endif
965      sil! let @/ = keepregslash
966"      call Dret("netrw#Explore")
967      return
968     endif
969     let indx= w:netrw_explore_indx
970     if indx < 0                        | let indx= 0                           | endif
971     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
972     let curfile= w:netrw_explore_list[indx]
973"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
974     while indx >= 0 && curfile == w:netrw_explore_list[indx]
975      let indx= indx - 1
976"      call Decho("....indx=".indx." (Pexplore while loop)",'~'.expand("<slnum>"))
977     endwhile
978     if indx < 0                        | let indx= 0                           | endif
979"     call Decho("....Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
980
981    else
982     " Explore -- initialize
983     " build list of files to Explore with Nexplore/Pexplore
984"     call Decho("..starpat=".starpat.": case Explore: initialize (indx=".indx.")",'~'.expand("<slnum>"))
985     NetrwKeepj keepalt call s:NetrwClearExplore()
986     let w:netrw_explore_indx= 0
987     if !exists("b:netrw_curdir")
988      let b:netrw_curdir= getcwd()
989     endif
990"     call Decho("....starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
991
992     " switch on starpat to build the w:netrw_explore_list of files
993     if starpat == 1
994      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
995"      call Decho("..case starpat=".starpat.": build *//pattern list  (curdir-only srch for files containing pattern)  &hls=".&hls,'~'.expand("<slnum>"))
996"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
997      try
998       exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
999      catch /^Vim\%((\a\+)\)\=:E480/
1000       keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
1001"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
1002       return
1003      endtry
1004      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
1005      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1006
1007     elseif starpat == 2
1008      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
1009"      call Decho("..case starpat=".starpat.": build **//pattern list  (recursive descent files containing pattern)",'~'.expand("<slnum>"))
1010"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
1011      try
1012       exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
1013      catch /^Vim\%((\a\+)\)\=:E480/
1014       keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
1015       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1016       if has("clipboard")
1017"        call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1018        if @* != keepregstar | sil! let @* = keepregstar | endif
1019        if @+ != keepregplus | sil! let @+ = keepregplus | endif
1020       endif
1021       sil! let @/ = keepregslash
1022"       call Dret("netrw#Explore : no files matched pattern")
1023       return
1024      endtry
1025      let s:netrw_curdir       = b:netrw_curdir
1026      let w:netrw_explore_list = getqflist()
1027      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
1028      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1029
1030     elseif starpat == 3
1031      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
1032"      call Decho("..case starpat=".starpat.": build */filepat list  (curdir-only srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1033      let filepat= substitute(dirname,'^\*/','','')
1034      let filepat= substitute(filepat,'^[%#<]','\\&','')
1035"      call Decho("....b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
1036"      call Decho("....filepat<".filepat.">",'~'.expand("<slnum>"))
1037      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
1038      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
1039
1040     elseif starpat == 4
1041      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
1042"      call Decho("..case starpat=".starpat.": build **/filepat list  (recursive descent srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1043      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
1044      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
1045     endif " switch on starpat to build w:netrw_explore_list
1046
1047     let w:netrw_explore_listlen = len(w:netrw_explore_list)
1048"     call Decho("....w:netrw_explore_list<".string(w:netrw_explore_list).">",'~'.expand("<slnum>"))
1049"     call Decho("....w:netrw_explore_listlen=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1050
1051     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1052      keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1053      if has("clipboard")
1054"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1055        if @* != keepregstar | sil! let @* = keepregstar | endif
1056        if @+ != keepregplus | sil! let @+ = keepregplus | endif
1057      endif
1058      sil! let @/ = keepregslash
1059"      call Dret("netrw#Explore : no files matched")
1060      return
1061     endif
1062    endif  " if indx ... endif
1063
1064    " NetrwStatusLine support - for exploring support
1065    let w:netrw_explore_indx= indx
1066"    call Decho("....w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1067
1068    " wrap the indx around, but issue a note
1069    if indx >= w:netrw_explore_listlen || indx < 0
1070"     call Decho("....wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")",'~'.expand("<slnum>"))
1071     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1072     let w:netrw_explore_indx= indx
1073     keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
1074    endif
1075
1076    exe "let dirfile= w:netrw_explore_list[".indx."]"
1077"    call Decho("....dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">",'~'.expand("<slnum>"))
1078    let newdir= substitute(dirfile,'/[^/]*$','','e')
1079"    call Decho("....newdir<".newdir.">",'~'.expand("<slnum>"))
1080
1081"    call Decho("....calling LocalBrowseCheck(newdir<".newdir.">)",'~'.expand("<slnum>"))
1082    call netrw#LocalBrowseCheck(newdir)
1083    if !exists("w:netrw_liststyle")
1084     let w:netrw_liststyle= g:netrw_liststyle
1085    endif
1086    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1087     keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1088    else
1089     keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1090    endif
1091    let w:netrw_explore_mtchcnt = indx + 1
1092    let w:netrw_explore_bufnr   = bufnr("%")
1093    let w:netrw_explore_line    = line(".")
1094    keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
1095"    call Decho("....explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line,'~'.expand("<slnum>"))
1096
1097   else
1098"    call Decho("..your vim does not have +path_extra",'~'.expand("<slnum>"))
1099    if !exists("g:netrw_quiet")
1100     keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1101    endif
1102    if has("clipboard")
1103"     call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1104      if @* != keepregstar | sil! let @* = keepregstar | endif
1105      if @+ != keepregplus | sil! let @+ = keepregplus | endif
1106    endif
1107    sil! let @/ = keepregslash
1108"    call Dret("netrw#Explore : missing +path_extra")
1109    return
1110   endif
1111
1112  else
1113"   call Decho("..default case: Explore newdir<".dirname.">",'~'.expand("<slnum>"))
1114   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1115    sil! unlet w:netrw_treedict
1116    sil! unlet w:netrw_treetop
1117   endif
1118   let newdir= dirname
1119   if !exists("b:netrw_curdir")
1120    NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1121   else
1122    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
1123   endif
1124  endif
1125
1126  " visual display of **/ **// */ Exploration files
1127"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"),'~'.expand("<slnum>"))
1128"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">",'~'.expand("<slnum>"))
1129  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
1130"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"),'~'.expand("<slnum>"))
1131   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1132    " only update match list when current directory isn't the same as before
1133"    call Decho("only update match list when current directory not the same as before",'~'.expand("<slnum>"))
1134    let s:explore_prvdir = b:netrw_curdir
1135    let s:explore_match  = ""
1136    let dirlen           = strlen(b:netrw_curdir)
1137    if b:netrw_curdir !~ '/$'
1138     let dirlen= dirlen + 1
1139    endif
1140    let prvfname= ""
1141    for fname in w:netrw_explore_list
1142"     call Decho("fname<".fname.">",'~'.expand("<slnum>"))
1143     if fname =~ '^'.b:netrw_curdir
1144      if s:explore_match == ""
1145       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1146      else
1147       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1148      endif
1149     elseif fname !~ '^/' && fname != prvfname
1150      if s:explore_match == ""
1151       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1152      else
1153       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1154      endif
1155     endif
1156     let prvfname= fname
1157    endfor
1158"    call Decho("explore_match<".s:explore_match.">",'~'.expand("<slnum>"))
1159    if has("syntax") && exists("g:syntax_on") && g:syntax_on
1160     exe "2match netrwMarkFile /".s:explore_match."/"
1161    endif
1162   endif
1163   echo "<s-up>==Pexplore  <s-down>==Nexplore"
1164  else
1165   2match none
1166   if exists("s:explore_match")  | unlet s:explore_match  | endif
1167   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
1168   echo " "
1169"   call Decho("cleared explore match list",'~'.expand("<slnum>"))
1170  endif
1171
1172  " since Explore may be used to initialize netrw's browser,
1173  " there's no danger of a late FocusGained event on initialization.
1174  " Consequently, set s:netrw_events to 2.
1175  let s:netrw_events= 2
1176  if has("clipboard")
1177"   call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1178   if @* != keepregstar | sil! let @* = keepregstar | endif
1179   if @+ != keepregplus | sil! let @+ = keepregplus | endif
1180  endif
1181  sil! let @/ = keepregslash
1182"  call Dret("netrw#Explore : @/<".@/.">")
1183endfun
1184
1185" ---------------------------------------------------------------------
1186" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
1187fun! netrw#Lexplore(count,rightside,...)
1188"  call Dfunc("netrw#Lexplore(count=".a:count." rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
1189  let curwin= winnr()
1190
1191  if a:0 > 0 && a:1 != ""
1192   " if a netrw window is already on the left-side of the tab
1193   " and a directory has been specified, explore with that
1194   " directory.
1195"   call Decho("case has input argument(s) (a:1<".a:1.">)")
1196   let a1 = expand(a:1)
1197"   call Decho("a:1<".a:1.">  curwin#".curwin,'~'.expand("<slnum>"))
1198   exe "1wincmd w"
1199   if &ft == "netrw"
1200"    call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
1201    exe "Explore ".fnameescape(a1)
1202    exe curwin."wincmd w"
1203    if exists("t:netrw_lexposn")
1204"     call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
1205     unlet t:netrw_lexposn
1206    endif
1207"    call Dret("netrw#Lexplore")
1208    return
1209   endif
1210   exe curwin."wincmd w"
1211  else
1212   let a1= ""
1213"   call Decho("no input arguments")
1214  endif
1215
1216  if exists("t:netrw_lexbufnr")
1217   " check if t:netrw_lexbufnr refers to a netrw window
1218   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1219"   call Decho("lexwinnr= bufwinnr(t:netrw_lexbufnr#".t:netrw_lexbufnr.")=".lexwinnr)
1220  else
1221   let lexwinnr= 0
1222"   call Decho("t:netrw_lexbufnr doesn't exist")
1223  endif
1224"  call Decho("lexwinnr=".lexwinnr,'~'.expand("<slnum>"))
1225
1226  if lexwinnr > 0
1227   " close down netrw explorer window
1228"   call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
1229   exe lexwinnr."wincmd w"
1230   let g:netrw_winsize = -winwidth(0)
1231   let t:netrw_lexposn = winsaveview()
1232"   call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1233"   call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
1234   close
1235   if lexwinnr < curwin
1236    let curwin= curwin - 1
1237   endif
1238   if lexwinnr != curwin
1239    exe curwin."wincmd w"
1240   endif
1241   unlet t:netrw_lexbufnr
1242"   call Decho("unlet t:netrw_lexbufnr")
1243
1244  else
1245   " open netrw explorer window
1246"   call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
1247   exe "1wincmd w"
1248   let keep_altv    = g:netrw_altv
1249   let g:netrw_altv = 0
1250   if a:count != 0
1251    let netrw_winsize   = g:netrw_winsize
1252    let g:netrw_winsize = a:count
1253   endif
1254   let curfile= expand("%")
1255"   call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
1256   exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1257"   call Decho("new buf#".bufnr("%")." win#".winnr())
1258   if a:0 > 0 && a1 != ""
1259"    call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
1260    call netrw#Explore(0,0,0,a1)
1261    exe "Explore ".fnameescape(a1)
1262   elseif curfile =~ '^\a\{3,}://'
1263"    call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
1264    call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
1265   else
1266"    call Decho("case 3: Explore .",'~'.expand("<slnum>"))
1267    call netrw#Explore(0,0,0,".")
1268   endif
1269   if a:count != 0
1270    let g:netrw_winsize = netrw_winsize
1271   endif
1272   setlocal winfixwidth
1273   let g:netrw_altv     = keep_altv
1274   let t:netrw_lexbufnr = bufnr("%")
1275   " done to prevent build-up of hidden buffers due to quitting and re-invocation of :Lexplore.
1276   " Since the intended use of :Lexplore is to have an always-present explorer window, the extra
1277   " effort to mis-use :Lex is warranted.
1278   set bh=wipe
1279"   call Decho("let t:netrw_lexbufnr=".t:netrw_lexbufnr)
1280"   call Decho("t:netrw_lexposn".(exists("t:netrw_lexposn")? string(t:netrw_lexposn) : " n/a"))
1281   if exists("t:netrw_lexposn")
1282"    call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1283"    call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1284    call winrestview(t:netrw_lexposn)
1285    unlet t:netrw_lexposn
1286   endif
1287  endif
1288
1289  " set up default window for editing via <cr>
1290  if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
1291   if a:rightside
1292    let g:netrw_chgwin= 1
1293   else
1294    let g:netrw_chgwin= 2
1295   endif
1296"   call Decho("let g:netrw_chgwin=".g:netrw_chgwin)
1297  endif
1298
1299"  call Dret("netrw#Lexplore")
1300endfun
1301
1302" ---------------------------------------------------------------------
1303" netrw#Clean: remove netrw {{{2
1304" supports :NetrwClean  -- remove netrw from first directory on runtimepath
1305"          :NetrwClean! -- remove netrw from all directories on runtimepath
1306fun! netrw#Clean(sys)
1307"  call Dfunc("netrw#Clean(sys=".a:sys.")")
1308
1309  if a:sys
1310   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
1311  else
1312   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
1313  endif
1314"  call Decho("choice=".choice,'~'.expand("<slnum>"))
1315  let diddel= 0
1316  let diddir= ""
1317
1318  if choice == 1
1319   for dir in split(&rtp,',')
1320    if filereadable(dir."/plugin/netrwPlugin.vim")
1321"     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1322     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
1323     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1324     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
1325     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
1326     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
1327     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
1328     let diddir= dir
1329     let diddel= diddel + 1
1330     if !a:sys|break|endif
1331    endif
1332   endfor
1333  endif
1334
1335   echohl WarningMsg
1336  if diddel == 0
1337   echomsg "netrw is either not installed or not removable"
1338  elseif diddel == 1
1339   echomsg "removed one copy of netrw from <".diddir.">"
1340  else
1341   echomsg "removed ".diddel." copies of netrw"
1342  endif
1343   echohl None
1344
1345"  call Dret("netrw#Clean")
1346endfun
1347
1348" ---------------------------------------------------------------------
1349" netrw#MakeTgt: make a target out of the directory name provided {{{2
1350fun! netrw#MakeTgt(dname)
1351"  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1352   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
1353  let svpos               = winsaveview()
1354"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1355  let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
1356"  call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
1357  if s:netrwmftgt_islocal
1358   let netrwmftgt= simplify(a:dname)
1359  else
1360   let netrwmftgt= a:dname
1361  endif
1362  if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
1363   " re-selected target, so just clear it
1364   unlet s:netrwmftgt s:netrwmftgt_islocal
1365  else
1366   let s:netrwmftgt= netrwmftgt
1367  endif
1368  if g:netrw_fastbrowse <= 1
1369   call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
1370  endif
1371"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
1372  call winrestview(svpos)
1373"  call Dret("netrw#MakeTgt")
1374endfun
1375
1376" ---------------------------------------------------------------------
1377" netrw#Obtain: {{{2
1378"   netrw#Obtain(islocal,fname[,tgtdirectory])
1379"     islocal=0  obtain from remote source
1380"            =1  obtain from local source
1381"     fname  :   a filename or a list of filenames
1382"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
1383fun! netrw#Obtain(islocal,fname,...)
1384"  call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
1385  " NetrwStatusLine support - for obtaining support
1386
1387  if type(a:fname) == 1
1388   let fnamelist= [ a:fname ]
1389  elseif type(a:fname) == 3
1390   let fnamelist= a:fname
1391  else
1392   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1393"   call Dret("netrw#Obtain")
1394   return
1395  endif
1396"  call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
1397  if a:0 > 0
1398   let tgtdir= a:1
1399  else
1400   let tgtdir= getcwd()
1401  endif
1402"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
1403
1404  if exists("b:netrw_islocal") && b:netrw_islocal
1405   " obtain a file from local b:netrw_curdir to (local) tgtdir
1406"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1407   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1408    let topath= s:ComposePath(tgtdir,"")
1409    if (has("win32") || has("win95") || has("win64") || has("win16"))
1410     " transfer files one at time
1411"     call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1412     for fname in fnamelist
1413"      call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1414      call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1415      if v:shell_error != 0
1416       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1417"       call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1418       return
1419      endif
1420     endfor
1421    else
1422     " transfer files with one command
1423"     call Decho("transfer files with one command",'~'.expand("<slnum>"))
1424     let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1425"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1426     call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".filelist." ".s:ShellEscape(topath))
1427     if v:shell_error != 0
1428      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1429"      call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1430      return
1431     endif
1432    endif
1433   elseif !exists("b:netrw_curdir")
1434    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
1435   else
1436    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
1437   endif
1438
1439  else
1440   " obtain files from remote b:netrw_curdir to local tgtdir
1441"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1442   if type(a:fname) == 1
1443    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
1444   endif
1445   call s:NetrwMethod(b:netrw_curdir)
1446
1447   if b:netrw_method == 4
1448    " obtain file using scp
1449"    call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1450    if exists("g:netrw_port") && g:netrw_port != ""
1451     let useport= " ".g:netrw_scpport." ".g:netrw_port
1452    else
1453     let useport= ""
1454    endif
1455    if b:netrw_fname =~ '/'
1456     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1457    else
1458     let path= ""
1459    endif
1460    let filelist= join(map(deepcopy(fnamelist),'escape(s:ShellEscape(g:netrw_machine.":".path.v:val,1)," ")'))
1461    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
1462
1463   elseif b:netrw_method == 2
1464    " obtain file using ftp + .netrc
1465"     call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1466     call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1467     let tmpbufnr= bufnr("%")
1468     setl ff=unix
1469     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1470      NetrwKeepj put =g:netrw_ftpmode
1471"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1472     endif
1473
1474     if exists("b:netrw_fname") && b:netrw_fname != ""
1475      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1476"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1477     endif
1478
1479     if exists("g:netrw_ftpextracmd")
1480      NetrwKeepj put =g:netrw_ftpextracmd
1481"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1482     endif
1483     for fname in fnamelist
1484      call setline(line("$")+1,'get "'.fname.'"')
1485"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1486     endfor
1487     if exists("g:netrw_port") && g:netrw_port != ""
1488      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1489     else
1490      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1491     endif
1492     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1493     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1494      let debugkeep= &debug
1495      setl debug=msg
1496      call netrw#ErrorMsg(s:ERROR,getline(1),4)
1497      let &debug= debugkeep
1498     endif
1499
1500   elseif b:netrw_method == 3
1501    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1502"    call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1503    call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1504    let tmpbufnr= bufnr("%")
1505    setl ff=unix
1506
1507    if exists("g:netrw_port") && g:netrw_port != ""
1508     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1509"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1510    else
1511     NetrwKeepj put ='open '.g:netrw_machine
1512"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1513    endif
1514
1515    if exists("g:netrw_uid") && g:netrw_uid != ""
1516     if exists("g:netrw_ftp") && g:netrw_ftp == 1
1517      NetrwKeepj put =g:netrw_uid
1518"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1519      if exists("s:netrw_passwd") && s:netrw_passwd != ""
1520       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1521      endif
1522"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1523     elseif exists("s:netrw_passwd")
1524      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1525"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1526     endif
1527    endif
1528
1529    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1530     NetrwKeepj put =g:netrw_ftpmode
1531"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1532    endif
1533
1534    if exists("b:netrw_fname") && b:netrw_fname != ""
1535     NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1536"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1537    endif
1538
1539    if exists("g:netrw_ftpextracmd")
1540     NetrwKeepj put =g:netrw_ftpextracmd
1541"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1542    endif
1543
1544    if exists("g:netrw_ftpextracmd")
1545     NetrwKeepj put =g:netrw_ftpextracmd
1546"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1547    endif
1548    for fname in fnamelist
1549     NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1550    endfor
1551"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1552
1553    " perform ftp:
1554    " -i       : turns off interactive prompting from ftp
1555    " -n  unix : DON'T use <.netrc>, even though it exists
1556    " -n  win32: quit being obnoxious about password
1557    "  Note: using "_dd to delete to the black hole register; avoids messing up @@
1558    NetrwKeepj norm! 1G"_dd
1559    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1560    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1561    if getline(1) !~ "^$"
1562"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1563     if !exists("g:netrw_quiet")
1564      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1565     endif
1566    endif
1567
1568   elseif b:netrw_method == 9
1569    " obtain file using sftp
1570"    call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1571    if a:fname =~ '/'
1572     let localfile= substitute(a:fname,'^.*/','','')
1573    else
1574     let localfile= a:fname
1575    endif
1576    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))
1577
1578   elseif !exists("b:netrw_method") || b:netrw_method < 0
1579    " probably a badly formed url; protocol not recognized
1580"    call Dret("netrw#Obtain : unsupported method")
1581    return
1582
1583   else
1584    " protocol recognized but not supported for Obtain (yet?)
1585    if !exists("g:netrw_quiet")
1586     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1587    endif
1588"    call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1589    return
1590   endif
1591
1592   " restore status line
1593   if type(a:fname) == 1 && exists("s:netrw_users_stl")
1594    NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
1595   endif
1596
1597  endif
1598
1599  " cleanup
1600  if exists("tmpbufnr")
1601   if bufnr("%") != tmpbufnr
1602    exe tmpbufnr."bw!"
1603   else
1604    q!
1605   endif
1606  endif
1607
1608"  call Dret("netrw#Obtain")
1609endfun
1610
1611" ---------------------------------------------------------------------
1612" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1613fun! netrw#Nread(mode,fname)
1614"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
1615  let svpos= winsaveview()
1616"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1617  call netrw#NetRead(a:mode,a:fname)
1618"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1619  call winrestview(svpos)
1620
1621  if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
1622   if exists("w:netrw_bannercnt")
1623    " start with cursor just after the banner
1624    exe w:netrw_bannercnt
1625   endif
1626  endif
1627"  call Dret("netrw#Nread")
1628endfun
1629
1630" ------------------------------------------------------------------------
1631" s:NetrwOptionsSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1632"             Options get restored by s:NetrwOptionsRestore()
1633"
1634"             Option handling:
1635"              * save user's options                                     (s:NetrwOptionsSave)
1636"              * set netrw-safe options                                  (s:NetrwOptionsSafe)
1637"                - change an option only when user option != safe option (s:netrwSetSafeSetting)
1638"              * restore user's options                                  (s:netrwOPtionsRestore)
1639"                - restore a user option when != safe option             (s:NetrwRestoreSetting)
1640"             vt: (variable type) normally its either "w:" or "s:"
1641fun! s:NetrwOptionsSave(vt)
1642"  call Dfunc("s:NetrwOptionsSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1643"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1644"  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>"))
1645
1646  if !exists("{a:vt}netrw_optionsave")
1647   let {a:vt}netrw_optionsave= 1
1648  else
1649"   call Dret("s:NetrwOptionsSave : options already saved")
1650   return
1651  endif
1652"  call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
1653
1654  " Save current settings and current directory
1655"  call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
1656  let s:yykeep          = @@
1657  if exists("&l:acd")|let {a:vt}netrw_acdkeep  = &l:acd|endif
1658  let {a:vt}netrw_aikeep    = &l:ai
1659  let {a:vt}netrw_awkeep    = &l:aw
1660  let {a:vt}netrw_bhkeep    = &l:bh
1661  let {a:vt}netrw_blkeep    = &l:bl
1662  let {a:vt}netrw_btkeep    = &l:bt
1663  let {a:vt}netrw_bombkeep  = &l:bomb
1664  let {a:vt}netrw_cedit     = &cedit
1665  let {a:vt}netrw_cikeep    = &l:ci
1666  let {a:vt}netrw_cinkeep   = &l:cin
1667  let {a:vt}netrw_cinokeep  = &l:cino
1668  let {a:vt}netrw_comkeep   = &l:com
1669  let {a:vt}netrw_cpokeep   = &l:cpo
1670  let {a:vt}netrw_diffkeep  = &l:diff
1671  let {a:vt}netrw_fenkeep   = &l:fen
1672  if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
1673   let {a:vt}netrw_ffkeep    = &l:ff
1674  endif
1675  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
1676  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
1677  let {a:vt}netrw_hidkeep   = &l:hidden
1678  let {a:vt}netrw_imkeep    = &l:im
1679  let {a:vt}netrw_iskkeep   = &l:isk
1680  let {a:vt}netrw_lskeep    = &l:ls
1681  let {a:vt}netrw_makeep    = &l:ma
1682  let {a:vt}netrw_magickeep = &l:magic
1683  let {a:vt}netrw_modkeep   = &l:mod
1684  let {a:vt}netrw_nukeep    = &l:nu
1685  let {a:vt}netrw_rnukeep   = &l:rnu
1686  let {a:vt}netrw_repkeep   = &l:report
1687  let {a:vt}netrw_rokeep    = &l:ro
1688  let {a:vt}netrw_selkeep   = &l:sel
1689  let {a:vt}netrw_spellkeep = &l:spell
1690  if !g:netrw_use_noswf
1691   let {a:vt}netrw_swfkeep  = &l:swf
1692  endif
1693  let {a:vt}netrw_tskeep    = &l:ts
1694  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
1695  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
1696  let {a:vt}netrw_wrapkeep  = &l:wrap
1697  let {a:vt}netrw_writekeep = &l:write
1698
1699  " save a few selected netrw-related variables
1700"  call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
1701  if g:netrw_keepdir
1702   let {a:vt}netrw_dirkeep  = getcwd()
1703"   call Decho("saving to ".a:vt."netrw_dirkeep<".{a:vt}netrw_dirkeep.">",'~'.expand("<slnum>"))
1704  endif
1705  if has("clipboard")
1706   sil! let {a:vt}netrw_starkeep = @*
1707   sil! let {a:vt}netrw_pluskeep = @+
1708  endif
1709  sil! let {a:vt}netrw_slashkeep= @/
1710
1711"  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>"))
1712"  call Dret("s:NetrwOptionsSave : tab#".tabpagenr()." win#".winnr())
1713endfun
1714
1715" ---------------------------------------------------------------------
1716" s:NetrwOptionsSafe: sets options to help netrw do its job {{{2
1717"                     Use  s:NetrwSaveOptions() to save user settings
1718"                     Use  s:NetrwOptionsRestore() to restore user settings
1719fun! s:NetrwOptionsSafe(islocal)
1720"  call Dfunc("s:NetrwOptionsSafe(islocal=".a:islocal.") win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1721"  call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1722"  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>"))
1723  if exists("+acd") | call s:NetrwSetSafeSetting("&l:acd",0)|endif
1724  call s:NetrwSetSafeSetting("&l:ai",0)
1725  call s:NetrwSetSafeSetting("&l:aw",0)
1726  call s:NetrwSetSafeSetting("&l:bl",0)
1727  call s:NetrwSetSafeSetting("&l:bomb",0)
1728  if a:islocal
1729   call s:NetrwSetSafeSetting("&l:bt","nofile")
1730  else
1731   call s:NetrwSetSafeSetting("&l:bt","acwrite")
1732  endif
1733  call s:NetrwSetSafeSetting("&l:ci",0)
1734  call s:NetrwSetSafeSetting("&l:cin",0)
1735  call s:NetrwSetSafeSetting("&l:bh","hide")
1736  call s:NetrwSetSafeSetting("&l:cino","")
1737  call s:NetrwSetSafeSetting("&l:com","")
1738  if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif
1739  if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif
1740  setl fo=nroql2
1741  call s:NetrwSetSafeSetting("&l:hid",0)
1742  call s:NetrwSetSafeSetting("&l:im",0)
1743  setl isk+=@ isk+=* isk+=/
1744  call s:NetrwSetSafeSetting("&l:magic",1)
1745  if g:netrw_use_noswf
1746   call s:NetrwSetSafeSetting("swf",0)
1747  endif
1748  call s:NetrwSetSafeSetting("&l:report",10000)
1749  call s:NetrwSetSafeSetting("&l:sel","inclusive")
1750  call s:NetrwSetSafeSetting("&l:spell",0)
1751  call s:NetrwSetSafeSetting("&l:tw",0)
1752  call s:NetrwSetSafeSetting("&l:wig","")
1753  setl cedit&
1754  call s:NetrwCursor()
1755
1756  " allow the user to override safe options
1757"  call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
1758  if &ft == "netrw"
1759"   call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1760   keepalt NetrwKeepj doau FileType netrw
1761  endif
1762
1763"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1764"  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>"))
1765"  call Dret("s:NetrwOptionsSafe")
1766endfun
1767
1768" ---------------------------------------------------------------------
1769" s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2
1770fun! s:NetrwOptionsRestore(vt)
1771"  call Dfunc("s:NetrwOptionsRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
1772"  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>"))
1773  if !exists("{a:vt}netrw_optionsave")
1774"   call Decho("case ".a:vt."netrw_optionsave : doesn't exist",'~'.expand("<slnum>"))
1775"   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>"))
1776"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1777"   call Dret("s:NetrwOptionsRestore : ".a:vt."netrw_optionsave doesn't exist")
1778   return
1779  endif
1780  unlet {a:vt}netrw_optionsave
1781
1782  if exists("+acd")
1783   if exists("{a:vt}netrw_acdkeep")
1784"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1785    let curdir = getcwd()
1786    let &l:acd = {a:vt}netrw_acdkeep
1787    unlet {a:vt}netrw_acdkeep
1788    if &l:acd
1789     call s:NetrwLcd(curdir)
1790    endif
1791   endif
1792  endif
1793  call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai")
1794  call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw")
1795  call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl")
1796  call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt")
1797  call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb")
1798  call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit")
1799  call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci")
1800  call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin")
1801  call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino")
1802  call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com")
1803  call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo")
1804  call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff")
1805  call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen")
1806  if exists("g:netrw_ffkeep") && g:netrw_ffkeep
1807   call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff")
1808  endif
1809  call s:NetrwRestoreSetting(a:vt."netrw_fokeep","&l:fo")
1810  call s:NetrwRestoreSetting(a:vt."netrw_gdkeep","&l:gd")
1811  call s:NetrwRestoreSetting(a:vt."netrw_hidkeep","&l:hidden")
1812  call s:NetrwRestoreSetting(a:vt."netrw_imkeep","&l:im")
1813  call s:NetrwRestoreSetting(a:vt."netrw_iskkeep","&l:isk")
1814  call s:NetrwRestoreSetting(a:vt."netrw_lskeep","&l:ls")
1815  call s:NetrwRestoreSetting(a:vt."netrw_makeep","&l:ma")
1816  call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic")
1817  call s:NetrwRestoreSetting(a:vt."netrw_modkeep","&l:mod")
1818  call s:NetrwRestoreSetting(a:vt."netrw_nukeep","&l:nu")
1819  call s:NetrwRestoreSetting(a:vt."netrw_rnukeep","&l:rnu")
1820  call s:NetrwRestoreSetting(a:vt."netrw_repkeep","&l:report")
1821  call s:NetrwRestoreSetting(a:vt."netrw_rokeep","&l:ro")
1822  call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
1823  call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell")
1824  call s:NetrwRestoreSetting(a:vt."netrw_twkeep","&l:tw")
1825  call s:NetrwRestoreSetting(a:vt."netrw_wigkeep","&l:wig")
1826  call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep","&l:wrap")
1827  call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write")
1828  call s:NetrwRestoreSetting("s:yykeep","@@")
1829  " former problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1830  " Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces
1831  "        rather than by appending a tab which previously was using "&ts" to set the desired spacing.  (Sep 28, 2018)
1832  call s:NetrwRestoreSetting(a:vt."netrw_tskeep","&l:ts")
1833
1834  if exists("{a:vt}netrw_swfkeep")
1835   if &directory == ""
1836    " user hasn't specified a swapfile directory;
1837    " netrw will temporarily set the swapfile directory
1838    " to the current directory as returned by getcwd().
1839    let &l:directory= getcwd()
1840    sil! let &l:swf = {a:vt}netrw_swfkeep
1841    setl directory=
1842    unlet {a:vt}netrw_swfkeep
1843   elseif &l:swf != {a:vt}netrw_swfkeep
1844    if !g:netrw_use_noswf
1845     " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1846     sil! let &l:swf= {a:vt}netrw_swfkeep
1847    endif
1848    unlet {a:vt}netrw_swfkeep
1849   endif
1850  endif
1851  if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
1852   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1853   if exists("{a:vt}netrw_dirkeep")
1854    call s:NetrwLcd(dirkeep)
1855    unlet {a:vt}netrw_dirkeep
1856   endif
1857  endif
1858  if has("clipboard")
1859"   call Decho("has clipboard",'~'.expand("<slnum>"))
1860   call s:NetrwRestoreSetting(a:vt."netrw_starkeep","@*")
1861   call s:NetrwRestoreSetting(a:vt."netrw_pluskeep","@+")
1862  endif
1863  call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/")
1864
1865"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1866"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
1867"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1868"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
1869"  call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
1870  " Moved the filetype detect here from NetrwGetFile() because remote files
1871  " were having their filetype detect-generated settings overwritten by
1872  " NetrwOptionRestore.
1873  if &ft != "netrw"
1874"   call Decho("filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1875   filetype detect
1876  endif
1877"  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>"))
1878"  call Dret("s:NetrwOptionsRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
1879endfun
1880
1881" ---------------------------------------------------------------------
1882" s:NetrwSetSafeSetting: sets an option to a safe setting {{{2
1883"                        but only when the options' value and the safe setting differ
1884"                        Doing this means that netrw will not come up as having changed a
1885"                        setting last when it really didn't actually change it.
1886"
1887"                        Called from s:NetrwOptionsSafe
1888"                          ex. call s:NetrwSetSafeSetting("&l:sel","inclusive")
1889fun! s:NetrwSetSafeSetting(setting,safesetting)
1890"  call Dfunc("s:NetrwSetSafeSetting(setting<".a:setting."> safesetting<".a:safesetting.">)")
1891
1892  if a:setting =~ '^&'
1893"   call Decho("fyi: a:setting starts with &")
1894   exe "let settingval= ".a:setting
1895"   call Decho("fyi: settingval<".settingval.">")
1896
1897   if settingval != a:safesetting
1898"    call Decho("set setting<".a:setting."> to option value<".a:safesetting.">")
1899    if type(a:safesetting) == 0
1900     exe "let ".a:setting."=".a:safesetting
1901    elseif type(a:safesetting) == 1
1902     exe "let ".a:setting."= '".a:safesetting."'"
1903    else
1904     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:setting." with a safesetting of type#".type(a:safesetting),105)
1905    endif
1906   endif
1907  endif
1908
1909"  call Dret("s:NetrwSetSafeSetting")
1910endfun
1911
1912" ------------------------------------------------------------------------
1913" s:NetrwRestoreSetting: restores specified setting using associated keepvar, {{{2
1914"                        but only if the setting value differs from the associated keepvar.
1915"                        Doing this means that netrw will not come up as having changed a
1916"                        setting last when it really didn't actually change it.
1917"
1918"                        Used by s:NetrwOptionsRestore() to restore each netrw-senstive setting
1919"                        keepvars are set up by s:NetrwOptionsSave
1920fun! s:NetrwRestoreSetting(keepvar,setting)
1921"""  call Dfunc("s:NetrwRestoreSetting(a:keepvar<".a:keepvar."> a:setting<".a:setting.">)")
1922
1923  " typically called from s:NetrwOptionsRestore
1924  "   call s:NetrwRestoreSettings(keep-option-variable-name,'associated-option')
1925  "   ex. call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
1926  "  Restores option (if different) from a keepvar
1927  if exists(a:keepvar)
1928   exe "let keepvarval= ".a:keepvar
1929   exe "let setting= ".a:setting
1930
1931""   call Decho("fyi: a:keepvar<".a:keepvar."> exists")
1932""   call Decho("fyi: keepvarval=".keepvarval)
1933""   call Decho("fyi: a:setting<".a:setting."> setting<".setting.">")
1934
1935   if setting != keepvarval
1936""    call Decho("restore setting<".a:setting."> (currently=".setting.") to keepvarval<".keepvarval.">")
1937    if type(a:setting) == 0
1938     exe "let ".a:setting."= ".keepvarval
1939    elseif type(a:setting) == 1
1940     exe "let ".a:setting."= '".substitute(keepvarval,"'","''","g")."'"
1941    else
1942     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105)
1943    endif
1944   endif
1945
1946   exe "unlet ".a:keepvar
1947  endif
1948
1949""  call Dret("s:NetrwRestoreSetting")
1950endfun
1951
1952" ---------------------------------------------------------------------
1953" NetrwStatusLine: {{{2
1954fun! NetrwStatusLine()
1955
1956" vvv NetrwStatusLine() debugging vvv
1957"  let g:stlmsg=""
1958"  if !exists("w:netrw_explore_bufnr")
1959"   let g:stlmsg="!X<explore_bufnr>"
1960"  elseif w:netrw_explore_bufnr != bufnr("%")
1961"   let g:stlmsg="explore_bufnr!=".bufnr("%")
1962"  endif
1963"  if !exists("w:netrw_explore_line")
1964"   let g:stlmsg=" !X<explore_line>"
1965"  elseif w:netrw_explore_line != line(".")
1966"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1967"  endif
1968"  if !exists("w:netrw_explore_list")
1969"   let g:stlmsg=" !X<explore_list>"
1970"  endif
1971" ^^^ NetrwStatusLine() debugging ^^^
1972
1973  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")
1974   " restore user's status line
1975   let &stl        = s:netrw_users_stl
1976   let &laststatus = s:netrw_users_ls
1977   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1978   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1979   return ""
1980  else
1981   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
1982  endif
1983endfun
1984
1985" ===============================
1986"  Netrw Transfer Functions: {{{1
1987" ===============================
1988
1989" ------------------------------------------------------------------------
1990" netrw#NetRead: responsible for reading a file over the net {{{2
1991"   mode: =0 read remote file and insert before current line
1992"         =1 read remote file and insert after current line
1993"         =2 replace with remote file
1994"         =3 obtain file, but leave in temporary format
1995fun! netrw#NetRead(mode,...)
1996"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
1997
1998  " NetRead: save options {{{3
1999  call s:NetrwOptionsSave("w:")
2000  call s:NetrwOptionsSafe(0)
2001  call s:RestoreCursorline()
2002  " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
2003  " However, this setting is not wanted for a remote editing session.  The buffer should be "nofile", still.
2004  setl bl
2005"  call Decho("buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
2006
2007  " NetRead: interpret mode into a readcmd {{{3
2008  if     a:mode == 0 " read remote file before current line
2009   let readcmd = "0r"
2010  elseif a:mode == 1 " read file after current line
2011   let readcmd = "r"
2012  elseif a:mode == 2 " replace with remote file
2013   let readcmd = "%r"
2014  elseif a:mode == 3 " skip read of file (leave as temporary)
2015   let readcmd = "t"
2016  else
2017   exe a:mode
2018   let readcmd = "r"
2019  endif
2020  let ichoice = (a:0 == 0)? 0 : 1
2021"  call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
2022
2023  " NetRead: get temporary filename {{{3
2024  let tmpfile= s:GetTempfile("")
2025  if tmpfile == ""
2026"   call Dret("netrw#NetRead : unable to get a tempfile!")
2027   return
2028  endif
2029
2030  while ichoice <= a:0
2031
2032   " attempt to repeat with previous host-file-etc
2033   if exists("b:netrw_lastfile") && a:0 == 0
2034"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2035    let choice = b:netrw_lastfile
2036    let ichoice= ichoice + 1
2037
2038   else
2039    exe "let choice= a:" . ichoice
2040"    call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
2041
2042    if match(choice,"?") == 0
2043     " give help
2044     echomsg 'NetRead Usage:'
2045     echomsg ':Nread machine:path                         uses rcp'
2046     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
2047     echomsg ':Nread "machine id password path"           uses ftp'
2048     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
2049     echomsg ':Nread fetch://machine/path                 uses fetch'
2050     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2051     echomsg ':Nread http://[user@]machine/path           uses http  wget'
2052     echomsg ':Nread file:///path           		  uses elinks'
2053     echomsg ':Nread https://[user@]machine/path          uses http  wget'
2054     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
2055     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
2056     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
2057     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
2058     sleep 4
2059     break
2060
2061    elseif match(choice,'^"') != -1
2062     " Reconstruct Choice if choice starts with '"'
2063"     call Decho("reconstructing choice",'~'.expand("<slnum>"))
2064     if match(choice,'"$') != -1
2065      " case "..."
2066      let choice= strpart(choice,1,strlen(choice)-2)
2067     else
2068       "  case "... ... ..."
2069      let choice      = strpart(choice,1,strlen(choice)-1)
2070      let wholechoice = ""
2071
2072      while match(choice,'"$') == -1
2073       let wholechoice = wholechoice . " " . choice
2074       let ichoice     = ichoice + 1
2075       if ichoice > a:0
2076       	if !exists("g:netrw_quiet")
2077	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
2078	endif
2079"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
2080        return
2081       endif
2082       let choice= a:{ichoice}
2083      endwhile
2084      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2085     endif
2086    endif
2087   endif
2088
2089"   call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
2090   let ichoice= ichoice + 1
2091
2092   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
2093   call s:NetrwMethod(choice)
2094   if !exists("b:netrw_method") || b:netrw_method < 0
2095"    call Dret("netrw#NetRead : unsupported method")
2096    return
2097   endif
2098   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
2099
2100   " Check whether or not NetrwBrowse() should be handling this request
2101"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
2102   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
2103"    call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
2104    NetrwKeepj call s:NetrwBrowse(0,choice)
2105"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
2106    return
2107   endif
2108
2109   " ============
2110   " NetRead: Perform Protocol-Based Read {{{3
2111   " ===========================
2112   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2113    echo "(netrw) Processing your read request..."
2114   endif
2115
2116   ".........................................
2117   " NetRead: (rcp)  NetRead Method #1 {{{3
2118   if  b:netrw_method == 1 " read with rcp
2119"    call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
2120   " ER: nothing done with g:netrw_uid yet?
2121   " ER: on Win2K" rcp machine[.user]:file tmpfile
2122   " ER: when machine contains '.' adding .user is required (use $USERNAME)
2123   " ER: the tmpfile is full path: rcp sees C:\... as host C
2124   if s:netrw_has_nt_rcp == 1
2125    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2126     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2127    else
2128     " Any way needed it machine contains a '.'
2129     let uid_machine = g:netrw_machine .'.'. $USERNAME
2130    endif
2131   else
2132    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2133     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2134    else
2135     let uid_machine = g:netrw_machine
2136    endif
2137   endif
2138   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))
2139   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2140   let b:netrw_lastfile = choice
2141
2142   ".........................................
2143   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
2144   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
2145"     call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2146     let netrw_fname= b:netrw_fname
2147     NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2148     let filtbuf= bufnr("%")
2149     setl ff=unix
2150     NetrwKeepj put =g:netrw_ftpmode
2151"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2152     if exists("g:netrw_ftpextracmd")
2153      NetrwKeepj put =g:netrw_ftpextracmd
2154"      call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2155     endif
2156     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2157"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2158     if exists("g:netrw_port") && g:netrw_port != ""
2159      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2160     else
2161      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2162     endif
2163     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2164     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2165      let debugkeep = &debug
2166      setl debug=msg
2167      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2168      let &debug    = debugkeep
2169     endif
2170     call s:SaveBufVars()
2171     keepj bd!
2172     if bufname("%") == "" && getline("$") == "" && line('$') == 1
2173      " needed when one sources a file in a nolbl setting window via ftp
2174      q!
2175     endif
2176     call s:RestoreBufVars()
2177     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2178     let b:netrw_lastfile = choice
2179
2180   ".........................................
2181   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
2182   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
2183    " Construct execution string (four lines) which will be passed through filter
2184"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2185    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2186    NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2187    let filtbuf= bufnr("%")
2188    setl ff=unix
2189    if exists("g:netrw_port") && g:netrw_port != ""
2190     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2191"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2192    else
2193     NetrwKeepj put ='open '.g:netrw_machine
2194"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2195    endif
2196
2197    if exists("g:netrw_uid") && g:netrw_uid != ""
2198     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2199      NetrwKeepj put =g:netrw_uid
2200"       call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2201      if exists("s:netrw_passwd")
2202       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2203      endif
2204"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2205     elseif exists("s:netrw_passwd")
2206      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2207"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2208     endif
2209    endif
2210
2211    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2212     NetrwKeepj put =g:netrw_ftpmode
2213"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2214    endif
2215    if exists("g:netrw_ftpextracmd")
2216     NetrwKeepj put =g:netrw_ftpextracmd
2217"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2218    endif
2219    NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2220"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2221
2222    " perform ftp:
2223    " -i       : turns off interactive prompting from ftp
2224    " -n  unix : DON'T use <.netrc>, even though it exists
2225    " -n  win32: quit being obnoxious about password
2226    NetrwKeepj norm! 1G"_dd
2227    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2228    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2229    if getline(1) !~ "^$"
2230"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2231     if !exists("g:netrw_quiet")
2232      call netrw#ErrorMsg(s:ERROR,getline(1),5)
2233     endif
2234    endif
2235    call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2236    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2237    let b:netrw_lastfile = choice
2238
2239   ".........................................
2240   " NetRead: (scp) NetRead Method #4 {{{3
2241   elseif     b:netrw_method  == 4	" read with scp
2242"    call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2243    if exists("g:netrw_port") && g:netrw_port != ""
2244     let useport= " ".g:netrw_scpport." ".g:netrw_port
2245    else
2246     let useport= ""
2247    endif
2248    " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2249    " This is workaround to avoid mis-handle windows local-path:
2250    if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
2251      let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2252    else
2253      let tmpfile_get = tmpfile
2254    endif
2255    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".escape(s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1),' ')." ".s:ShellEscape(tmpfile_get,1))
2256    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2257    let b:netrw_lastfile = choice
2258
2259   ".........................................
2260   " NetRead: (http) NetRead Method #5 (wget) {{{3
2261   elseif     b:netrw_method  == 5
2262"    call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2263    if g:netrw_http_cmd == ""
2264     if !exists("g:netrw_quiet")
2265      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2266     endif
2267"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2268     return
2269    endif
2270
2271    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2272     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2273"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2274     if exists("g:netrw_http_xcmd")
2275      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))
2276     else
2277      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))
2278     endif
2279     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2280
2281    else
2282     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2283"     call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2284     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2285     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2286"     call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2287"     call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2288     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))
2289     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2290"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2291     exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2292    endif
2293    let b:netrw_lastfile = choice
2294"    call Decho("setl ro",'~'.expand("<slnum>"))
2295    setl ro nomod
2296
2297   ".........................................
2298   " NetRead: (dav) NetRead Method #6 {{{3
2299   elseif     b:netrw_method  == 6
2300"    call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2301
2302    if !executable(g:netrw_dav_cmd)
2303     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2304"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2305     return
2306    endif
2307    if g:netrw_dav_cmd =~ "curl"
2308     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2309    else
2310     " Construct execution string (four lines) which will be passed through filter
2311     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2312     new
2313     setl ff=unix
2314     if exists("g:netrw_port") && g:netrw_port != ""
2315      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2316     else
2317      NetrwKeepj put ='open '.g:netrw_machine
2318     endif
2319     if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2320      NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2321     endif
2322     NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2323     NetrwKeepj put ='quit'
2324
2325     " perform cadaver operation:
2326     NetrwKeepj norm! 1G"_dd
2327     call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2328     keepj bd!
2329    endif
2330    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2331    let b:netrw_lastfile = choice
2332
2333   ".........................................
2334   " NetRead: (rsync) NetRead Method #7 {{{3
2335   elseif     b:netrw_method  == 7
2336"    call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2337    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(g:netrw_machine.g:netrw_rsync_sep.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2338    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2339    let b:netrw_lastfile = choice
2340
2341   ".........................................
2342   " NetRead: (fetch) NetRead Method #8 {{{3
2343   "    fetch://[user@]host[:http]/path
2344   elseif     b:netrw_method  == 8
2345"    call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2346    if g:netrw_fetch_cmd == ""
2347     if !exists("g:netrw_quiet")
2348      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2349     endif
2350"     call Dret("NetRead")
2351     return
2352    endif
2353    if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2354     let netrw_option= "http"
2355    else
2356     let netrw_option= "ftp"
2357    endif
2358"    call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2359
2360    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2361     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))
2362    else
2363     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))
2364    endif
2365
2366    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2367    let b:netrw_lastfile = choice
2368"    call Decho("setl ro",'~'.expand("<slnum>"))
2369    setl ro nomod
2370
2371   ".........................................
2372   " NetRead: (sftp) NetRead Method #9 {{{3
2373   elseif     b:netrw_method  == 9
2374"    call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2375    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2376    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2377    let b:netrw_lastfile = choice
2378
2379   ".........................................
2380   " NetRead: (file) NetRead Method #10 {{{3
2381  elseif      b:netrw_method == 10 && exists("g:netrw_file_cmd")
2382"   "    call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2383   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2384   let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2385   let b:netrw_lastfile = choice
2386
2387   ".........................................
2388   " NetRead: Complain {{{3
2389   else
2390    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
2391   endif
2392  endwhile
2393
2394  " NetRead: cleanup {{{3
2395  if exists("b:netrw_method")
2396"   call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2397   unlet b:netrw_method
2398   unlet b:netrw_fname
2399  endif
2400  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
2401"   call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2402   NetrwKeepj call s:NetrwDelete(tmpfile)
2403  endif
2404  NetrwKeepj call s:NetrwOptionsRestore("w:")
2405
2406"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
2407endfun
2408
2409" ------------------------------------------------------------------------
2410" netrw#NetWrite: responsible for writing a file over the net {{{2
2411fun! netrw#NetWrite(...) range
2412"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
2413
2414  " NetWrite: option handling {{{3
2415  let mod= 0
2416  call s:NetrwOptionsSave("w:")
2417  call s:NetrwOptionsSafe(0)
2418
2419  " NetWrite: Get Temporary Filename {{{3
2420  let tmpfile= s:GetTempfile("")
2421  if tmpfile == ""
2422"   call Dret("netrw#NetWrite : unable to get a tempfile!")
2423   return
2424  endif
2425
2426  if a:0 == 0
2427   let ichoice = 0
2428  else
2429   let ichoice = 1
2430  endif
2431
2432  let curbufname= expand("%")
2433"  call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
2434  if &binary
2435   " For binary writes, always write entire file.
2436   " (line numbers don't really make sense for that).
2437   " Also supports the writing of tar and zip files.
2438"   call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2439   exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2440  elseif g:netrw_cygwin
2441   " write (selected portion of) file to temporary
2442   let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2443"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2444   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
2445  else
2446   " write (selected portion of) file to temporary
2447"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2448   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2449  endif
2450
2451  if curbufname == ""
2452   " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2453   " on the temporary file's name.  Deletion of the temporary file during
2454   " cleanup then causes an error message.
2455   0file!
2456  endif
2457
2458  " NetWrite: while choice loop: {{{3
2459  while ichoice <= a:0
2460
2461   " Process arguments: {{{4
2462   " attempt to repeat with previous host-file-etc
2463   if exists("b:netrw_lastfile") && a:0 == 0
2464"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2465    let choice = b:netrw_lastfile
2466    let ichoice= ichoice + 1
2467   else
2468    exe "let choice= a:" . ichoice
2469
2470    " Reconstruct Choice when choice starts with '"'
2471    if match(choice,"?") == 0
2472     echomsg 'NetWrite Usage:"'
2473     echomsg ':Nwrite machine:path                        uses rcp'
2474     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
2475     echomsg ':Nwrite "machine id password path"          uses ftp'
2476     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
2477     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
2478     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
2479     echomsg ':Nwrite rcp://machine/path                  uses rcp'
2480     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
2481     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2482     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
2483     sleep 4
2484     break
2485
2486    elseif match(choice,"^\"") != -1
2487     if match(choice,"\"$") != -1
2488       " case "..."
2489      let choice=strpart(choice,1,strlen(choice)-2)
2490     else
2491      "  case "... ... ..."
2492      let choice      = strpart(choice,1,strlen(choice)-1)
2493      let wholechoice = ""
2494
2495      while match(choice,"\"$") == -1
2496       let wholechoice= wholechoice . " " . choice
2497       let ichoice    = ichoice + 1
2498       if choice > a:0
2499       	if !exists("g:netrw_quiet")
2500	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2501	endif
2502"        call Dret("netrw#NetWrite")
2503        return
2504       endif
2505       let choice= a:{ichoice}
2506      endwhile
2507      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2508     endif
2509    endif
2510   endif
2511   let ichoice= ichoice + 1
2512"   call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
2513
2514   " Determine method of write (ftp, rcp, etc) {{{4
2515   NetrwKeepj call s:NetrwMethod(choice)
2516   if !exists("b:netrw_method") || b:netrw_method < 0
2517"    call Dfunc("netrw#NetWrite : unsupported method")
2518    return
2519   endif
2520
2521   " =============
2522   " NetWrite: Perform Protocol-Based Write {{{3
2523   " ============================
2524   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2525    echo "(netrw) Processing your write request..."
2526"    call Decho("Processing your write request...",'~'.expand("<slnum>"))
2527   endif
2528
2529   ".........................................
2530   " NetWrite: (rcp) NetWrite Method #1 {{{3
2531   if  b:netrw_method == 1
2532"    call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2533    if s:netrw_has_nt_rcp == 1
2534     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2535      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2536     else
2537      let uid_machine = g:netrw_machine .'.'. $USERNAME
2538     endif
2539    else
2540     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2541      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2542     else
2543      let uid_machine = g:netrw_machine
2544     endif
2545    endif
2546    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))
2547    let b:netrw_lastfile = choice
2548
2549   ".........................................
2550   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2551   elseif b:netrw_method == 2
2552"    call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2553    let netrw_fname = b:netrw_fname
2554
2555    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2556    let bhkeep      = &l:bh
2557    let curbuf      = bufnr("%")
2558    setl bh=hide
2559    keepj keepalt enew
2560
2561"    call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2562    setl ff=unix
2563    NetrwKeepj put =g:netrw_ftpmode
2564"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2565    if exists("g:netrw_ftpextracmd")
2566     NetrwKeepj put =g:netrw_ftpextracmd
2567"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2568    endif
2569    NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2570"    call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2571    if exists("g:netrw_port") && g:netrw_port != ""
2572     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2573    else
2574"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2575     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2576    endif
2577    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2578    if getline(1) !~ "^$"
2579     if !exists("g:netrw_quiet")
2580      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2581     endif
2582     let mod=1
2583    endif
2584
2585    " remove enew buffer (quietly)
2586    let filtbuf= bufnr("%")
2587    exe curbuf."b!"
2588    let &l:bh            = bhkeep
2589    exe filtbuf."bw!"
2590
2591    let b:netrw_lastfile = choice
2592
2593   ".........................................
2594   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2595   elseif b:netrw_method == 3
2596    " Construct execution string (three or more lines) which will be passed through filter
2597"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2598    let netrw_fname = b:netrw_fname
2599    let bhkeep      = &l:bh
2600
2601    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2602    let curbuf      = bufnr("%")
2603    setl bh=hide
2604    keepj keepalt enew
2605    setl ff=unix
2606
2607    if exists("g:netrw_port") && g:netrw_port != ""
2608     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2609"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2610    else
2611     NetrwKeepj put ='open '.g:netrw_machine
2612"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2613    endif
2614    if exists("g:netrw_uid") && g:netrw_uid != ""
2615     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2616      NetrwKeepj put =g:netrw_uid
2617"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2618      if exists("s:netrw_passwd") && s:netrw_passwd != ""
2619       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2620      endif
2621"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2622     elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2623      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2624"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2625     endif
2626    endif
2627    NetrwKeepj put =g:netrw_ftpmode
2628"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2629    if exists("g:netrw_ftpextracmd")
2630     NetrwKeepj put =g:netrw_ftpextracmd
2631"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2632    endif
2633    NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2634"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2635    " save choice/id/password for future use
2636    let b:netrw_lastfile = choice
2637
2638    " perform ftp:
2639    " -i       : turns off interactive prompting from ftp
2640    " -n  unix : DON'T use <.netrc>, even though it exists
2641    " -n  win32: quit being obnoxious about password
2642    NetrwKeepj norm! 1G"_dd
2643    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2644    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2645    if getline(1) !~ "^$"
2646     if  !exists("g:netrw_quiet")
2647      call netrw#ErrorMsg(s:ERROR,getline(1),15)
2648     endif
2649     let mod=1
2650    endif
2651
2652    " remove enew buffer (quietly)
2653    let filtbuf= bufnr("%")
2654    exe curbuf."b!"
2655    let &l:bh= bhkeep
2656    exe filtbuf."bw!"
2657
2658   ".........................................
2659   " NetWrite: (scp) NetWrite Method #4 {{{3
2660   elseif     b:netrw_method == 4
2661"    call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2662    if exists("g:netrw_port") && g:netrw_port != ""
2663     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2664    else
2665     let useport= ""
2666    endif
2667    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2668    let b:netrw_lastfile = choice
2669
2670   ".........................................
2671   " NetWrite: (http) NetWrite Method #5 {{{3
2672   elseif     b:netrw_method == 5
2673"    call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2674    let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2675    if executable(curl)
2676     let url= g:netrw_choice
2677     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2678    elseif !exists("g:netrw_quiet")
2679     call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd.">".",16)
2680    endif
2681
2682   ".........................................
2683   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2684   elseif     b:netrw_method == 6
2685"    call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2686
2687    " Construct execution string (four lines) which will be passed through filter
2688    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2689    let bhkeep      = &l:bh
2690
2691    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2692    let curbuf      = bufnr("%")
2693    setl bh=hide
2694    keepj keepalt enew
2695
2696    setl ff=unix
2697    if exists("g:netrw_port") && g:netrw_port != ""
2698     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2699    else
2700     NetrwKeepj put ='open '.g:netrw_machine
2701    endif
2702    if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2703     NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2704    endif
2705    NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2706
2707    " perform cadaver operation:
2708    NetrwKeepj norm! 1G"_dd
2709    call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2710
2711    " remove enew buffer (quietly)
2712    let filtbuf= bufnr("%")
2713    exe curbuf."b!"
2714    let &l:bh            = bhkeep
2715    exe filtbuf."bw!"
2716
2717    let b:netrw_lastfile = choice
2718
2719   ".........................................
2720   " NetWrite: (rsync) NetWrite Method #7 {{{3
2721   elseif     b:netrw_method == 7
2722"    call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2723    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.g:netrw_rsync_sep.b:netrw_fname,1))
2724    let b:netrw_lastfile = choice
2725
2726   ".........................................
2727   " NetWrite: (sftp) NetWrite Method #9 {{{3
2728   elseif     b:netrw_method == 9
2729"    call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2730    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2731    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2732     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2733    else
2734     let uid_machine = g:netrw_machine
2735    endif
2736
2737    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2738    let bhkeep = &l:bh
2739    let curbuf = bufnr("%")
2740    setl bh=hide
2741    keepj keepalt enew
2742
2743    setl ff=unix
2744    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2745"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2746    let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2747    call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2748    let filtbuf= bufnr("%")
2749    exe curbuf."b!"
2750    let &l:bh            = bhkeep
2751    exe filtbuf."bw!"
2752    let b:netrw_lastfile = choice
2753
2754   ".........................................
2755   " NetWrite: Complain {{{3
2756   else
2757    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2758    let leavemod= 1
2759   endif
2760  endwhile
2761
2762  " NetWrite: Cleanup: {{{3
2763"  call Decho("cleanup",'~'.expand("<slnum>"))
2764  if s:FileReadable(tmpfile)
2765"   call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2766   call s:NetrwDelete(tmpfile)
2767  endif
2768  call s:NetrwOptionsRestore("w:")
2769
2770  if a:firstline == 1 && a:lastline == line("$")
2771   " restore modifiability; usually equivalent to set nomod
2772   let &mod= mod
2773"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2774  elseif !exists("leavemod")
2775   " indicate that the buffer has not been modified since last written
2776"   call Decho("set nomod",'~'.expand("<slnum>"))
2777   setl nomod
2778"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2779  endif
2780
2781"  call Dret("netrw#NetWrite")
2782endfun
2783
2784" ---------------------------------------------------------------------
2785" netrw#NetSource: source a remotely hosted vim script {{{2
2786" uses NetRead to get a copy of the file into a temporarily file,
2787"              then sources that file,
2788"              then removes that file.
2789fun! netrw#NetSource(...)
2790"  call Dfunc("netrw#NetSource() a:0=".a:0)
2791  if a:0 > 0 && a:1 == '?'
2792   " give help
2793   echomsg 'NetSource Usage:'
2794   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
2795   echomsg ':Nsource fetch://machine/path                 uses fetch'
2796   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2797   echomsg ':Nsource http[s]://[user@]machine/path        uses http  wget'
2798   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
2799   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
2800   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
2801   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2802   sleep 4
2803  else
2804   let i= 1
2805   while i <= a:0
2806    call netrw#NetRead(3,a:{i})
2807"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2808    if s:FileReadable(s:netrw_tmpfile)
2809"     call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2810     exe "so ".fnameescape(s:netrw_tmpfile)
2811"     call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2812     if delete(s:netrw_tmpfile)
2813      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2814     endif
2815     unlet s:netrw_tmpfile
2816    else
2817     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2818    endif
2819    let i= i + 1
2820   endwhile
2821  endif
2822"  call Dret("netrw#NetSource")
2823endfun
2824
2825" ---------------------------------------------------------------------
2826" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2827"                   (implements the :Ntree command)
2828fun! netrw#SetTreetop(iscmd,...)
2829"  call Dfunc("netrw#SetTreetop(iscmd=".a:iscmd." ".((a:0 > 0)? a:1 : "").") a:0=".a:0)
2830"  call Decho("w:netrw_treetop<".w:netrw_treetop.">")
2831
2832  " iscmd==0: netrw#SetTreetop called using gn mapping
2833  " iscmd==1: netrw#SetTreetop called using :Ntree from the command line
2834"  call Decho("(iscmd=".a:iscmd.": called using :Ntree from command line",'~'.expand("<slnum>"))
2835  " clear out the current tree
2836  if exists("w:netrw_treetop")
2837"   call Decho("clearing out current tree",'~'.expand("<slnum>"))
2838   let inittreetop= w:netrw_treetop
2839   unlet w:netrw_treetop
2840  endif
2841  if exists("w:netrw_treedict")
2842"   call Decho("freeing w:netrw_treedict",'~'.expand("<slnum>"))
2843   unlet w:netrw_treedict
2844  endif
2845"  call Decho("inittreetop<".(exists("inittreetop")? inittreetop : "n/a").">")
2846
2847  if (a:iscmd == 0 || a:1 == "") && exists("inittreetop")
2848   let treedir= s:NetrwTreePath(inittreetop)
2849"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2850  else
2851   if isdirectory(s:NetrwFile(a:1))
2852"    call Decho("a:1<".a:1."> is a directory",'~'.expand("<slnum>"))
2853    let treedir= a:1
2854   elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2855    let treedir= b:netrw_curdir."/".a:1
2856"    call Decho("a:1<".a:1."> is NOT a directory, using treedir<".treedir.">",'~'.expand("<slnum>"))
2857   else
2858    " normally the cursor is left in the message window.
2859    " However, here this results in the directory being listed in the message window, which is not wanted.
2860    let netrwbuf= bufnr("%")
2861    call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2862    exe bufwinnr(netrwbuf)."wincmd w"
2863    let treedir= "."
2864   endif
2865  endif
2866"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2867
2868  " determine if treedir is remote or local
2869  let islocal= expand("%") !~ '^\a\{3,}://'
2870"  call Decho("islocal=".islocal,'~'.expand("<slnum>"))
2871
2872  " browse the resulting directory
2873  if islocal
2874   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir))
2875  else
2876   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir))
2877  endif
2878
2879"  call Dret("netrw#SetTreetop")
2880endfun
2881
2882" ===========================================
2883" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
2884"    readcmd == %r : replace buffer with newly read file
2885"            == 0r : read file at top of buffer
2886"            == r  : read file after current line
2887"            == t  : leave file in temporary form (ie. don't read into buffer)
2888fun! s:NetrwGetFile(readcmd, tfile, method)
2889"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
2890
2891  " readcmd=='t': simply do nothing
2892  if a:readcmd == 't'
2893"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2894"   call Dret("NetrwGetFile : skip read of tfile<".a:tfile.">")
2895   return
2896  endif
2897
2898  " get name of remote filename (ie. url and all)
2899  let rfile= bufname("%")
2900"  call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
2901
2902  if exists("*NetReadFixup")
2903   " for the use of NetReadFixup (not otherwise used internally)
2904   let line2= line("$")
2905  endif
2906
2907  if a:readcmd[0] == '%'
2908  " get file into buffer
2909"   call Decho("get file into buffer",'~'.expand("<slnum>"))
2910
2911   " rename the current buffer to the temp file (ie. tfile)
2912   if g:netrw_cygwin
2913    let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2914   else
2915    let tfile= a:tfile
2916   endif
2917   call s:NetrwBufRename(tfile)
2918
2919   " edit temporary file (ie. read the temporary file in)
2920   if     rfile =~ '\.zip$'
2921"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2922    call zip#Browse(tfile)
2923   elseif rfile =~ '\.tar$'
2924"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2925    call tar#Browse(tfile)
2926   elseif rfile =~ '\.tar\.gz$'
2927"    call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2928    call tar#Browse(tfile)
2929   elseif rfile =~ '\.tar\.bz2$'
2930"    call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2931    call tar#Browse(tfile)
2932   elseif rfile =~ '\.tar\.xz$'
2933"    call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2934    call tar#Browse(tfile)
2935   elseif rfile =~ '\.txz$'
2936"    call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2937    call tar#Browse(tfile)
2938   else
2939"    call Decho("edit temporary file",'~'.expand("<slnum>"))
2940    NetrwKeepj e!
2941   endif
2942
2943   " rename buffer back to remote filename
2944   call s:NetrwBufRename(rfile)
2945
2946   " Detect filetype of local version of remote file.
2947   " Note that isk must not include a "/" for scripts.vim
2948   " to process this detection correctly.
2949"   call Decho("detect filetype of local version of remote file",'~'.expand("<slnum>"))
2950   let iskkeep= &l:isk
2951   setl isk-=/
2952   let &l:isk= iskkeep
2953"   call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
2954   let line1 = 1
2955   let line2 = line("$")
2956
2957  elseif !&ma
2958   " attempting to read a file after the current line in the file, but the buffer is not modifiable
2959   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2960"   call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2961   return
2962
2963  elseif s:FileReadable(a:tfile)
2964   " read file after current line
2965"   call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2966   let curline = line(".")
2967   let lastline= line("$")
2968"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline,'~'.expand("<slnum>"))
2969   exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2970   let line1= curline + 1
2971   let line2= line("$") - lastline + 1
2972
2973  else
2974   " not readable
2975"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2976"   call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2977   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2978"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2979   return
2980  endif
2981
2982  " User-provided (ie. optional) fix-it-up command
2983  if exists("*NetReadFixup")
2984"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2985   NetrwKeepj call NetReadFixup(a:method, line1, line2)
2986"  else " Decho
2987"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2988  endif
2989
2990  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
2991   " update the Buffers menu
2992   NetrwKeepj call s:UpdateBuffersMenu()
2993  endif
2994
2995"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
2996
2997 " make sure file is being displayed
2998"  redraw!
2999
3000"  call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3001"  call Dret("NetrwGetFile")
3002endfun
3003
3004" ------------------------------------------------------------------------
3005" s:NetrwMethod:  determine method of transfer {{{2
3006" Input:
3007"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
3008" Output:
3009"  b:netrw_method= 1: rcp
3010"                  2: ftp + <.netrc>
3011"	           3: ftp + machine, id, password, and [path]filename
3012"	           4: scp
3013"	           5: http[s] (wget)
3014"	           6: dav
3015"	           7: rsync
3016"	           8: fetch
3017"	           9: sftp
3018"	          10: file
3019"  g:netrw_machine= hostname
3020"  b:netrw_fname  = filename
3021"  g:netrw_port   = optional port number (for ftp)
3022"  g:netrw_choice = copy of input url (choice)
3023fun! s:NetrwMethod(choice)
3024"   call Dfunc("s:NetrwMethod(a:choice<".a:choice.">)")
3025
3026   " sanity check: choice should have at least three slashes in it
3027   if strlen(substitute(a:choice,'[^/]','','g')) < 3
3028    call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
3029    let b:netrw_method = -1
3030"    call Dret("s:NetrwMethod : incorrect url format<".a:choice.">")
3031    return
3032   endif
3033
3034   " record current g:netrw_machine, if any
3035   " curmachine used if protocol == ftp and no .netrc
3036   if exists("g:netrw_machine")
3037    let curmachine= g:netrw_machine
3038"    call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
3039   else
3040    let curmachine= "N O T A HOST"
3041   endif
3042   if exists("g:netrw_port")
3043    let netrw_port= g:netrw_port
3044   endif
3045
3046   " insure that netrw_ftp_cmd starts off every method determination
3047   " with the current g:netrw_ftp_cmd
3048   let s:netrw_ftp_cmd= g:netrw_ftp_cmd
3049
3050  " initialization
3051  let b:netrw_method  = 0
3052  let g:netrw_machine = ""
3053  let b:netrw_fname   = ""
3054  let g:netrw_port    = ""
3055  let g:netrw_choice  = a:choice
3056
3057  " Patterns:
3058  " mipf     : a:machine a:id password filename	     Use ftp
3059  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
3060  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
3061  " rcpurm   : rcp://[user@]host/filename	     Use rcp
3062  " rcphf    : [user@]host:filename		     Use rcp
3063  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
3064  " httpurm  : http[s]://[user@]host/filename	     Use wget
3065  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
3066  " rsyncurm : rsync://host[:port]/path              Use rsync
3067  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
3068  " sftpurm  : sftp://[user@]host/filename  Use scp
3069  " fileurm  : file://[user@]host/filename	     Use elinks or links
3070  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
3071  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
3072  let ftpurm   = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
3073  let rcpurm   = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
3074  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
3075  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
3076  let httpurm  = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
3077  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
3078  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
3079  let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
3080  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
3081  let fileurm  = '^file\=://\(.*\)$'
3082
3083"  call Decho("determine method:",'~'.expand("<slnum>"))
3084  " Determine Method
3085  " Method#1: rcp://user@hostname/...path-to-file {{{3
3086  if match(a:choice,rcpurm) == 0
3087"   call Decho("rcp://...",'~'.expand("<slnum>"))
3088   let b:netrw_method  = 1
3089   let userid          = substitute(a:choice,rcpurm,'\1',"")
3090   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
3091   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
3092   if userid != ""
3093    let g:netrw_uid= userid
3094   endif
3095
3096  " Method#4: scp://user@hostname/...path-to-file {{{3
3097  elseif match(a:choice,scpurm) == 0
3098"   call Decho("scp://...",'~'.expand("<slnum>"))
3099   let b:netrw_method  = 4
3100   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
3101   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
3102   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
3103
3104  " Method#5: http[s]://user@hostname/...path-to-file {{{3
3105  elseif match(a:choice,httpurm) == 0
3106"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3107   let b:netrw_method = 5
3108   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
3109   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
3110   let b:netrw_http   = (a:choice =~ '^https:')? "https" : "http"
3111
3112  " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
3113  elseif match(a:choice,davurm) == 0
3114"   call Decho("dav://...",'~'.expand("<slnum>"))
3115   let b:netrw_method= 6
3116   if a:choice =~ 'davs:'
3117    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
3118   else
3119    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
3120   endif
3121   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
3122
3123   " Method#7: rsync://user@hostname/...path-to-file {{{3
3124  elseif match(a:choice,rsyncurm) == 0
3125"   call Decho("rsync://...",'~'.expand("<slnum>"))
3126   let b:netrw_method = 7
3127   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
3128   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
3129
3130   " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
3131  elseif match(a:choice,ftpurm) == 0
3132"   call Decho("ftp://...",'~'.expand("<slnum>"))
3133   let userid	      = substitute(a:choice,ftpurm,'\2',"")
3134   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
3135   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
3136   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
3137"   call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3138   if userid != ""
3139    let g:netrw_uid= userid
3140   endif
3141
3142   if curmachine != g:netrw_machine
3143    if exists("s:netrw_hup[".g:netrw_machine."]")
3144     call NetUserPass("ftp:".g:netrw_machine)
3145    elseif exists("s:netrw_passwd")
3146     " if there's a change in hostname, require password re-entry
3147     unlet s:netrw_passwd
3148    endif
3149    if exists("netrw_port")
3150     unlet netrw_port
3151    endif
3152   endif
3153
3154   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3155    let b:netrw_method = 3
3156   else
3157    let host= substitute(g:netrw_machine,'\..*$','','')
3158    if exists("s:netrw_hup[host]")
3159     call NetUserPass("ftp:".host)
3160
3161    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~# '-[sS]:'
3162"     call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3163"     call Decho("          g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3164     if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
3165      let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3166"      call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3167     endif
3168     let b:netrw_method= 2
3169    elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3170"     call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3171     let b:netrw_method= 2
3172    else
3173     if !exists("g:netrw_uid") || g:netrw_uid == ""
3174      call NetUserPass()
3175     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3176      call NetUserPass(g:netrw_uid)
3177    " else just use current g:netrw_uid and s:netrw_passwd
3178     endif
3179     let b:netrw_method= 3
3180    endif
3181   endif
3182
3183  " Method#8: fetch {{{3
3184  elseif match(a:choice,fetchurm) == 0
3185"   call Decho("fetch://...",'~'.expand("<slnum>"))
3186   let b:netrw_method = 8
3187   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3188   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3189   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3190   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
3191
3192   " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
3193  elseif match(a:choice,mipf) == 0
3194"   call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
3195   let b:netrw_method  = 3
3196   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3197   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
3198   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
3199   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
3200   call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
3201
3202  " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3203  elseif match(a:choice,mf) == 0
3204"   call Decho("(ftp) host file",'~'.expand("<slnum>"))
3205   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3206    let b:netrw_method  = 3
3207    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3208    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3209
3210   elseif s:FileReadable(expand("$HOME/.netrc"))
3211    let b:netrw_method  = 2
3212    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3213    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3214   endif
3215
3216  " Method#9: sftp://user@hostname/...path-to-file {{{3
3217  elseif match(a:choice,sftpurm) == 0
3218"   call Decho("sftp://...",'~'.expand("<slnum>"))
3219   let b:netrw_method = 9
3220   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3221   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
3222
3223  " Method#1: Issue an rcp: hostname:filename"  (this one should be last) {{{3
3224  elseif match(a:choice,rcphf) == 0
3225"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3226   let b:netrw_method  = 1
3227   let userid          = substitute(a:choice,rcphf,'\2',"")
3228   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3229   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
3230"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3231"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3232"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3233"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3234   if userid != ""
3235    let g:netrw_uid= userid
3236   endif
3237
3238   " Method#10: file://user@hostname/...path-to-file {{{3
3239  elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
3240"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3241   let b:netrw_method = 10
3242   let b:netrw_fname  = substitute(a:choice,fileurm,'\1',"")
3243"   call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
3244
3245  " Cannot Determine Method {{{3
3246  else
3247   if !exists("g:netrw_quiet")
3248    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3249   endif
3250   let b:netrw_method  = -1
3251  endif
3252  "}}}3
3253
3254  if g:netrw_port != ""
3255   " remove any leading [:#] from port number
3256   let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
3257  elseif exists("netrw_port")
3258   " retain port number as implicit for subsequent ftp operations
3259   let g:netrw_port= netrw_port
3260  endif
3261
3262"  call Decho("a:choice       <".a:choice.">",'~'.expand("<slnum>"))
3263"  call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3264"  call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3265"  call Decho("g:netrw_port   <".g:netrw_port.">",'~'.expand("<slnum>"))
3266"  if exists("g:netrw_uid")		"Decho
3267"   call Decho("g:netrw_uid    <".g:netrw_uid.">",'~'.expand("<slnum>"))
3268"  endif					"Decho
3269"  if exists("s:netrw_passwd")		"Decho
3270"   call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3271"  endif					"Decho
3272"  call Decho("b:netrw_fname  <".b:netrw_fname.">",'~'.expand("<slnum>"))
3273"  call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
3274endfun
3275
3276" ------------------------------------------------------------------------
3277" NetReadFixup: this sort of function is typically written by the user {{{2
3278"               to handle extra junk that their system's ftp dumps
3279"               into the transfer.  This function is provided as an
3280"               example and as a fix for a Windows 95 problem: in my
3281"               experience, win95's ftp always dumped four blank lines
3282"               at the end of the transfer.
3283if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
3284 fun! NetReadFixup(method, line1, line2)
3285"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
3286
3287   " sanity checks -- attempt to convert inputs to integers
3288   let method = a:method + 0
3289   let line1  = a:line1 + 0
3290   let line2  = a:line2 + 0
3291   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
3292"    call Dret("NetReadFixup")
3293    return
3294   endif
3295
3296   if method == 3   " ftp (no <.netrc>)
3297    let fourblanklines= line2 - 3
3298    if fourblanklines >= line1
3299     exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
3300     call histdel("/",-1)
3301    endif
3302   endif
3303
3304"   call Dret("NetReadFixup")
3305 endfun
3306endif
3307
3308" ---------------------------------------------------------------------
3309" NetUserPass: set username and password for subsequent ftp transfer {{{2
3310"   Usage:  :call NetUserPass()		               -- will prompt for userid and password
3311"	    :call NetUserPass("uid")	               -- will prompt for password
3312"	    :call NetUserPass("uid","password")        -- sets global userid and password
3313"	    :call NetUserPass("ftp:host")              -- looks up userid and password using hup dictionary
3314"	    :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
3315fun! NetUserPass(...)
3316
3317" call Dfunc("NetUserPass() a:0=".a:0)
3318
3319 if !exists('s:netrw_hup')
3320  let s:netrw_hup= {}
3321 endif
3322
3323 if a:0 == 0
3324  " case: no input arguments
3325
3326  " change host and username if not previously entered; get new password
3327  if !exists("g:netrw_machine")
3328   let g:netrw_machine= input('Enter hostname: ')
3329  endif
3330  if !exists("g:netrw_uid") || g:netrw_uid == ""
3331   " get username (user-id) via prompt
3332   let g:netrw_uid= input('Enter username: ')
3333  endif
3334  " get password via prompting
3335  let s:netrw_passwd= inputsecret("Enter Password: ")
3336
3337  " set up hup database
3338  let host = substitute(g:netrw_machine,'\..*$','','')
3339  if !exists('s:netrw_hup[host]')
3340   let s:netrw_hup[host]= {}
3341  endif
3342  let s:netrw_hup[host].uid    = g:netrw_uid
3343  let s:netrw_hup[host].passwd = s:netrw_passwd
3344
3345 elseif a:0 == 1
3346  " case: one input argument
3347
3348  if a:1 =~ '^ftp:'
3349   " get host from ftp:... url
3350   " access userid and password from hup (host-user-passwd) dictionary
3351"   call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3352   let host = substitute(a:1,'^ftp:','','')
3353   let host = substitute(host,'\..*','','')
3354   if exists("s:netrw_hup[host]")
3355    let g:netrw_uid    = s:netrw_hup[host].uid
3356    let s:netrw_passwd = s:netrw_hup[host].passwd
3357"    call Decho("get s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3358"    call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3359   else
3360    let g:netrw_uid    = input("Enter UserId: ")
3361    let s:netrw_passwd = inputsecret("Enter Password: ")
3362   endif
3363
3364  else
3365   " case: one input argument, not an url.  Using it as a new user-id.
3366"   call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3367   if exists("g:netrw_machine")
3368    if g:netrw_machine =~ '[0-9.]\+'
3369     let host= g:netrw_machine
3370    else
3371     let host= substitute(g:netrw_machine,'\..*$','','')
3372    endif
3373   else
3374    let g:netrw_machine= input('Enter hostname: ')
3375   endif
3376   let g:netrw_uid = a:1
3377"   call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3378   if exists("g:netrw_passwd")
3379    " ask for password if one not previously entered
3380    let s:netrw_passwd= g:netrw_passwd
3381   else
3382    let s:netrw_passwd = inputsecret("Enter Password: ")
3383   endif
3384  endif
3385
3386"  call Decho("host<".host.">",'~'.expand("<slnum>"))
3387  if exists("host")
3388   if !exists('s:netrw_hup[host]')
3389    let s:netrw_hup[host]= {}
3390   endif
3391   let s:netrw_hup[host].uid    = g:netrw_uid
3392   let s:netrw_hup[host].passwd = s:netrw_passwd
3393  endif
3394
3395 elseif a:0 == 2
3396  let g:netrw_uid    = a:1
3397  let s:netrw_passwd = a:2
3398
3399 elseif a:0 == 3
3400  " enter hostname, user-id, and password into the hup dictionary
3401  let host = substitute(a:1,'^\a\+:','','')
3402  let host = substitute(host,'\..*$','','')
3403  if !exists('s:netrw_hup[host]')
3404   let s:netrw_hup[host]= {}
3405  endif
3406  let s:netrw_hup[host].uid    = a:2
3407  let s:netrw_hup[host].passwd = a:3
3408  let g:netrw_uid              = s:netrw_hup[host].uid
3409  let s:netrw_passwd           = s:netrw_hup[host].passwd
3410"  call Decho("set s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3411"  call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3412 endif
3413
3414" call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
3415endfun
3416
3417" =================================
3418"  Shared Browsing Support:    {{{1
3419" =================================
3420
3421" ---------------------------------------------------------------------
3422" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3423fun! s:ExplorePatHls(pattern)
3424"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
3425  let repat= substitute(a:pattern,'^**/\{1,2}','','')
3426"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3427  let repat= escape(repat,'][.\')
3428"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3429  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
3430"  call Dret("s:ExplorePatHls repat<".repat.">")
3431  return repat
3432endfun
3433
3434" ---------------------------------------------------------------------
3435"  s:NetrwBookHistHandler: {{{2
3436"    0: (user: <mb>)   bookmark current directory
3437"    1: (user: <gb>)   change to the bookmarked directory
3438"    2: (user: <qb>)   list bookmarks
3439"    3: (browsing)     records current directory history
3440"    4: (user: <u>)    go up   (previous) directory, using history
3441"    5: (user: <U>)    go down (next)     directory, using history
3442"    6: (user: <mB>)   delete bookmark
3443fun! s:NetrwBookHistHandler(chg,curdir)
3444"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhistcnt." histmax=".g:netrw_dirhistmax)
3445  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3446"   "  call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3447   return
3448  endif
3449
3450  let ykeep    = @@
3451  let curbufnr = bufnr("%")
3452
3453  if a:chg == 0
3454   " bookmark the current directory
3455"   call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3456   if exists("s:netrwmarkfilelist_{curbufnr}")
3457    call s:NetrwBookmark(0)
3458    echo "bookmarked marked files"
3459   else
3460    call s:MakeBookmark(a:curdir)
3461    echo "bookmarked the current directory"
3462   endif
3463
3464  elseif a:chg == 1
3465   " change to the bookmarked directory
3466"   call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3467   if exists("g:netrw_bookmarklist[v:count-1]")
3468"    call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3469    exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3470   else
3471    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3472   endif
3473
3474  elseif a:chg == 2
3475"   redraw!
3476   let didwork= 0
3477   " list user's bookmarks
3478"   call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3479   if exists("g:netrw_bookmarklist")
3480"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3481    let cnt= 1
3482    for bmd in g:netrw_bookmarklist
3483"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3484     echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3485     let didwork = 1
3486     let cnt     = cnt + 1
3487    endfor
3488   endif
3489
3490   " list directory history
3491   " Note: history is saved only when PerformListing is done;
3492   "       ie. when netrw can re-use a netrw buffer, the current directory is not saved in the history.
3493   let cnt     = g:netrw_dirhistcnt
3494   let first   = 1
3495   let histcnt = 0
3496   if g:netrw_dirhistmax > 0
3497    while ( first || cnt != g:netrw_dirhistcnt )
3498"    call Decho("first=".first." cnt=".cnt." dirhistcnt=".g:netrw_dirhistcnt,'~'.expand("<slnum>"))
3499     if exists("g:netrw_dirhist_{cnt}")
3500"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3501      echo printf("Netrw  History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3502      let didwork= 1
3503     endif
3504     let histcnt = histcnt + 1
3505     let first   = 0
3506     let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3507     if cnt < 0
3508      let cnt= cnt + g:netrw_dirhistmax
3509     endif
3510    endwhile
3511   else
3512    let g:netrw_dirhistcnt= 0
3513   endif
3514   if didwork
3515    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3516   endif
3517
3518  elseif a:chg == 3
3519   " saves most recently visited directories (when they differ)
3520"   call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3521   if !exists("g:netrw_dirhistcnt") || !exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") || g:netrw_dirhist_{g:netrw_dirhistcnt} != a:curdir
3522    if g:netrw_dirhistmax > 0
3523     let g:netrw_dirhistcnt                   = ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3524     let g:netrw_dirhist_{g:netrw_dirhistcnt} = a:curdir
3525    endif
3526"    call Decho("save dirhist#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3527   endif
3528
3529  elseif a:chg == 4
3530   " u: change to the previous directory stored on the history list
3531"   call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
3532   if g:netrw_dirhistmax > 0
3533    let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - v:count1 ) % g:netrw_dirhistmax
3534    if g:netrw_dirhistcnt < 0
3535     let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3536    endif
3537   else
3538    let g:netrw_dirhistcnt= 0
3539   endif
3540   if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3541"    call Decho("changedir u#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3542    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3543     setl ma noro
3544"     call Decho("setl ma noro",'~'.expand("<slnum>"))
3545     sil! NetrwKeepj %d _
3546     setl nomod
3547"     call Decho("setl nomod",'~'.expand("<slnum>"))
3548"     call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3549    endif
3550"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3551    exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3552   else
3553    if g:netrw_dirhistmax > 0
3554     let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + v:count1 ) % g:netrw_dirhistmax
3555    else
3556     let g:netrw_dirhistcnt= 0
3557    endif
3558    echo "Sorry, no predecessor directory exists yet"
3559   endif
3560
3561  elseif a:chg == 5
3562   " U: change to the subsequent directory stored on the history list
3563"   call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3564   if g:netrw_dirhistmax > 0
3565    let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3566    if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3567"    call Decho("changedir U#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3568     if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3569"      call Decho("setl ma noro",'~'.expand("<slnum>"))
3570      setl ma noro
3571      sil! NetrwKeepj %d _
3572"      call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3573"      call Decho("setl nomod",'~'.expand("<slnum>"))
3574      setl nomod
3575"      call Decho("(set nomod)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3576     endif
3577"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3578     exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3579    else
3580     let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - 1 ) % g:netrw_dirhistmax
3581     if g:netrw_dirhistcnt < 0
3582      let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3583     endif
3584     echo "Sorry, no successor directory exists yet"
3585    endif
3586   else
3587    let g:netrw_dirhistcnt= 0
3588    echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
3589   endif
3590
3591  elseif a:chg == 6
3592"   call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3593   if exists("s:netrwmarkfilelist_{curbufnr}")
3594    call s:NetrwBookmark(1)
3595    echo "removed marked files from bookmarks"
3596   else
3597    " delete the v:count'th bookmark
3598    let iremove = v:count
3599    let dremove = g:netrw_bookmarklist[iremove - 1]
3600"    call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3601    call s:MergeBookmarks()
3602"    call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3603    NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3604    echo "removed ".dremove." from g:netrw_bookmarklist"
3605"    call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3606   endif
3607"   call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3608  endif
3609  call s:NetrwBookmarkMenu()
3610  call s:NetrwTgtMenu()
3611  let @@= ykeep
3612"  call Dret("s:NetrwBookHistHandler")
3613endfun
3614
3615" ---------------------------------------------------------------------
3616" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
3617"  Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
3618"                      Sister function: s:NetrwBookHistSave()
3619fun! s:NetrwBookHistRead()
3620"  call Dfunc("s:NetrwBookHistRead()")
3621  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3622"   call Dret("s:NetrwBookHistRead - nothing read (suppressed due to dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a").")")
3623   return
3624  endif
3625  let ykeep= @@
3626
3627  " read bookmarks
3628  if !exists("s:netrw_initbookhist")
3629   let home    = s:NetrwHome()
3630   let savefile= home."/.netrwbook"
3631   if filereadable(s:NetrwFile(savefile))
3632"    call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3633    exe "keepalt NetrwKeepj so ".savefile
3634   endif
3635
3636   " read history
3637   if g:netrw_dirhistmax > 0
3638    let savefile= home."/.netrwhist"
3639    if filereadable(s:NetrwFile(savefile))
3640"    call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3641     exe "keepalt NetrwKeepj so ".savefile
3642    endif
3643    let s:netrw_initbookhist= 1
3644    au VimLeave * call s:NetrwBookHistSave()
3645   endif
3646  endif
3647
3648  let @@= ykeep
3649"  call Decho("dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a"),'~'.expand("<slnum>"))
3650"  call Decho("dirhistcnt=".(exists("g:netrw_dirhistcnt")? g:netrw_dirhistcnt : "n/a"),'~'.expand("<slnum>"))
3651"  call Dret("s:NetrwBookHistRead")
3652endfun
3653
3654" ---------------------------------------------------------------------
3655" s:NetrwBookHistSave: this function saves bookmarks and history to files {{{2
3656"                      Sister function: s:NetrwBookHistRead()
3657"                      I used to do this via viminfo but that appears to
3658"                      be unreliable for long-term storage
3659"                      If g:netrw_dirhistmax is <= 0, no history or bookmarks
3660"                      will be saved.
3661"                      (s:NetrwBookHistHandler(3,...) used to record history)
3662fun! s:NetrwBookHistSave()
3663"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt)
3664  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3665"   call Dret("s:NetrwBookHistSave : nothing saved (dirhistmax=".g:netrw_dirhistmax.")")
3666   return
3667  endif
3668
3669  let savefile= s:NetrwHome()."/.netrwhist"
3670"  call Decho("savefile<".savefile.">",'~'.expand("<slnum>"))
3671  1split
3672
3673  " setting up a new buffer which will become .netrwhist
3674  call s:NetrwEnew()
3675"  call Decho("case g:netrw_use_noswf=".g:netrw_use_noswf.(exists("+acd")? " +acd" : " -acd"),'~'.expand("<slnum>"))
3676  if g:netrw_use_noswf
3677   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
3678  else
3679   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
3680  endif
3681  setl nocin noai noci magic nospell nohid wig= noaw
3682  setl ma noro write
3683  if exists("+acd") | setl noacd | endif
3684  sil! NetrwKeepj keepalt %d _
3685
3686  " rename enew'd file: .netrwhist -- no attempt to merge
3687  " record dirhistmax and current dirhistcnt
3688  " save history
3689"  call Decho("saving history: dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt." lastline=".line("$"),'~'.expand("<slnum>"))
3690  sil! keepalt file .netrwhist
3691  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
3692  call setline(2,"let g:netrw_dirhistcnt =".g:netrw_dirhistcnt)
3693  if g:netrw_dirhistmax > 0
3694   let lastline = line("$")
3695   let cnt      = g:netrw_dirhistcnt
3696   let first    = 1
3697   while ( first || cnt != g:netrw_dirhistcnt )
3698    let lastline= lastline + 1
3699    if exists("g:netrw_dirhist_{cnt}")
3700     call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3701"     call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("<slnum>"))
3702    endif
3703    let first   = 0
3704    let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3705    if cnt < 0
3706     let cnt= cnt + g:netrw_dirhistmax
3707    endif
3708   endwhile
3709   exe "sil! w! ".savefile
3710"   call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
3711  endif
3712
3713  " save bookmarks
3714  sil NetrwKeepj %d _
3715  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
3716"   call Decho("saving bookmarks",'~'.expand("<slnum>"))
3717   " merge and write .netrwbook
3718   let savefile= s:NetrwHome()."/.netrwbook"
3719
3720   if filereadable(s:NetrwFile(savefile))
3721    let booklist= deepcopy(g:netrw_bookmarklist)
3722    exe "sil NetrwKeepj keepalt so ".savefile
3723    for bdm in booklist
3724     if index(g:netrw_bookmarklist,bdm) == -1
3725      call add(g:netrw_bookmarklist,bdm)
3726     endif
3727    endfor
3728    call sort(g:netrw_bookmarklist)
3729   endif
3730
3731   " construct and save .netrwbook
3732   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3733   exe "sil! w! ".savefile
3734"   call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
3735  endif
3736
3737  " cleanup -- remove buffer used to construct history
3738  let bgone= bufnr("%")
3739  q!
3740  exe "keepalt ".bgone."bwipe!"
3741
3742"  call Dret("s:NetrwBookHistSave")
3743endfun
3744
3745" ---------------------------------------------------------------------
3746" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3747"  list of the contents of a local or remote directory.  It is assumed that the
3748"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3749"  with the requested remote hostname first.
3750"    Often called via:  Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
3751fun! s:NetrwBrowse(islocal,dirname)
3752  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
3753"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
3754"  call Decho("fyi: modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
3755"  call Decho("fyi: tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3756"  call Dredir("ls!","s:NetrwBrowse")
3757
3758  " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3759  " This is useful when one edits a local file, then :e ., then :Rex
3760  if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
3761   let w:netrw_rexfile= bufname("#")
3762"   call Decho("setting w:netrw_rexfile<".w:netrw_rexfile."> win#".winnr(),'~'.expand("<slnum>"))
3763  endif
3764
3765  " s:NetrwBrowse : initialize history {{{3
3766  if !exists("s:netrw_initbookhist")
3767   NetrwKeepj call s:NetrwBookHistRead()
3768  endif
3769
3770  " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
3771  if a:dirname !~ '^\a\{3,}://'
3772   let dirname= simplify(a:dirname)
3773"   call Decho("simplified dirname<".dirname.">")
3774  else
3775   let dirname= a:dirname
3776  endif
3777
3778  " repoint t:netrw_lexbufnr if appropriate
3779  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
3780"   call Decho("set repointlexbufnr to true!")
3781   let repointlexbufnr= 1
3782  endif
3783
3784  " s:NetrwBrowse : sanity checks: {{{3
3785  if exists("s:netrw_skipbrowse")
3786   unlet s:netrw_skipbrowse
3787"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("<slnum>"))
3788"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed")
3789   return
3790  endif
3791  if !exists("*shellescape")
3792   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3793"   call Dret("s:NetrwBrowse : missing shellescape()")
3794   return
3795  endif
3796  if !exists("*fnameescape")
3797   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3798"   call Dret("s:NetrwBrowse : missing fnameescape()")
3799   return
3800  endif
3801
3802  " s:NetrwBrowse : save options: {{{3
3803  call s:NetrwOptionsSave("w:")
3804
3805  " s:NetrwBrowse : re-instate any marked files {{{3
3806  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3807   if exists("s:netrwmarkfilelist_{bufnr('%')}")
3808"    call Decho("clearing marked files",'~'.expand("<slnum>"))
3809    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3810   endif
3811  endif
3812
3813  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
3814   " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3815"   call Decho("handle w:netrw_acdkeep:",'~'.expand("<slnum>"))
3816"   call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("<slnum>"))
3817   if s:NetrwLcd(dirname)
3818"    call Dret("s:NetrwBrowse : lcd failure")
3819    return
3820   endif
3821   "   call s:NetrwOptionsSafe() " tst952 failed with this enabled.
3822"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
3823
3824  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
3825   " s:NetrwBrowse :  remote regular file handler {{{3
3826"   call Decho("handle remote regular file: dirname<".dirname.">",'~'.expand("<slnum>"))
3827   if bufname(dirname) != ""
3828"    call Decho("edit buf#".bufname(dirname)." in win#".winnr(),'~'.expand("<slnum>"))
3829    exe "NetrwKeepj b ".bufname(dirname)
3830   else
3831    " attempt transfer of remote regular file
3832"    call Decho("attempt transfer as regular file<".dirname.">",'~'.expand("<slnum>"))
3833
3834    " remove any filetype indicator from end of dirname, except for the
3835    " "this is a directory" indicator (/).
3836    " There shouldn't be one of those here, anyway.
3837    let path= substitute(dirname,'[*=@|]\r\=$','','e')
3838"    call Decho("new path<".path.">",'~'.expand("<slnum>"))
3839    call s:RemotePathAnalysis(dirname)
3840
3841    " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3842    call s:NetrwEnew(dirname)
3843    call s:NetrwOptionsSafe(a:islocal)
3844    setl ma noro
3845"    call Decho("setl ma noro",'~'.expand("<slnum>"))
3846    let b:netrw_curdir = dirname
3847    let url            = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3848    call s:NetrwBufRename(url)
3849    exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3850    sil call netrw#NetRead(2,url)
3851    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3852"    call Decho("url<".url.">",'~'.expand("<slnum>"))
3853"    call Decho("s:path<".s:path.">",'~'.expand("<slnum>"))
3854"    call Decho("s:fname<".s:fname.">",'~'.expand("<slnum>"))
3855    if s:path =~ '.bz2'
3856     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3857    elseif s:path =~ '.gz'
3858     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3859    elseif s:path =~ '.gz'
3860     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3861    else
3862     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3863    endif
3864   endif
3865
3866   " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3867   call s:SetBufWinVars()
3868   call s:NetrwOptionsRestore("w:")
3869"   call Decho("setl ma nomod",'~'.expand("<slnum>"))
3870   setl ma nomod noro
3871"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3872
3873"   call Dret("s:NetrwBrowse : file<".s:fname.">")
3874   return
3875  endif
3876
3877  " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
3878  call s:UseBufWinVars()
3879
3880  " set up some variables {{{3
3881  let b:netrw_browser_active = 1
3882  let dirname                = dirname
3883  let s:last_sort_by         = g:netrw_sort_by
3884
3885  " set up menu {{{3
3886  NetrwKeepj call s:NetrwMenu(1)
3887
3888  " get/set-up buffer {{{3
3889"  call Decho("saving position across a buffer refresh",'~'.expand("<slnum>"))
3890  let svpos  = winsaveview()
3891"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3892  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
3893
3894  " maintain markfile highlighting
3895  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3896   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3897" "   call Decho("bufnr(%)=".bufnr('%'),'~'.expand("<slnum>"))
3898" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
3899    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3900   else
3901" "   call Decho("2match none",'~'.expand("<slnum>"))
3902    2match none
3903   endif
3904  endif
3905  if reusing && line("$") > 1
3906   call s:NetrwOptionsRestore("w:")
3907"   call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3908   setl noma nomod nowrap
3909"   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>"))
3910"   call Dret("s:NetrwBrowse : re-using not-cleared buffer")
3911   return
3912  endif
3913
3914  " set b:netrw_curdir to the new directory name {{{3
3915"  call Decho("set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")",'~'.expand("<slnum>"))
3916  let b:netrw_curdir= dirname
3917  if b:netrw_curdir =~ '[/\\]$'
3918   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
3919  endif
3920  if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
3921   let b:netrw_curdir= b:netrw_curdir."/"
3922  endif
3923  if b:netrw_curdir == ''
3924   if has("amiga")
3925    " On the Amiga, the empty string connotes the current directory
3926    let b:netrw_curdir= getcwd()
3927   else
3928    " under unix, when the root directory is encountered, the result
3929    " from the preceding substitute is an empty string.
3930    let b:netrw_curdir= '/'
3931   endif
3932  endif
3933  if !a:islocal && b:netrw_curdir !~ '/$'
3934   let b:netrw_curdir= b:netrw_curdir.'/'
3935  endif
3936"  call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
3937
3938  " ------------
3939  " (local only) {{{3
3940  " ------------
3941  if a:islocal
3942"   call Decho("local only:",'~'.expand("<slnum>"))
3943
3944   " Set up ShellCmdPost handling.  Append current buffer to browselist
3945   call s:LocalFastBrowser()
3946
3947  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3948   if !g:netrw_keepdir
3949"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
3950"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("<slnum>"))
3951    if !exists("&l:acd") || !&l:acd
3952     if s:NetrwLcd(b:netrw_curdir)
3953"      call Dret("s:NetrwBrowse : lcd failure")
3954      return
3955     endif
3956    endif
3957   endif
3958
3959  " --------------------------------
3960  " remote handling: {{{3
3961  " --------------------------------
3962  else
3963"   call Decho("remote only:",'~'.expand("<slnum>"))
3964
3965   " analyze dirname and g:netrw_list_cmd {{{3
3966"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>"))
3967   if dirname =~# "^NetrwTreeListing\>"
3968    let dirname= b:netrw_curdir
3969"    call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>"))
3970   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3971    let dirname= substitute(b:netrw_curdir,'\\','/','g')
3972    if dirname !~ '/$'
3973     let dirname= dirname.'/'
3974    endif
3975    let b:netrw_curdir = dirname
3976"    call Decho("(liststyle is TREELIST) dirname<".dirname.">",'~'.expand("<slnum>"))
3977   else
3978    let dirname = substitute(dirname,'\\','/','g')
3979"    call Decho("(normal) dirname<".dirname.">",'~'.expand("<slnum>"))
3980   endif
3981
3982   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3983   if dirname !~ dirpat
3984    if !exists("g:netrw_quiet")
3985     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3986    endif
3987    NetrwKeepj call s:NetrwOptionsRestore("w:")
3988"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3989    setl noma nomod nowrap
3990"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3991"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
3992    return
3993   endif
3994   let b:netrw_curdir= dirname
3995"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("<slnum>"))
3996  endif  " (additional remote handling)
3997
3998  " -------------------------------
3999  " Perform Directory Listing: {{{3
4000  " -------------------------------
4001  NetrwKeepj call s:NetrwMaps(a:islocal)
4002  NetrwKeepj call s:NetrwCommands(a:islocal)
4003  NetrwKeepj call s:PerformListing(a:islocal)
4004
4005  " restore option(s)
4006  call s:NetrwOptionsRestore("w:")
4007"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4008
4009  " If there is a rexposn: restore position with rexposn
4010  " Otherwise            : set rexposn
4011  if exists("s:rexposn_".bufnr("%"))
4012"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
4013   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
4014   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4015    NetrwKeepj exe w:netrw_bannercnt
4016   endif
4017  else
4018   NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
4019  endif
4020  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
4021   let &l:bexpr= "netrw#BalloonHelp()"
4022"   call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>"))
4023   setl beval
4024  endif
4025
4026  " repoint t:netrw_lexbufnr if appropriate
4027  if exists("repointlexbufnr")
4028   let t:netrw_lexbufnr= bufnr("%")
4029"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
4030  endif
4031
4032  " restore position
4033  if reusing
4034"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4035   call winrestview(svpos)
4036  endif
4037
4038  " The s:LocalBrowseRefresh() function is called by an autocmd
4039  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow or medium speed).
4040  " However, s:NetrwBrowse() causes the FocusGained event to fire the first time.
4041"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4042"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4043"  call Dret("s:NetrwBrowse : did PerformListing  ft<".&ft.">")
4044  return
4045endfun
4046
4047" ---------------------------------------------------------------------
4048" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
4049" may not apply correctly; ie. netrw's idea of the current directory may
4050" differ from vim's.  This function insures that netrw's idea of the current
4051" directory is used.
4052" Returns a path to the file specified by a:fname
4053fun! s:NetrwFile(fname)
4054"  "" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
4055"  "" call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
4056"  "" call Decho("g:netrw_cygwin   =".(exists("g:netrw_cygwin")?    g:netrw_cygwin    : 'n/a'),'~'.expand("<slnum>"))
4057"  "" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
4058"  "" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
4059
4060  " clean up any leading treedepthstring
4061  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4062   let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
4063"   "" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>"))
4064  else
4065   let fname= a:fname
4066  endif
4067
4068  if g:netrw_keepdir
4069   " vim's idea of the current directory possibly may differ from netrw's
4070   if !exists("b:netrw_curdir")
4071    let b:netrw_curdir= getcwd()
4072   endif
4073
4074   if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
4075    if fname =~ '^\' || fname =~ '^\a:\'
4076     " windows, but full path given
4077     let ret= fname
4078"     "" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4079    else
4080     " windows, relative path given
4081     let ret= s:ComposePath(b:netrw_curdir,fname)
4082"     "" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4083    endif
4084
4085   elseif fname =~ '^/'
4086    " not windows, full path given
4087    let ret= fname
4088"    "" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4089   else
4090    " not windows, relative path given
4091    let ret= s:ComposePath(b:netrw_curdir,fname)
4092"    "" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4093   endif
4094  else
4095   " vim and netrw agree on the current directory
4096   let ret= fname
4097"   "" call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
4098"   "" call Decho("vim   directory: ".getcwd(),'~'.expand("<slnum>"))
4099"   "" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>"))
4100  endif
4101
4102"  "" call Dret("s:NetrwFile ".ret)
4103  return ret
4104endfun
4105
4106" ---------------------------------------------------------------------
4107" s:NetrwFileInfo: supports qf (query for file information) {{{2
4108fun! s:NetrwFileInfo(islocal,fname)
4109"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
4110  let ykeep= @@
4111  if a:islocal
4112   let lsopt= "-lsad"
4113   if g:netrw_sizestyle =~# 'H'
4114    let lsopt= "-lsadh"
4115   elseif g:netrw_sizestyle =~# 'h'
4116    let lsopt= "-lsadh --si"
4117   endif
4118   if (has("unix") || has("macunix")) && executable("/bin/ls")
4119
4120    if getline(".") == "../"
4121     echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
4122"     call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
4123
4124    elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
4125     echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
4126"     call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
4127
4128    elseif exists("b:netrw_curdir")
4129      echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
4130"      call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
4131
4132    else
4133"     call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
4134     echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
4135"     call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
4136    endif
4137   else
4138    " use vim functions to return information about file below cursor
4139"    call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
4140    if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
4141     let fname= substitute(a:fname,".$","","")
4142    else
4143     let fname= a:fname
4144    endif
4145    let t  = getftime(s:NetrwFile(fname))
4146    let sz = getfsize(s:NetrwFile(fname))
4147    if g:netrw_sizestyle =~# "[hH]"
4148     let sz= s:NetrwHumanReadable(sz)
4149    endif
4150    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
4151"    call Decho("fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
4152   endif
4153  else
4154   echo "sorry, \"qf\" not supported yet for remote files"
4155  endif
4156  let @@= ykeep
4157"  call Dret("s:NetrwFileInfo")
4158endfun
4159
4160" ---------------------------------------------------------------------
4161" s:NetrwFullPath: returns the full path to a directory and/or file {{{2
4162fun! s:NetrwFullPath(filename)
4163"  " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)")
4164  let filename= a:filename
4165  if filename !~ '^/'
4166   let filename= resolve(getcwd().'/'.filename)
4167  endif
4168  if filename != "/" && filename =~ '/$'
4169   let filename= substitute(filename,'/$','','')
4170  endif
4171"  " call Dret("s:NetrwFullPath <".filename.">")
4172  return filename
4173endfun
4174
4175" ---------------------------------------------------------------------
4176" s:NetrwGetBuffer: [get a new|find an old netrw] buffer for a netrw listing {{{2
4177"   returns 0=cleared buffer
4178"           1=re-used buffer (buffer not cleared)
4179fun! s:NetrwGetBuffer(islocal,dirname)
4180"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
4181"  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>"))
4182"  call Decho("netrwbuf dictionary=".(exists("s:netrwbuf")? string(s:netrwbuf) : 'n/a'),'~'.expand("<slnum>"))
4183"  call Dredir("ls!","s:NetrwGetBuffer")
4184  let dirname= a:dirname
4185
4186  " re-use buffer if possible {{{3
4187"  call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
4188  if !exists("s:netrwbuf")
4189"   call Decho("  s:netrwbuf initialized to {}",'~'.expand("<slnum>"))
4190   let s:netrwbuf= {}
4191  endif
4192"  call Decho("  s:netrwbuf         =".string(s:netrwbuf),'~'.expand("<slnum>"))
4193"  call Decho("  w:netrw_liststyle  =".(exists("w:netrw_liststyle")? w:netrw_liststyle : "n/a"),'~'.expand("<slnum>"))
4194
4195  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4196   let bufnum = -1
4197
4198   if !empty(s:netrwbuf) && has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4199    if has_key(s:netrwbuf,"NetrwTreeListing")
4200     let bufnum= s:netrwbuf["NetrwTreeListing"]
4201    else
4202     let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4203    endif
4204"    call Decho("  NetrwTreeListing: bufnum#".bufnum,'~'.expand("<slnum>"))
4205    if !bufexists(bufnum)
4206     call remove(s:netrwbuf,"NetrwTreeListing"])
4207     let bufnum= -1
4208    endif
4209   elseif bufnr("NetrwTreeListing") != -1
4210    let bufnum= bufnr("NetrwTreeListing")
4211"    call Decho("  NetrwTreeListing".": bufnum#".bufnum,'~'.expand("<slnum>"))
4212   else
4213"    call Decho("  did not find a NetrwTreeListing buffer",'~'.expand("<slnum>"))
4214     let bufnum= -1
4215   endif
4216
4217  elseif has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4218   let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4219"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum,'~'.expand("<slnum>"))
4220   if !bufexists(bufnum)
4221    call remove(s:netrwbuf,s:NetrwFullPath(dirname))
4222    let bufnum= -1
4223   endif
4224
4225  else
4226"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key",'~'.expand("<slnum>"))
4227   let bufnum= -1
4228  endif
4229"  call Decho("  bufnum#".bufnum,'~'.expand("<slnum>"))
4230
4231  " highjack the current buffer if
4232  "   it has the desired name
4233  "   it is empty
4234"  call Decho("deciding if I can highjack the current buffer#".bufnr("%"),'~'.expand("<slnum>"))
4235"  call Decho("..dirname<".dirname.">",'~'.expand("<slnum>"))
4236"  call Decho("..bufname<".bufname("%").">",'~'.expand("<slnum>"))
4237"  call Decho("..getline($)<".getline("$").">",'~'.expand("<slnum>"))
4238  if dirname == bufname("%") && line("$") == 1 && getline("%") == ""
4239"   call Dret("s:NetrwGetBuffer 0<cleared buffer> : highjacking buffer#".bufnr("%"))
4240   return 0
4241  endif
4242
4243  " get enew buffer and name it -or- re-use buffer {{{3
4244  if bufnum < 0      " get enew buffer and name it
4245"   call Decho("--get enew buffer and name it  (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4246   call s:NetrwEnew(dirname)
4247"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4248   " name the buffer
4249   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4250    " Got enew buffer; transform into a NetrwTreeListing
4251"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4252    let w:netrw_treebufnr = bufnr("%")
4253    call s:NetrwBufRename("NetrwTreeListing")
4254    if g:netrw_use_noswf
4255     setl nobl bt=nofile noswf
4256    else
4257     setl nobl bt=nofile
4258    endif
4259    nnoremap <silent> <buffer> [[       :sil call <SID>TreeListMove('[[')<cr>
4260    nnoremap <silent> <buffer> ]]       :sil call <SID>TreeListMove(']]')<cr>
4261    nnoremap <silent> <buffer> []       :sil call <SID>TreeListMove('[]')<cr>
4262    nnoremap <silent> <buffer> ][       :sil call <SID>TreeListMove('][')<cr>
4263"    call Decho("  tree listing bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
4264   else
4265    call s:NetrwBufRename(dirname)
4266    " enter the new buffer into the s:netrwbuf dictionary
4267    let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%")
4268"    call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>"))
4269"    call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
4270   endif
4271"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4272
4273  else " Re-use the buffer
4274"   call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4275   let eikeep= &ei
4276   setl ei=all
4277   if getline(2) =~# '^" Netrw Directory Listing'
4278"    call Decho("  getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>"))
4279    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4280   else
4281"    call Decho("  getline(2)<".getline(2).'> does not match "Netrw Directory Listing" : using b '.bufnum,'~'.expand("<slnum>"))
4282    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4283   endif
4284"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
4285   if bufname("%") == '.'
4286    call s:NetrwBufRename(getcwd())
4287   endif
4288   let &ei= eikeep
4289
4290   if line("$") <= 1 && getline(1) == ""
4291    " empty buffer
4292    NetrwKeepj call s:NetrwListSettings(a:islocal)
4293"    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>"))
4294"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4295"    call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4296    return 0
4297
4298   elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4299"    call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4300    NetrwKeepj call s:NetrwListSettings(a:islocal)
4301    sil NetrwKeepj %d _
4302"    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>"))
4303"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4304"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4305    return 0
4306
4307   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4308"    call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4309"    call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4310    setl ma
4311    sil NetrwKeepj %d _
4312    NetrwKeepj call s:NetrwListSettings(a:islocal)
4313"    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>"))
4314"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4315"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4316    return 0
4317
4318   else
4319"    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>"))
4320"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4321"    call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4322    return 1
4323   endif
4324  endif
4325
4326  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4327  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
4328  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
4329  "  med    1         D      H
4330  "  fast   2         H      H
4331"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
4332  let fname= expand("%")
4333  NetrwKeepj call s:NetrwListSettings(a:islocal)
4334  call s:NetrwBufRename(fname)
4335
4336  " delete all lines from buffer {{{3
4337"  call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4338"  call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4339  sil! keepalt NetrwKeepj %d _
4340
4341"  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>"))
4342"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4343"  call Dret("s:NetrwGetBuffer 0<cleared buffer>")
4344  return 0
4345endfun
4346
4347" ---------------------------------------------------------------------
4348" s:NetrwGetcwd: get the current directory. {{{2
4349"   Change backslashes to forward slashes, if any.
4350"   If doesc is true, escape certain troublesome characters
4351fun! s:NetrwGetcwd(doesc)
4352"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
4353  let curdir= substitute(getcwd(),'\\','/','ge')
4354  if curdir !~ '[\/]$'
4355   let curdir= curdir.'/'
4356  endif
4357  if a:doesc
4358   let curdir= fnameescape(curdir)
4359  endif
4360"  call Dret("NetrwGetcwd <".curdir.">")
4361  return curdir
4362endfun
4363
4364" ---------------------------------------------------------------------
4365"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4366fun! s:NetrwGetWord()
4367"  call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4368"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4369  let keepsol= &l:sol
4370  setl nosol
4371
4372  call s:UseBufWinVars()
4373
4374  " insure that w:netrw_liststyle is set up
4375  if !exists("w:netrw_liststyle")
4376   if exists("g:netrw_liststyle")
4377    let w:netrw_liststyle= g:netrw_liststyle
4378   else
4379    let w:netrw_liststyle= s:THINLIST
4380   endif
4381"   call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
4382  endif
4383
4384  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4385   " Active Banner support
4386"   call Decho("active banner handling",'~'.expand("<slnum>"))
4387   NetrwKeepj norm! 0
4388   let dirname= "./"
4389   let curline= getline('.')
4390
4391   if curline =~# '"\s*Sorted by\s'
4392    NetrwKeepj norm! "_s
4393    let s:netrw_skipbrowse= 1
4394    echo 'Pressing "s" also works'
4395
4396   elseif curline =~# '"\s*Sort sequence:'
4397    let s:netrw_skipbrowse= 1
4398    echo 'Press "S" to edit sorting sequence'
4399
4400   elseif curline =~# '"\s*Quick Help:'
4401    NetrwKeepj norm! ?
4402    let s:netrw_skipbrowse= 1
4403
4404   elseif curline =~# '"\s*\%(Hiding\|Showing\):'
4405    NetrwKeepj norm! a
4406    let s:netrw_skipbrowse= 1
4407    echo 'Pressing "a" also works'
4408
4409   elseif line("$") > w:netrw_bannercnt
4410    exe 'sil NetrwKeepj '.w:netrw_bannercnt
4411   endif
4412
4413  elseif w:netrw_liststyle == s:THINLIST
4414"   call Decho("thin column handling",'~'.expand("<slnum>"))
4415   NetrwKeepj norm! 0
4416   let dirname= substitute(getline('.'),'\t -->.*$','','')
4417
4418  elseif w:netrw_liststyle == s:LONGLIST
4419"   call Decho("long column handling",'~'.expand("<slnum>"))
4420   NetrwKeepj norm! 0
4421   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
4422
4423  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4424"   call Decho("treelist handling",'~'.expand("<slnum>"))
4425   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4426   let dirname= substitute(dirname,'\t -->.*$','','')
4427
4428  else
4429"   call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4430   let dirname= getline('.')
4431
4432   if !exists("b:netrw_cpf")
4433    let b:netrw_cpf= 0
4434    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
4435    call histdel("/",-1)
4436"   "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4437   endif
4438
4439"   call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4440   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4441"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4442"   call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4443   if filestart == 0
4444    NetrwKeepj norm! 0ma
4445   else
4446    call cursor(line("."),filestart+1)
4447    NetrwKeepj norm! ma
4448   endif
4449   let rega= @a
4450   let eofname= filestart + b:netrw_cpf + 1
4451   if eofname <= col("$")
4452    call cursor(line("."),filestart+b:netrw_cpf+1)
4453    NetrwKeepj norm! "ay`a
4454   else
4455    NetrwKeepj norm! "ay$
4456   endif
4457   let dirname = @a
4458   let @a      = rega
4459"   call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4460   let dirname= substitute(dirname,'\s\+$','','e')
4461"   call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4462  endif
4463
4464  " symlinks are indicated by a trailing "@".  Remove it before further processing.
4465  let dirname= substitute(dirname,"@$","","")
4466
4467  " executables are indicated by a trailing "*".  Remove it before further processing.
4468  let dirname= substitute(dirname,"\*$","","")
4469
4470  let &l:sol= keepsol
4471
4472"  call Dret("s:NetrwGetWord <".dirname.">")
4473  return dirname
4474endfun
4475
4476" ---------------------------------------------------------------------
4477" s:NetrwListSettings: make standard settings for making a netrw listing {{{2
4478"                      g:netrw_bufsettings will be used after the listing is produced.
4479"                      Called by s:NetrwGetBuffer()
4480fun! s:NetrwListSettings(islocal)
4481"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4482"  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>"))
4483  let fname= bufname("%")
4484"  "  call Decho("setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
4485  "              nobl noma nomod nonu noma nowrap ro   nornu  (std g:netrw_bufsettings)
4486  setl bt=nofile nobl ma         nonu      nowrap noro nornu
4487  call s:NetrwBufRename(fname)
4488  if g:netrw_use_noswf
4489   setl noswf
4490  endif
4491"  call Dredir("ls!","s:NetrwListSettings")
4492"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
4493  exe "setl ts=".(g:netrw_maxfilenamelen+1)
4494  setl isk+=.,~,-
4495  if g:netrw_fastbrowse > a:islocal
4496   setl bh=hide
4497  else
4498   setl bh=delete
4499  endif
4500"  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>"))
4501"  call Dret("s:NetrwListSettings")
4502endfun
4503
4504" ---------------------------------------------------------------------
4505"  s:NetrwListStyle: change list style (thin - long - wide - tree) {{{2
4506"  islocal=0: remote browsing
4507"         =1: local browsing
4508fun! s:NetrwListStyle(islocal)
4509"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
4510
4511  let ykeep             = @@
4512  let fname             = s:NetrwGetWord()
4513  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
4514  let svpos            = winsaveview()
4515"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4516  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
4517"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
4518"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>"))
4519"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
4520
4521  " repoint t:netrw_lexbufnr if appropriate
4522  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
4523"   call Decho("set repointlexbufnr to true!")
4524   let repointlexbufnr= 1
4525  endif
4526
4527  if w:netrw_liststyle == s:THINLIST
4528   " use one column listing
4529"   call Decho("use one column list",'~'.expand("<slnum>"))
4530   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4531
4532  elseif w:netrw_liststyle == s:LONGLIST
4533   " use long list
4534"   call Decho("use long list",'~'.expand("<slnum>"))
4535   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
4536
4537  elseif w:netrw_liststyle == s:WIDELIST
4538   " give wide list
4539"   call Decho("use wide list",'~'.expand("<slnum>"))
4540   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4541
4542  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4543"   call Decho("use tree list",'~'.expand("<slnum>"))
4544   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4545
4546  else
4547   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4548   let g:netrw_liststyle = s:THINLIST
4549   let w:netrw_liststyle = g:netrw_liststyle
4550   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
4551  endif
4552  setl ma noro
4553"  call Decho("setl ma noro",'~'.expand("<slnum>"))
4554
4555  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
4556"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4557  sil! NetrwKeepj %d _
4558  " following prevents tree listing buffer from being marked "modified"
4559"  call Decho("setl nomod",'~'.expand("<slnum>"))
4560  setl nomod
4561"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4562
4563  " refresh the listing
4564"  call Decho("refresh the listing",'~'.expand("<slnum>"))
4565  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4566  NetrwKeepj call s:NetrwCursor()
4567
4568  " repoint t:netrw_lexbufnr if appropriate
4569  if exists("repointlexbufnr")
4570   let t:netrw_lexbufnr= bufnr("%")
4571"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
4572  endif
4573
4574  " restore position; keep cursor on the filename
4575"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4576  NetrwKeepj call winrestview(svpos)
4577  let @@= ykeep
4578
4579"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
4580endfun
4581
4582" ---------------------------------------------------------------------
4583" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4584fun! s:NetrwBannerCtrl(islocal)
4585"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
4586
4587  let ykeep= @@
4588  " toggle the banner (enable/suppress)
4589  let g:netrw_banner= !g:netrw_banner
4590
4591  " refresh the listing
4592  let svpos= winsaveview()
4593"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4594  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4595
4596  " keep cursor on the filename
4597  if g:netrw_banner && exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt
4598   let fname= s:NetrwGetWord()
4599   sil NetrwKeepj $
4600   let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4601" "  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4602   if result <= 0 && exists("w:netrw_bannercnt")
4603    exe "NetrwKeepj ".w:netrw_bannercnt
4604   endif
4605  endif
4606  let @@= ykeep
4607"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
4608endfun
4609
4610" ---------------------------------------------------------------------
4611" s:NetrwBookmark: supports :NetrwMB[!] [file]s                 {{{2
4612"
4613"  No bang: enters files/directories into Netrw's bookmark system
4614"   No argument and in netrw buffer:
4615"     if there are marked files: bookmark marked files
4616"     otherwise                : bookmark file/directory under cursor
4617"   No argument and not in netrw buffer: bookmarks current open file
4618"   Has arguments: globs them individually and bookmarks them
4619"
4620"  With bang: deletes files/directories from Netrw's bookmark system
4621fun! s:NetrwBookmark(del,...)
4622"  call Dfunc("s:NetrwBookmark(del=".a:del.",...) a:0=".a:0)
4623  if a:0 == 0
4624   if &ft == "netrw"
4625    let curbufnr = bufnr("%")
4626
4627    if exists("s:netrwmarkfilelist_{curbufnr}")
4628     " for every filename in the marked list
4629"     call Decho("bookmark every filename in marked list",'~'.expand("<slnum>"))
4630     let svpos  = winsaveview()
4631"     call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4632     let islocal= expand("%") !~ '^\a\{3,}://'
4633     for fname in s:netrwmarkfilelist_{curbufnr}
4634      if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4635     endfor
4636     let curdir  = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4637     call s:NetrwUnmarkList(curbufnr,curdir)
4638     NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./'))
4639"     call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4640     NetrwKeepj call winrestview(svpos)
4641    else
4642     let fname= s:NetrwGetWord()
4643     if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4644    endif
4645
4646   else
4647    " bookmark currently open file
4648"    call Decho("bookmark currently open file",'~'.expand("<slnum>"))
4649    let fname= expand("%")
4650    if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4651   endif
4652
4653  else
4654   " bookmark specified files
4655   "  attempts to infer if working remote or local
4656   "  by deciding if the current file begins with an url
4657   "  Globbing cannot be done remotely.
4658   let islocal= expand("%") !~ '^\a\{3,}://'
4659"   call Decho("bookmark specified file".((a:0>1)? "s" : ""),'~'.expand("<slnum>"))
4660   let i = 1
4661   while i <= a:0
4662    if islocal
4663     if v:version > 704 || (v:version == 704 && has("patch656"))
4664      let mbfiles= glob(fnameescape(a:{i}),0,1,1)
4665     else
4666      let mbfiles= glob(fnameescape(a:{i}),0,1)
4667     endif
4668    else
4669     let mbfiles= [a:{i}]
4670    endif
4671"    call Decho("mbfiles".string(mbfiles),'~'.expand("<slnum>"))
4672    for mbfile in mbfiles
4673"     call Decho("mbfile<".mbfile.">",'~'.expand("<slnum>"))
4674     if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4675    endfor
4676    let i= i + 1
4677   endwhile
4678  endif
4679
4680  " update the menu
4681  call s:NetrwBookmarkMenu()
4682
4683"  call Dret("s:NetrwBookmark")
4684endfun
4685
4686" ---------------------------------------------------------------------
4687" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4688"                      .2.[cnt] for bookmarks, and
4689"                      .3.[cnt] for history
4690"                      (see s:NetrwMenu())
4691fun! s:NetrwBookmarkMenu()
4692  if !exists("s:netrw_menucnt")
4693   return
4694  endif
4695"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhistcnt." menucnt=".s:netrw_menucnt)
4696
4697  " the following test assures that gvim is running, has menus available, and has menus enabled.
4698  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
4699   if exists("g:NetrwTopLvlMenu")
4700"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4701    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4702    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4703   endif
4704   if !exists("s:netrw_initbookhist")
4705    call s:NetrwBookHistRead()
4706   endif
4707
4708   " show bookmarked places
4709   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4710    let cnt= 1
4711    for bmd in g:netrw_bookmarklist
4712"     call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd,'~'.expand("<slnum>"))
4713     let bmd= escape(bmd,g:netrw_menu_escape)
4714
4715     " show bookmarks for goto menu
4716     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
4717
4718     " show bookmarks for deletion menu
4719     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
4720     let cnt= cnt + 1
4721    endfor
4722
4723   endif
4724
4725   " show directory browsing history
4726   if g:netrw_dirhistmax > 0
4727    let cnt     = g:netrw_dirhistcnt
4728    let first   = 1
4729    let histcnt = 0
4730    while ( first || cnt != g:netrw_dirhistcnt )
4731     let histcnt  = histcnt + 1
4732     let priority = g:netrw_dirhistcnt + histcnt
4733     if exists("g:netrw_dirhist_{cnt}")
4734      let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4735"     call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir,'~'.expand("<slnum>"))
4736      exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
4737     endif
4738     let first = 0
4739     let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
4740     if cnt < 0
4741      let cnt= cnt + g:netrw_dirhistmax
4742     endif
4743    endwhile
4744   endif
4745
4746  endif
4747"  call Dret("NetrwBookmarkMenu")
4748endfun
4749
4750" ---------------------------------------------------------------------
4751"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4752"                       directory and a new directory name.  Also, if the
4753"                       "new directory name" is actually a file,
4754"                       NetrwBrowseChgDir() edits the file.
4755fun! s:NetrwBrowseChgDir(islocal,newdir,...)
4756"  call Dfunc("s:NetrwBrowseChgDir(islocal=".a:islocal."> newdir<".a:newdir.">) a:0=".a:0." win#".winnr()." curpos<".string(getpos("."))."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "").">")
4757"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4758
4759  let ykeep= @@
4760  if !exists("b:netrw_curdir")
4761   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4762   " and the current window is the NetrwMessage window.
4763   let @@= ykeep
4764"   call Decho("b:netrw_curdir doesn't exist!",'~'.expand("<slnum>"))
4765"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
4766"   call Dredir("ls!","s:NetrwBrowseChgDir")
4767"   call Dret("s:NetrwBrowseChgDir")
4768   return
4769  endif
4770"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
4771
4772  " NetrwBrowseChgDir: save options and initialize {{{3
4773"  call Decho("saving options",'~'.expand("<slnum>"))
4774  call s:SavePosn(s:netrw_posn)
4775  NetrwKeepj call s:NetrwOptionsSave("s:")
4776  NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
4777  if (has("win32") || has("win95") || has("win64") || has("win16"))
4778   let dirname = substitute(b:netrw_curdir,'\\','/','ge')
4779  else
4780   let dirname = b:netrw_curdir
4781  endif
4782  let newdir    = a:newdir
4783  let dolockout = 0
4784  let dorestore = 1
4785"  call Decho("win#".winnr(),'~'.expand("<slnum>"))
4786"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
4787"  call Decho("newdir<".newdir.">",'~'.expand("<slnum>"))
4788
4789  " ignore <cr>s when done in the banner
4790"  call Decho('(s:NetrwBrowseChgDir) ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("<slnum>"))
4791  if g:netrw_banner
4792"   call Decho("win#".winnr()." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>"))
4793   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4794    if getline(".") =~# 'Quick Help'
4795"     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>"))
4796     let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4797"     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>"))
4798     setl ma noro nowrap
4799     NetrwKeepj call setline(line('.'),'"   Quick Help: <F1>:help  '.s:QuickHelp[g:netrw_quickhelp])
4800     setl noma nomod nowrap
4801     NetrwKeepj call s:NetrwOptionsRestore("s:")
4802"     call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4803    endif
4804   endif
4805"  else " Decho
4806"   call Decho("g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("<slnum>"))
4807  endif
4808
4809  " set up o/s-dependent directory recognition pattern
4810  if has("amiga")
4811   let dirpat= '[\/:]$'
4812  else
4813   let dirpat= '[\/]$'
4814  endif
4815"  call Decho("set up o/s-dependent directory recognition pattern: dirname<".dirname.">  dirpat<".dirpat.">",'~'.expand("<slnum>"))
4816
4817  if dirname !~ dirpat
4818   " apparently vim is "recognizing" that it is in a directory and
4819   " is removing the trailing "/".  Bad idea, so let's put it back.
4820   let dirname= dirname.'/'
4821"   call Decho("adjusting dirname<".dirname.'>  (put trailing "/" back)','~'.expand("<slnum>"))
4822  endif
4823
4824"  call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>"))
4825  if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
4826   " ------------------------------
4827   " NetrwBrowseChgDir: edit a file {{{3
4828   " ------------------------------
4829"   call Decho('edit-a-file: case "handling a file": win#'.winnr().' newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>"))
4830
4831   " save position for benefit of Rexplore
4832   let s:rexposn_{bufnr("%")}= winsaveview()
4833"   call Decho("edit-a-file: saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
4834"   call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
4835"   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>"))
4836
4837   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4838"    call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("<slnum>"))
4839"    call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("<slnum>"))
4840    let dirname= s:NetrwTreeDir(a:islocal)
4841    "COMBAK : not working for a symlink -- but what about a regular file? a directory?
4842"    call Decho("COMBAK : not working for a symlink -- but what about a regular file? a directory?")
4843    " Feb 17, 2019: following if-else-endif restored -- wasn't editing a file in tree mode
4844    if dirname =~ '/$'
4845     let dirname= dirname.newdir
4846    else
4847     let dirname= dirname."/".newdir
4848    endif
4849"    call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>"))
4850"    call Decho("edit-a-file: tree listing",'~'.expand("<slnum>"))
4851   elseif newdir =~ '^\(/\|\a:\)'
4852"    call Decho("edit-a-file: handle an url or path starting with /: <".newdir.">",'~'.expand("<slnum>"))
4853    let dirname= newdir
4854   else
4855    let dirname= s:ComposePath(dirname,newdir)
4856   endif
4857"   call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>"))
4858   " this lets netrw#BrowseX avoid the edit
4859   if a:0 < 1
4860"    call Decho("edit-a-file: (a:0=".a:0."<1) set up windows for editing<".fnameescape(dirname).">  didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist"),'~'.expand("<slnum>"))
4861    NetrwKeepj call s:NetrwOptionsRestore("s:")
4862    let curdir= b:netrw_curdir
4863    if !exists("s:didsplit")
4864"     "     call Decho("edit-a-file: s:didsplit does not exist; g:netrw_browse_split=".string(g:netrw_browse_split)." win#".winnr()." g:netrw_chgwin=".g:netrw_chgwin",'~'.expand("<slnum>"))
4865     if type(g:netrw_browse_split) == 3
4866      " open file in server
4867      " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4868"      call Decho("edit-a-file: open file in server",'~'.expand("<slnum>"))
4869      call s:NetrwServerEdit(a:islocal,dirname)
4870"      call Dret("s:NetrwBrowseChgDir")
4871      return
4872
4873     elseif g:netrw_browse_split == 1
4874      " horizontally splitting the window first
4875"      call Decho("edit-a-file: horizontally splitting window prior to edit",'~'.expand("<slnum>"))
4876      let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
4877      exe "keepalt ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
4878      if !&ea
4879       keepalt wincmd _
4880      endif
4881      call s:SetRexDir(a:islocal,curdir)
4882
4883     elseif g:netrw_browse_split == 2
4884      " vertically splitting the window first
4885"      call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>"))
4886      let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
4887      exe "keepalt ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
4888      if !&ea
4889       keepalt wincmd |
4890      endif
4891      call s:SetRexDir(a:islocal,curdir)
4892
4893     elseif g:netrw_browse_split == 3
4894      " open file in new tab
4895"      call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>"))
4896      keepalt tabnew
4897      if !exists("b:netrw_curdir")
4898       let b:netrw_curdir= getcwd()
4899      endif
4900      call s:SetRexDir(a:islocal,curdir)
4901
4902     elseif g:netrw_browse_split == 4
4903      " act like "P" (ie. open previous window)
4904"      call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>"))
4905      if s:NetrwPrevWinOpen(2) == 3
4906       let @@= ykeep
4907"       call Dret("s:NetrwBrowseChgDir")
4908       return
4909      endif
4910      call s:SetRexDir(a:islocal,curdir)
4911
4912     else
4913      " handling a file, didn't split, so remove menu
4914"      call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>"))
4915      call s:NetrwMenu(0)
4916      " optional change to window
4917      if g:netrw_chgwin >= 1
4918"       call Decho("edit-a-file: changing window to #".g:netrw_chgwin.": (due to g:netrw_chgwin)",'~'.expand("<slnum>"))
4919       if winnr("$")+1 == g:netrw_chgwin
4920	" if g:netrw_chgwin is set to one more than the last window, then
4921	" vertically split the last window to make that window available.
4922	let curwin= winnr()
4923	exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4924	vs
4925	exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4926       endif
4927       exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4928      endif
4929      call s:SetRexDir(a:islocal,curdir)
4930     endif
4931
4932    endif
4933
4934    " the point where netrw actually edits the (local) file
4935    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4936    " no keepalt to support  :e #  to return to a directory listing
4937    if !&mod
4938     " if e the new file would fail due to &mod, then don't change any of the flags
4939     let dolockout= 1
4940    endif
4941    if a:islocal
4942"     call Decho("edit-a-file: edit local file: exe e! ".fnameescape(dirname),'~'.expand("<slnum>"))
4943     " some like c-^ to return to the last edited file
4944     " others like c-^ to return to the netrw buffer
4945     " Apr 30, 2020: used to have e! here.  That can cause loss of a modified file,
4946     " so emit error E37 instead.
4947     if exists("g:netrw_altfile") && g:netrw_altfile
4948      exe "NetrwKeepj keepalt e ".fnameescape(dirname)
4949     else
4950      exe "NetrwKeepj e ".fnameescape(dirname)
4951     endif
4952"     call Decho("edit-a-file: after e! ".dirname.": hidden=".&hidden." bufhidden<".&bufhidden."> mod=".&mod,'~'.expand("<slnum>"))
4953     call s:NetrwCursor()
4954     if &hidden || &bufhidden == "hide"
4955      " file came from vim's hidden storage.  Don't "restore" options with it.
4956      let dorestore= 0
4957     endif
4958    else
4959"     call Decho("edit-a-file: remote file: NetrwBrowse will edit it",'~'.expand("<slnum>"))
4960    endif
4961
4962    " handle g:Netrw_funcref -- call external-to-netrw functions
4963    "   This code will handle g:Netrw_funcref as an individual function reference
4964    "   or as a list of function references.  It will ignore anything that's not
4965    "   a function reference.  See  :help Funcref  for information about function references.
4966    if exists("g:Netrw_funcref")
4967"     call Decho("edit-a-file: handle optional Funcrefs",'~'.expand("<slnum>"))
4968     if type(g:Netrw_funcref) == 2
4969"      call Decho("edit-a-file: handling a g:Netrw_funcref",'~'.expand("<slnum>"))
4970      NetrwKeepj call g:Netrw_funcref()
4971     elseif type(g:Netrw_funcref) == 3
4972"      call Decho("edit-a-file: handling a list of g:Netrw_funcrefs",'~'.expand("<slnum>"))
4973      for Fncref in g:Netrw_funcref
4974       if type(FncRef) == 2
4975        NetrwKeepj call FncRef()
4976       endif
4977      endfor
4978     endif
4979    endif
4980   endif
4981
4982  elseif newdir =~ '^/'
4983   " ----------------------------------------------------
4984   " NetrwBrowseChgDir: just go to the new directory spec {{{3
4985   " ----------------------------------------------------
4986"   call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("<slnum>"))
4987   let dirname = newdir
4988   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4989   NetrwKeepj call s:NetrwOptionsRestore("s:")
4990   norm! m`
4991
4992  elseif newdir == './'
4993   " ---------------------------------------------
4994   " NetrwBrowseChgDir: refresh the directory list {{{3
4995   " ---------------------------------------------
4996"   call Decho('(s:NetrwBrowseChgDir)refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("<slnum>"))
4997   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4998   norm! m`
4999
5000  elseif newdir == '../'
5001   " --------------------------------------
5002   " NetrwBrowseChgDir: go up one directory {{{3
5003   " --------------------------------------
5004"   call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../"','~'.expand("<slnum>"))
5005
5006   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5007    " force a refresh
5008"    call Decho("go-up: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
5009"    call Decho("go-up: setl noro ma",'~'.expand("<slnum>"))
5010    setl noro ma
5011    NetrwKeepj %d _
5012   endif
5013
5014   if has("amiga")
5015    " amiga
5016"    call Decho('go-up: case "go up one directory": newdir == "../" and amiga','~'.expand("<slnum>"))
5017    if a:islocal
5018     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
5019     let dirname= substitute(dirname,'/$','','')
5020    else
5021     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
5022    endif
5023"    call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5024
5025   elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
5026    " windows
5027    if a:islocal
5028     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
5029     if dirname == ""
5030      let dirname= '/'
5031     endif
5032    else
5033     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
5034    endif
5035    if dirname =~ '^\a:$'
5036     let dirname= dirname.'/'
5037    endif
5038"    call Decho("go-up: windows: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5039
5040   else
5041    " unix or cygwin
5042"    call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("<slnum>"))
5043    if a:islocal
5044     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
5045     if dirname == ""
5046      let dirname= '/'
5047     endif
5048    else
5049     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
5050    endif
5051"    call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5052   endif
5053   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5054   norm! m`
5055
5056  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5057   " --------------------------------------
5058   " NetrwBrowseChgDir: Handle Tree Listing {{{3
5059   " --------------------------------------
5060"   call Decho('(s:NetrwBrowseChgDir)tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("<slnum>"))
5061   " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
5062"   call Decho("tree-list: setl noro ma",'~'.expand("<slnum>"))
5063   setl noro ma
5064   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
5065"    call Decho("tree-list: clear buffer<".expand("%")."> with :%d  (force refresh)",'~'.expand("<slnum>"))
5066    NetrwKeepj %d _
5067   endif
5068   let treedir      = s:NetrwTreeDir(a:islocal)
5069"   call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>"))
5070   let s:treecurpos = winsaveview()
5071   let haskey       = 0
5072"   call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
5073
5074   " search treedict for tree dir as-is
5075"   call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("<slnum>"))
5076   if has_key(w:netrw_treedict,treedir)
5077"    call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>"))
5078    let haskey= 1
5079   else
5080"    call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
5081   endif
5082
5083   " search treedict for treedir with a [/@] appended
5084"   call Decho("tree-list: search treedict for treedir with a [/@] appended",'~'.expand("<slnum>"))
5085   if !haskey && treedir !~ '[/@]$'
5086    if has_key(w:netrw_treedict,treedir."/")
5087     let treedir= treedir."/"
5088"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
5089     let haskey = 1
5090    else
5091"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("<slnum>"))
5092    endif
5093   endif
5094
5095   " search treedict for treedir with any trailing / elided
5096"   call Decho("tree-list: search treedict for treedir with any trailing / elided",'~'.expand("<slnum>"))
5097   if !haskey && treedir =~ '/$'
5098    let treedir= substitute(treedir,'/$','','')
5099    if has_key(w:netrw_treedict,treedir)
5100"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
5101     let haskey = 1
5102    else
5103"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
5104    endif
5105   endif
5106
5107"   call Decho("haskey=".haskey,'~'.expand("<slnum>"))
5108   if haskey
5109    " close tree listing for selected subdirectory
5110"    call Decho("tree-list: closing selected subdirectory<".dirname.">",'~'.expand("<slnum>"))
5111    call remove(w:netrw_treedict,treedir)
5112"    call Decho("tree-list: removed     entry<".treedir."> from treedict",'~'.expand("<slnum>"))
5113"    call Decho("tree-list: yielding treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
5114    let dirname= w:netrw_treetop
5115   else
5116    " go down one directory
5117    let dirname= substitute(treedir,'/*$','/','')
5118"    call Decho("tree-list: go down one dir: treedir<".treedir.">",'~'.expand("<slnum>"))
5119"    call Decho("tree-list: ...            : dirname<".dirname.">",'~'.expand("<slnum>"))
5120   endif
5121   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5122"   call Decho("setting s:treeforceredraw to true",'~'.expand("<slnum>"))
5123   let s:treeforceredraw = 1
5124
5125  else
5126   " ----------------------------------------
5127   " NetrwBrowseChgDir: Go down one directory {{{3
5128   " ----------------------------------------
5129   let dirname    = s:ComposePath(dirname,newdir)
5130"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("<slnum>"))
5131   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5132   norm! m`
5133  endif
5134
5135 " --------------------------------------
5136 " NetrwBrowseChgDir: Restore and Cleanup {{{3
5137 " --------------------------------------
5138  if dorestore
5139   " dorestore is zero'd when a local file was hidden or bufhidden;
5140   " in such a case, we want to keep whatever settings it may have.
5141"   call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("<slnum>"))
5142   NetrwKeepj call s:NetrwOptionsRestore("s:")
5143"  else " Decho
5144"   call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>"))
5145  endif
5146  if dolockout && dorestore
5147"   call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>"))
5148   if filewritable(dirname)
5149"    call Decho("restore: doing modification lockout settings: ma nomod noro",'~'.expand("<slnum>"))
5150"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5151    setl ma noro nomod
5152"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5153   else
5154"    call Decho("restore: doing modification lockout settings: ma nomod ro",'~'.expand("<slnum>"))
5155"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5156    setl ma ro nomod
5157"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5158   endif
5159  endif
5160  call s:RestorePosn(s:netrw_posn)
5161  let @@= ykeep
5162
5163"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
5164  return dirname
5165endfun
5166
5167" ---------------------------------------------------------------------
5168" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
5169"    for thin, long, and wide: cursor placed just after banner
5170"    for tree, keeps cursor on current filename
5171fun! s:NetrwBrowseUpDir(islocal)
5172"  call Dfunc("s:NetrwBrowseUpDir(islocal=".a:islocal.")")
5173  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
5174   " this test needed because occasionally this function seems to be incorrectly called
5175   " when multiple leftmouse clicks are taken when atop the one line help in the banner.
5176   " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
5177   " directories.
5178"   call Dret("s:NetrwBrowseUpDir : cursor not in file area")
5179   return
5180  endif
5181
5182  norm! 0
5183  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5184"   call Decho("case: treestyle",'~'.expand("<slnum>"))
5185   let curline= getline(".")
5186   let swwline= winline() - 1
5187   if exists("w:netrw_treetop")
5188    let b:netrw_curdir= w:netrw_treetop
5189   elseif exists("b:netrw_curdir")
5190    let w:netrw_treetop= b:netrw_curdir
5191   else
5192    let w:netrw_treetop= getcwd()
5193    let b:netrw_curdir = w:netrw_treetop
5194   endif
5195   let curfile = getline(".")
5196   let curpath = s:NetrwTreePath(w:netrw_treetop)
5197   if a:islocal
5198    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5199   else
5200    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5201   endif
5202"   call Decho("looking for curfile<^".s:treedepthstring.curfile.">",'~'.expand("<slnum>"))
5203"   call Decho("having      curpath<".curpath.">",'~'.expand("<slnum>"))
5204   if w:netrw_treetop == '/'
5205     keepj call search('^\M'.curfile,"w")
5206   elseif curfile == '../'
5207     keepj call search('^\M'.curfile,"wb")
5208   else
5209"    call Decho("search(^\\M".s:treedepthstring.curfile.") backwards"))
5210    while 1
5211     keepj call search('^\M'.s:treedepthstring.curfile,"wb")
5212     let treepath= s:NetrwTreePath(w:netrw_treetop)
5213"     call Decho("..current treepath<".treepath.">",'~'.expand("<slnum>"))
5214     if treepath == curpath
5215      break
5216     endif
5217    endwhile
5218   endif
5219
5220  else
5221"   call Decho("case: not treestyle",'~'.expand("<slnum>"))
5222   call s:SavePosn(s:netrw_posn)
5223   if exists("b:netrw_curdir")
5224    let curdir= b:netrw_curdir
5225   else
5226    let curdir= expand(getcwd())
5227   endif
5228   if a:islocal
5229    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5230   else
5231    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5232   endif
5233   call s:RestorePosn(s:netrw_posn)
5234   let curdir= substitute(curdir,'^.*[\/]','','')
5235   call search('\<'.curdir.'/','wc')
5236  endif
5237"  call Dret("s:NetrwBrowseUpDir")
5238endfun
5239
5240" ---------------------------------------------------------------------
5241" netrw#BrowseX:  (implements "x" and "gx") executes a special "viewer" script or program for the {{{2
5242"              given filename; typically this means given their extension.
5243"              0=local, 1=remote
5244fun! netrw#BrowseX(fname,remote)
5245  let use_ctrlo= 1
5246"  call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")  implements x and gx maps")
5247
5248  if a:remote == 0 && isdirectory(a:fname)
5249   " if its really just a local directory, then do a "gf" instead
5250"   call Decho("remote≡0 and a:fname<".a:fname."> ".(isdirectory(a:fname)? "is a directory" : "is not a directory"),'~'.expand("<slnum>"))
5251"   call Decho("..appears to be a local directory; using e ".a:fname." instead",'~'.expand("<slnum>"))
5252   exe "e ".a:fname
5253"   call Dret("netrw#BrowseX")
5254   return
5255  elseif a:remote == 1 && a:fname !~ '^https\=:' && a:fname =~ '/$'
5256   " remote directory, not a webpage access, looks like an attempt to do a directory listing
5257"   call Decho("remote≡1 and a:fname<".a:fname.">",'~'.expand("<slnum>"))
5258"   call Decho("..and fname ".((a:fname =~ '^https\=:')? 'matches' : 'does not match').'^https\=:','~'.expand("<slnum>"))
5259"   call Decho("..and fname ".((a:fname =~ '/$')?        'matches' : 'does not match').' /$','~'.expand("<slnum>"))
5260"   call Decho("..appears to be a remote directory listing request; using gf instead",'~'.expand("<slnum>"))
5261   norm! gf
5262"   call Dret("netrw#BrowseX")
5263   return
5264  endif
5265"  call Decho("not a local file nor a webpage request",'~'.expand("<slnum>"))
5266
5267  let ykeep      = @@
5268  let screenposn = winsaveview()
5269"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5270
5271  " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
5272  let awkeep     = &aw
5273  set noaw
5274
5275  " special core dump handler
5276  if a:fname =~ '/core\(\.\d\+\)\=$'
5277   if exists("g:Netrw_corehandler")
5278    if type(g:Netrw_corehandler) == 2
5279     " g:Netrw_corehandler is a function reference (see :help Funcref)
5280"     call Decho("g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
5281     call g:Netrw_corehandler(s:NetrwFile(a:fname))
5282    elseif type(g:Netrw_corehandler) == 3
5283     " g:Netrw_corehandler is a List of function references (see :help Funcref)
5284"     call Decho("g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
5285     for Fncref in g:Netrw_corehandler
5286      if type(FncRef) == 2
5287       call FncRef(a:fname)
5288      endif
5289     endfor
5290    endif
5291"    call Decho("restoring posn: screenposn<".string(screenposn).">,'~'.expand("<slnum>"))"
5292    call winrestview(screenposn)
5293    let @@= ykeep
5294    let &aw= awkeep
5295"    call Dret("netrw#BrowseX : coredump handler invoked")
5296    return
5297   endif
5298  endif
5299
5300  " set up the filename
5301  " (lower case the extension, make a local copy of a remote file)
5302  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5303  if has("win32") || has("win95") || has("win64") || has("win16")
5304   let exten= substitute(exten,'^.*$','\L&\E','')
5305  endif
5306  if exten =~ "[\\/]"
5307   let exten= ""
5308  endif
5309"  call Decho("exten<".exten.">",'~'.expand("<slnum>"))
5310
5311  if a:remote == 1
5312   " create a local copy
5313"   call Decho("remote: a:remote=".a:remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
5314   setl bh=delete
5315   call netrw#NetRead(3,a:fname)
5316   " attempt to rename tempfile
5317   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5318   let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5319"   call Decho("basename<".basename.">",'~'.expand("<slnum>"))
5320"   call Decho("newname <".newname.">",'~'.expand("<slnum>"))
5321   if s:netrw_tmpfile != newname && newname != ""
5322    if rename(s:netrw_tmpfile,newname) == 0
5323     " renaming succeeded
5324"     call Decho("renaming succeeded (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5325     let fname= newname
5326    else
5327     " renaming failed
5328"     call Decho("renaming failed (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5329     let fname= s:netrw_tmpfile
5330    endif
5331   else
5332    let fname= s:netrw_tmpfile
5333   endif
5334  else
5335"   call Decho("local: a:remote=".a:remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
5336   let fname= a:fname
5337   " special ~ handler for local
5338   if fname =~ '^\~' && expand("$HOME") != ""
5339"    call Decho('invoking special ~ handler','~'.expand("<slnum>"))
5340    let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5341   endif
5342  endif
5343"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
5344"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
5345
5346  " set up redirection (avoids browser messages)
5347  " by default, g:netrw_suppress_gx_mesg is true
5348  if g:netrw_suppress_gx_mesg
5349   if &srr =~ "%s"
5350    if (has("win32") || has("win95") || has("win64") || has("win16"))
5351     let redir= substitute(&srr,"%s","nul","")
5352    else
5353     let redir= substitute(&srr,"%s","/dev/null","")
5354    endif
5355   elseif (has("win32") || has("win95") || has("win64") || has("win16"))
5356    let redir= &srr . "nul"
5357   else
5358    let redir= &srr . "/dev/null"
5359   endif
5360  endif
5361"  call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
5362
5363  " extract any viewing options.  Assumes that they're set apart by spaces.
5364  if exists("g:netrw_browsex_viewer")
5365"   call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5366   if g:netrw_browsex_viewer =~ '\s'
5367    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5368    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5369    let oviewer = ''
5370    let cnt     = 1
5371    while !executable(viewer) && viewer != oviewer
5372     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5373     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5374     let cnt     = cnt + 1
5375     let oviewer = viewer
5376"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5377    endwhile
5378   else
5379    let viewer  = g:netrw_browsex_viewer
5380    let viewopt = ""
5381   endif
5382"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5383  endif
5384
5385  " execute the file handler
5386"  call Decho("execute the file handler (if any)",'~'.expand("<slnum>"))
5387  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
5388"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5389   let ret= netrwFileHandlers#Invoke(exten,fname)
5390
5391  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
5392"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5393   call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
5394   let ret= v:shell_error
5395
5396  elseif has("win32") || has("win64")
5397"   call Decho("(netrw#BrowseX) win".(has("win32")? "32" : "64"),'~'.expand("<slnum>"))
5398   if executable("start")
5399    call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5400   elseif executable("rundll32")
5401    call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5402   else
5403    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5404   endif
5405   let ret= v:shell_error
5406
5407  elseif has("win32unix")
5408   let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
5409"   call Decho("(netrw#BrowseX) cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
5410   if executable("start")
5411"    call Decho("(netrw#BrowseX) win32unix+start",'~'.expand("<slnum>"))
5412    call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5413   elseif executable("rundll32")
5414"    call Decho("(netrw#BrowseX) win32unix+rundll32",'~'.expand("<slnum>"))
5415    call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5416   elseif executable("cygstart")
5417"    call Decho("(netrw#BrowseX) win32unix+cygstart",'~'.expand("<slnum>"))
5418    call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
5419   else
5420    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5421   endif
5422   let ret= v:shell_error
5423
5424  elseif has("unix") && $DESKTOP_SESSION == "mate" && executable("atril")
5425"   call Decho("(netrw#BrowseX) unix and atril",'~'.expand("<slnum>"))
5426   if a:fname =~ '^https\=://'
5427    " atril does not appear to understand how to handle html -- so use gvim to edit the document
5428    let use_ctrlo= 0
5429"    call Decho("(COMBAK) fname<".fname.">")
5430"    call Decho("(COMBAK) a:fname<".a:fname.">")
5431    call s:NetrwExe("sil! !gvim ".fname.' -c "keepj keepalt file '.fnameescape(a:fname).'"')
5432
5433   else
5434    call s:NetrwExe("sil !atril ".s:ShellEscape(fname,1).redir)
5435   endif
5436   let ret= v:shell_error
5437
5438  elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
5439"   call Decho("(netrw#BrowseX) unix and kfmclient",'~'.expand("<slnum>"))
5440   call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
5441   let ret= v:shell_error
5442
5443  elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
5444"   call Decho("(netrw#BrowseX) unix, exo-open, xdg-open",'~'.expand("<slnum>"))
5445   call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir.'&')
5446   let ret= v:shell_error
5447
5448  elseif has("unix") && executable("xdg-open")
5449"   call Decho("(netrw#BrowseX) unix and xdg-open",'~'.expand("<slnum>"))
5450   call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir.'&')
5451   let ret= v:shell_error
5452
5453  elseif has("macunix") && executable("open")
5454"   call Decho("(netrw#BrowseX) macunix and open",'~'.expand("<slnum>"))
5455   call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
5456   let ret= v:shell_error
5457
5458  else
5459   " netrwFileHandlers#Invoke() always returns 0
5460"   call Decho("(netrw#BrowseX) use netrwFileHandlers",'~'.expand("<slnum>"))
5461   let ret= netrwFileHandlers#Invoke(exten,fname)
5462  endif
5463
5464  " if unsuccessful, attempt netrwFileHandlers#Invoke()
5465  if ret
5466"   call Decho("(netrw#BrowseX) ret=".ret," indicates unsuccessful thus far",'~'.expand("<slnum>"))
5467   let ret= netrwFileHandlers#Invoke(exten,fname)
5468  endif
5469
5470  " restoring redraw! after external file handlers
5471  redraw!
5472
5473  " cleanup: remove temporary file,
5474  "          delete current buffer if success with handler,
5475  "          return to prior buffer (directory listing)
5476  "          Feb 12, 2008: had to de-activiate removal of
5477  "          temporary file because it wasn't getting seen.
5478"  if a:remote == 1 && fname != a:fname
5479""   call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
5480"   call s:NetrwDelete(fname)
5481"  endif
5482
5483  if a:remote == 1
5484   setl bh=delete bt=nofile
5485   if g:netrw_use_noswf
5486    setl noswf
5487   endif
5488   if use_ctrlo
5489    exe "sil! NetrwKeepj norm! \<c-o>"
5490   endif
5491  endif
5492"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5493  call winrestview(screenposn)
5494  let @@ = ykeep
5495  let &aw= awkeep
5496
5497"  call Dret("netrw#BrowseX")
5498endfun
5499
5500" ---------------------------------------------------------------------
5501" netrw#GX: gets word under cursor for gx support {{{2
5502"           See also: netrw#BrowseXVis
5503"                     netrw#BrowseX
5504fun! netrw#GX()
5505"  call Dfunc("netrw#GX()")
5506  if &ft == "netrw"
5507   let fname= s:NetrwGetWord()
5508  else
5509   let fname= expand((exists("g:netrw_gx")? g:netrw_gx : '<cfile>'))
5510  endif
5511"  call Dret("netrw#GX <".fname.">")
5512  return fname
5513endfun
5514
5515" ---------------------------------------------------------------------
5516" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5517fun! netrw#BrowseXVis()
5518"  call Dfunc("netrw#BrowseXVis()")
5519  let akeep = @a
5520  norm! gv"ay
5521  let gxfile= @a
5522  let @a    = akeep
5523  call netrw#BrowseX(gxfile,netrw#CheckIfRemote(gxfile))
5524"  call Dret("netrw#BrowseXVis")
5525endfun
5526
5527" ---------------------------------------------------------------------
5528" s:NetrwBufRename: renames a buffer without the side effect of retaining an unlisted buffer having the old name {{{2
5529"                   Using the file command on a "[No Name]" buffer does not seem to cause the old "[No Name]" buffer
5530"                   to become an unlisted buffer, so in that case don't bwipe it.
5531fun! s:NetrwBufRename(newname)
5532"  call Dfunc("s:NetrwBufRename(newname<".a:newname.">) buf(%)#".bufnr("%")."<".bufname(bufnr("%")).">")
5533"  call Dredir("ls!","s:NetrwBufRename (before rename)")
5534  let oldbufname= bufname(bufnr("%"))
5535"  call Decho("buf#".bufnr("%").": oldbufname<".oldbufname.">",'~'.expand("<slnum>"))
5536
5537  if oldbufname != a:newname
5538"   call Decho("do buffer rename: oldbufname<".oldbufname."> ≠ a:newname<".a:newname.">",'~'.expand("<slnum>"))
5539   let b:junk= 1
5540"   call Decho("rename buffer: sil! keepj keepalt file ".fnameescape(a:newname),'~'.expand("<slnum>"))
5541   exe 'sil! keepj keepalt file '.fnameescape(a:newname)
5542"   call Dredir("ls!","s:NetrwBufRename (before bwipe)")
5543   let oldbufnr= bufnr(oldbufname)
5544"   call Decho("oldbufname<".oldbufname."> oldbufnr#".oldbufnr,'~'.expand("<slnum>"))
5545"   call Decho("bufnr(%)=".bufnr("%"),'~'.expand("<slnum>"))
5546   if oldbufname != "" && oldbufnr != -1 && oldbufnr != bufnr("%")
5547"    call Decho("bwipe ".oldbufnr,'~'.expand("<slnum>"))
5548    exe "bwipe! ".oldbufnr
5549"   else " Decho
5550"    call Decho("did *not* bwipe buf#".oldbufnr,'~'.expand("<slnum>"))
5551   endif
5552"   call Dredir("ls!","s:NetrwBufRename (after rename)")
5553"  else " Decho
5554"   call Decho("oldbufname<".oldbufname."> == a:newname: did *not* rename",'~'.expand("<slnum>"))
5555  endif
5556
5557"  call Dret("s:NetrwBufRename : buf#".bufnr("%").": oldname<".oldbufname."> newname<".a:newname."> expand(%)<".expand("%").">")
5558endfun
5559
5560" ---------------------------------------------------------------------
5561" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5562fun! netrw#CheckIfRemote(...)
5563"  call Dfunc("netrw#CheckIfRemote() a:0=".a:0)
5564  if a:0 > 0
5565   let curfile= a:1
5566  else
5567   let curfile= expand("%")
5568  endif
5569"  call Decho("curfile<".curfile.">")
5570  if curfile =~ '^\a\{3,}://'
5571"   call Dret("netrw#CheckIfRemote 1")
5572   return 1
5573  else
5574"   call Dret("netrw#CheckIfRemote 0")
5575   return 0
5576  endif
5577endfun
5578
5579" ---------------------------------------------------------------------
5580" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5581fun! s:NetrwChgPerm(islocal,curdir)
5582"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
5583  let ykeep  = @@
5584  call inputsave()
5585  let newperm= input("Enter new permission: ")
5586  call inputrestore()
5587  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5588  let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5589"  call Decho("chgperm<".chgperm.">",'~'.expand("<slnum>"))
5590  call system(chgperm)
5591  if v:shell_error != 0
5592   NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5593  endif
5594  if a:islocal
5595   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5596  endif
5597  let @@= ykeep
5598"  call Dret("s:NetrwChgPerm")
5599endfun
5600
5601" ---------------------------------------------------------------------
5602" s:CheckIfKde: checks if kdeinit is running {{{2
5603"    Returns 0: kdeinit not running
5604"            1: kdeinit is  running
5605fun! s:CheckIfKde()
5606"  call Dfunc("s:CheckIfKde()")
5607  " seems kde systems often have gnome-open due to dependencies, even though
5608  " gnome-open's subsidiary display tools are largely absent.  Kde systems
5609  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
5610  if !exists("s:haskdeinit")
5611   if has("unix") && executable("ps") && !has("win32unix")
5612    let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5613    if v:shell_error
5614     let s:haskdeinit = 0
5615    endif
5616   else
5617    let s:haskdeinit= 0
5618   endif
5619"   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5620  endif
5621
5622"  call Dret("s:CheckIfKde ".s:haskdeinit)
5623  return s:haskdeinit
5624endfun
5625
5626" ---------------------------------------------------------------------
5627" s:NetrwClearExplore: clear explore variables (if any) {{{2
5628fun! s:NetrwClearExplore()
5629"  call Dfunc("s:NetrwClearExplore()")
5630  2match none
5631  if exists("s:explore_match")        |unlet s:explore_match        |endif
5632  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
5633  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5634  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
5635  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
5636  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
5637  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5638  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
5639  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
5640"   redraw!
5641  echo " "
5642  echo " "
5643"  call Dret("s:NetrwClearExplore")
5644endfun
5645
5646" ---------------------------------------------------------------------
5647" s:NetrwExploreListUniq: {{{2
5648fun! s:NetrwExploreListUniq(explist)
5649"  call Dfunc("s:NetrwExploreListUniq(explist<".string(a:explist).">)")
5650
5651  " this assumes that the list is already sorted
5652  let newexplist= []
5653  for member in a:explist
5654   if !exists("uniqmember") || member != uniqmember
5655    let uniqmember = member
5656    let newexplist = newexplist + [ member ]
5657   endif
5658  endfor
5659
5660"  call Dret("s:NetrwExploreListUniq newexplist<".string(newexplist).">")
5661  return newexplist
5662endfun
5663
5664" ---------------------------------------------------------------------
5665" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5666fun! s:NetrwForceChgDir(islocal,newdir)
5667"  call Dfunc("s:NetrwForceChgDir(islocal=".a:islocal." newdir<".a:newdir.">)")
5668  let ykeep= @@
5669  if a:newdir !~ '/$'
5670   " ok, looks like force is needed to get directory-style treatment
5671   if a:newdir =~ '@$'
5672    let newdir= substitute(a:newdir,'@$','/','')
5673   elseif a:newdir =~ '[*=|\\]$'
5674    let newdir= substitute(a:newdir,'.$','/','')
5675   else
5676    let newdir= a:newdir.'/'
5677   endif
5678"   call Decho("adjusting newdir<".newdir."> due to gd",'~'.expand("<slnum>"))
5679  else
5680   " should already be getting treatment as a directory
5681   let newdir= a:newdir
5682  endif
5683  let newdir= s:NetrwBrowseChgDir(a:islocal,newdir)
5684  call s:NetrwBrowse(a:islocal,newdir)
5685  let @@= ykeep
5686"  call Dret("s:NetrwForceChgDir")
5687endfun
5688
5689" ---------------------------------------------------------------------
5690" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5691"     direntry: this is the name of the directory.  Will be fnameescape'd to prevent wildcard handling by glob()
5692"     expr    : this is the expression to follow the directory.  Will use s:ComposePath()
5693"     pare    =1: remove the current directory from the resulting glob() filelist
5694"             =0: leave  the current directory   in the resulting glob() filelist
5695fun! s:NetrwGlob(direntry,expr,pare)
5696"  call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")")
5697  if netrw#CheckIfRemote()
5698   keepalt 1sp
5699   keepalt enew
5700   let keep_liststyle    = w:netrw_liststyle
5701   let w:netrw_liststyle = s:THINLIST
5702   if s:NetrwRemoteListing() == 0
5703    keepj keepalt %s@/@@
5704    let filelist= getline(1,$)
5705    q!
5706   else
5707    " remote listing error -- leave treedict unchanged
5708    let filelist= w:netrw_treedict[a:direntry]
5709   endif
5710   let w:netrw_liststyle= keep_liststyle
5711  elseif v:version > 704 || (v:version == 704 && has("patch656"))
5712   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1)
5713   if a:pare
5714    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5715   endif
5716  else
5717   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1)
5718   if a:pare
5719    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5720   endif
5721  endif
5722"  call Dret("s:NetrwGlob ".string(filelist))
5723  return filelist
5724endfun
5725
5726" ---------------------------------------------------------------------
5727" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5728fun! s:NetrwForceFile(islocal,newfile)
5729"  call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)")
5730  if a:newfile =~ '[/@*=|\\]$'
5731   let newfile= substitute(a:newfile,'.$','','')
5732  else
5733   let newfile= a:newfile
5734  endif
5735  if a:islocal
5736   call s:NetrwBrowseChgDir(a:islocal,newfile)
5737  else
5738   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile))
5739  endif
5740"  call Dret("s:NetrwForceFile")
5741endfun
5742
5743" ---------------------------------------------------------------------
5744" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5745"          and switches the hiding mode.  The actual hiding is done by
5746"          s:NetrwListHide().
5747"             g:netrw_hide= 0: show all
5748"                           1: show not-hidden files
5749"                           2: show hidden files only
5750fun! s:NetrwHide(islocal)
5751"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
5752  let ykeep= @@
5753  let svpos= winsaveview()
5754"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5755
5756  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5757"   call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>"))
5758"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5759
5760   " hide the files in the markfile list
5761   for fname in s:netrwmarkfilelist_{bufnr("%")}
5762"    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>"))
5763    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5764     " remove fname from hiding list
5765     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5766     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5767     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5768"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5769    else
5770     " append fname to hiding list
5771     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5772      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5773     else
5774      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5775     endif
5776"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5777    endif
5778   endfor
5779   NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5780   let g:netrw_hide= 1
5781
5782  else
5783
5784   " switch between show-all/show-not-hidden/show-hidden
5785   let g:netrw_hide=(g:netrw_hide+1)%3
5786   exe "NetrwKeepj norm! 0"
5787   if g:netrw_hide && g:netrw_list_hide == ""
5788    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5789    let @@= ykeep
5790"    call Dret("NetrwHide")
5791    return
5792   endif
5793  endif
5794
5795  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5796"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5797  NetrwKeepj call winrestview(svpos)
5798  let @@= ykeep
5799"  call Dret("NetrwHide")
5800endfun
5801
5802" ---------------------------------------------------------------------
5803" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5804fun! s:NetrwHideEdit(islocal)
5805"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
5806
5807  let ykeep= @@
5808  " save current cursor position
5809  let svpos= winsaveview()
5810"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5811
5812  " get new hiding list from user
5813  call inputsave()
5814  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5815  call inputrestore()
5816  let g:netrw_list_hide= newhide
5817"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5818
5819  " refresh the listing
5820  sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
5821
5822  " restore cursor position
5823"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5824  call winrestview(svpos)
5825  let @@= ykeep
5826
5827"  call Dret("NetrwHideEdit")
5828endfun
5829
5830" ---------------------------------------------------------------------
5831" s:NetrwHidden: invoked by "gh" {{{2
5832fun! s:NetrwHidden(islocal)
5833"  call Dfunc("s:NetrwHidden()")
5834  let ykeep= @@
5835  "  save current position
5836  let svpos  = winsaveview()
5837"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5838
5839  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5840   " remove .file pattern from hiding list
5841"   call Decho("remove .file pattern from hiding list",'~'.expand("<slnum>"))
5842   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5843  elseif s:Strlen(g:netrw_list_hide) >= 1
5844"   call Decho("add .file pattern from hiding list",'~'.expand("<slnum>"))
5845   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5846  else
5847"   call Decho("set .file pattern as hiding list",'~'.expand("<slnum>"))
5848   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5849  endif
5850  if g:netrw_list_hide =~ '^,'
5851   let g:netrw_list_hide= strpart(g:netrw_list_hide,1)
5852  endif
5853
5854  " refresh screen and return to saved position
5855  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5856"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5857  NetrwKeepj call winrestview(svpos)
5858  let @@= ykeep
5859"  call Dret("s:NetrwHidden")
5860endfun
5861
5862" ---------------------------------------------------------------------
5863"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5864fun! s:NetrwHome()
5865  if exists("g:netrw_home")
5866   let home= expand(g:netrw_home)
5867  else
5868   " go to vim plugin home
5869   for home in split(&rtp,',') + ['']
5870    if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5871     let basehome= substitute(home,'[/\\]\.vim$','','')
5872     if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5873     let home= basehome."/.vim"
5874     break
5875    endif
5876   endfor
5877   if home == ""
5878    " just pick the first directory
5879    let home= substitute(&rtp,',.*$','','')
5880   endif
5881   if (has("win32") || has("win95") || has("win64") || has("win16"))
5882    let home= substitute(home,'/','\\','g')
5883   endif
5884  endif
5885  " insure that the home directory exists
5886  if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5887"   call Decho("insure that the home<".home."> directory exists")
5888   if exists("g:netrw_mkdir")
5889"    call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")")
5890    call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5891   else
5892"    call Decho("mkdir(".home.")")
5893    call mkdir(home)
5894   endif
5895  endif
5896  let g:netrw_home= home
5897  return home
5898endfun
5899
5900" ---------------------------------------------------------------------
5901" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5902fun! s:NetrwLeftmouse(islocal)
5903  if exists("s:netrwdrag")
5904   return
5905  endif
5906  if &ft != "netrw"
5907   return
5908  endif
5909"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
5910
5911  let ykeep= @@
5912  " check if the status bar was clicked on instead of a file/directory name
5913  while getchar(0) != 0
5914   "clear the input stream
5915  endwhile
5916  call feedkeys("\<LeftMouse>")
5917  let c          = getchar()
5918  let mouse_lnum = v:mouse_lnum
5919  let wlastline  = line('w$')
5920  let lastline   = line('$')
5921"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr(),'~'.expand("<slnum>"))
5922"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0),'~'.expand("<slnum>"))
5923  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5924   " appears to be a status bar leftmouse click
5925   let @@= ykeep
5926"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
5927   return
5928  endif
5929   " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5930   " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5931   " without this test when its disabled.
5932   " May 26, 2014: edit file, :Lex, resize window -- causes refresh.  Reinstated a modified test.  See if problems develop.
5933"   call Decho("v:mouse_col=".v:mouse_col." col#".col('.')." virtcol#".virtcol('.')." col($)#".col("$")." virtcol($)#".virtcol("$"),'~'.expand("<slnum>"))
5934   if v:mouse_col > virtcol('.')
5935    let @@= ykeep
5936"    call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
5937    return
5938   endif
5939
5940  if a:islocal
5941   if exists("b:netrw_curdir")
5942    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
5943   endif
5944  else
5945   if exists("b:netrw_curdir")
5946    NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5947   endif
5948  endif
5949  let @@= ykeep
5950"  call Dret("s:NetrwLeftmouse")
5951endfun
5952
5953" ---------------------------------------------------------------------
5954" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5955fun! s:NetrwCLeftmouse(islocal)
5956  if &ft != "netrw"
5957   return
5958  endif
5959"  call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")")
5960  call s:NetrwMarkFileTgt(a:islocal)
5961"  call Dret("s:NetrwCLeftmouse")
5962endfun
5963
5964" ---------------------------------------------------------------------
5965" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER  (implements <c-r>){{{2
5966"   a:islocal=0 : <c-r> not used, remote
5967"   a:islocal=1 : <c-r> not used, local
5968"   a:islocal=2 : <c-r>     used, remote
5969"   a:islocal=3 : <c-r>     used, local
5970fun! s:NetrwServerEdit(islocal,fname)
5971"  call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5972  let islocal = a:islocal%2      " =0: remote           =1: local
5973  let ctrlr   = a:islocal >= 2   " =0: <c-r> not used   =1: <c-r> used
5974"  call Decho("islocal=".islocal." ctrlr=".ctrlr,'~'.expand("<slnum>"))
5975
5976  if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5977   " handle directories in the local window -- not in the remote vim server
5978   " user must have closed the NETRWSERVER window.  Treat as normal editing from netrw.
5979"   call Decho("handling directory in client window",'~'.expand("<slnum>"))
5980   let g:netrw_browse_split= 0
5981   if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
5982    let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5983    unlet s:netrw_browse_split_{winnr()}
5984   endif
5985   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5986"   call Dret("s:NetrwServerEdit")
5987   return
5988  endif
5989
5990"  call Decho("handling file in server window",'~'.expand("<slnum>"))
5991  if has("clientserver") && executable("gvim")
5992"   call Decho("has clientserver and gvim",'~'.expand("<slnum>"))
5993
5994    if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
5995"     call Decho("g:netrw_browse_split=".string(g:netrw_browse_split),'~'.expand("<slnum>"))
5996     let srvrname = g:netrw_browse_split[0]
5997     let tabnum   = g:netrw_browse_split[1]
5998     let winnum   = g:netrw_browse_split[2]
5999
6000     if serverlist() !~ '\<'.srvrname.'\>'
6001"      call Decho("server not available; ctrlr=".ctrlr,'~'.expand("<slnum>"))
6002
6003      if !ctrlr
6004       " user must have closed the server window and the user did not use <c-r>, but
6005       " used something like <cr>.
6006"       call Decho("user must have closed server AND did not use ctrl-r",'~'.expand("<slnum>"))
6007       if exists("g:netrw_browse_split")
6008	unlet g:netrw_browse_split
6009       endif
6010       let g:netrw_browse_split= 0
6011       if exists("s:netrw_browse_split_".winnr())
6012        let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
6013       endif
6014       call s:NetrwBrowseChgDir(islocal,a:fname)
6015"       call Dret("s:NetrwServerEdit")
6016       return
6017
6018      elseif has("win32") && executable("start")
6019       " start up remote netrw server under windows
6020"       call Decho("starting up gvim server<".srvrname."> for windows",'~'.expand("<slnum>"))
6021       call system("start gvim --servername ".srvrname)
6022
6023      else
6024       " start up remote netrw server under linux
6025"       call Decho("starting up gvim server<".srvrname.">",'~'.expand("<slnum>"))
6026       call system("gvim --servername ".srvrname)
6027      endif
6028     endif
6029
6030"     call Decho("srvrname<".srvrname."> tabnum=".tabnum." winnum=".winnum." server-editing<".a:fname.">",'~'.expand("<slnum>"))
6031     call remote_send(srvrname,":tabn ".tabnum."\<cr>")
6032     call remote_send(srvrname,":".winnum."wincmd w\<cr>")
6033     call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
6034
6035    else
6036
6037     if serverlist() !~ '\<'.g:netrw_servername.'\>'
6038
6039      if !ctrlr
6040"       call Decho("server<".g:netrw_servername."> not available and ctrl-r not used",'~'.expand("<slnum>"))
6041       if exists("g:netrw_browse_split")
6042	unlet g:netrw_browse_split
6043       endif
6044       let g:netrw_browse_split= 0
6045       call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
6046"       call Dret("s:NetrwServerEdit")
6047       return
6048
6049      else
6050"       call Decho("server<".g:netrw_servername."> not available but ctrl-r used",'~'.expand("<slnum>"))
6051       if has("win32") && executable("start")
6052        " start up remote netrw server under windows
6053"        call Decho("starting up gvim server<".g:netrw_servername."> for windows",'~'.expand("<slnum>"))
6054        call system("start gvim --servername ".g:netrw_servername)
6055       else
6056        " start up remote netrw server under linux
6057"        call Decho("starting up gvim server<".g:netrw_servername.">",'~'.expand("<slnum>"))
6058        call system("gvim --servername ".g:netrw_servername)
6059       endif
6060      endif
6061     endif
6062
6063     while 1
6064      try
6065"       call Decho("remote-send: e ".a:fname,'~'.expand("<slnum>"))
6066       call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
6067       break
6068      catch /^Vim\%((\a\+)\)\=:E241/
6069       sleep 200m
6070      endtry
6071     endwhile
6072
6073     if exists("g:netrw_browse_split")
6074      if type(g:netrw_browse_split) != 3
6075        let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
6076       endif
6077      unlet g:netrw_browse_split
6078     endif
6079     let g:netrw_browse_split= [g:netrw_servername,1,1]
6080    endif
6081
6082   else
6083    call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
6084   endif
6085
6086"  call Dret("s:NetrwServerEdit")
6087endfun
6088
6089" ---------------------------------------------------------------------
6090" s:NetrwSLeftmouse: marks the file under the cursor.  May be dragged to select additional files {{{2
6091fun! s:NetrwSLeftmouse(islocal)
6092  if &ft != "netrw"
6093   return
6094  endif
6095"  call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
6096
6097  let s:ngw= s:NetrwGetWord()
6098  call s:NetrwMarkFile(a:islocal,s:ngw)
6099
6100"  call Dret("s:NetrwSLeftmouse")
6101endfun
6102
6103" ---------------------------------------------------------------------
6104" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
6105"                   Used to mark multiple files.
6106fun! s:NetrwSLeftdrag(islocal)
6107"  call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
6108  if !exists("s:netrwdrag")
6109   let s:netrwdrag = winnr()
6110   if a:islocal
6111    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
6112   else
6113    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
6114   endif
6115  endif
6116  let ngw = s:NetrwGetWord()
6117  if !exists("s:ngw") || s:ngw != ngw
6118   call s:NetrwMarkFile(a:islocal,ngw)
6119  endif
6120  let s:ngw= ngw
6121"  call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
6122endfun
6123
6124" ---------------------------------------------------------------------
6125" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
6126fun! s:NetrwSLeftrelease(islocal)
6127"  call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
6128  if exists("s:netrwdrag")
6129   nunmap <s-leftrelease>
6130   let ngw = s:NetrwGetWord()
6131   if !exists("s:ngw") || s:ngw != ngw
6132    call s:NetrwMarkFile(a:islocal,ngw)
6133   endif
6134   if exists("s:ngw")
6135    unlet s:ngw
6136   endif
6137   unlet s:netrwdrag
6138  endif
6139"  call Dret("s:NetrwSLeftrelease")
6140endfun
6141
6142" ---------------------------------------------------------------------
6143" s:NetrwListHide: uses [range]g~...~d to delete files that match       {{{2
6144"                  comma-separated patterns given in g:netrw_list_hide
6145fun! s:NetrwListHide()
6146"  call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
6147"  call Decho("initial: ".string(getline(w:netrw_bannercnt,'$')))
6148  let ykeep= @@
6149
6150  " find a character not in the "hide" string to use as a separator for :g and :v commands
6151  " How-it-works: take the hiding command, convert it into a range.
6152  " Duplicate characters don't matter.
6153  " Remove all such characters from the '/~@#...890' string.
6154  " Use the first character left as a separator character.
6155"  call Decho("find a character not in the hide string to use as a separator",'~'.expand("<slnum>"))
6156  let listhide= g:netrw_list_hide
6157  let sep     = strpart(substitute('~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
6158"  call Decho("sep<".sep.">  (sep not in hide string)",'~'.expand("<slnum>"))
6159
6160  while listhide != ""
6161   if listhide =~ ','
6162    let hide     = substitute(listhide,',.*$','','e')
6163    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
6164   else
6165    let hide     = listhide
6166    let listhide = ""
6167   endif
6168"   call Decho("..extracted pattern from listhide: hide<".hide."> g:netrw_sort_by<".g:netrw_sort_by.'>','~'.expand("<slnum>"))
6169   if g:netrw_sort_by =~ '^[ts]'
6170    if hide =~ '^\^'
6171"     call Decho("..modify hide to handle a \"^...\" pattern",'~'.expand("<slnum>"))
6172     let hide= substitute(hide,'^\^','^\(\\d\\+/\)','')
6173    elseif hide =~ '^\\(\^'
6174     let hide= substitute(hide,'^\\(\^','\\(^\\(\\d\\+/\\)','')
6175    endif
6176"    call Decho("..hide<".hide."> listhide<".listhide.'>','~'.expand("<slnum>"))
6177   endif
6178
6179   " Prune the list by hiding any files which match
6180"   call Decho("..prune the list by hiding any files which ".((g:netrw_hide == 1)? "" : "don't")."match hide<".hide.">")
6181   if g:netrw_hide == 1
6182"    call Decho("..hiding<".hide.">",'~'.expand("<slnum>"))
6183    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
6184   elseif g:netrw_hide == 2
6185"    call Decho("..showing<".hide.">",'~'.expand("<slnum>"))
6186    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
6187   endif
6188"   call Decho("..result: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6189  endwhile
6190
6191  if g:netrw_hide == 2
6192   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
6193"   call Decho("..v KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6194   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
6195"   call Decho("..g KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6196  endif
6197
6198  " remove any blank lines that have somehow remained.
6199  " This seems to happen under Windows.
6200  exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
6201
6202  let @@= ykeep
6203"  call Dret("s:NetrwListHide")
6204endfun
6205
6206" ---------------------------------------------------------------------
6207" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
6208"                 implements the "d" mapping.
6209fun! s:NetrwMakeDir(usrhost)
6210"  call Dfunc("s:NetrwMakeDir(usrhost<".a:usrhost.">)")
6211
6212  let ykeep= @@
6213  " get name of new directory from user.  A bare <CR> will skip.
6214  " if its currently a directory, also request will be skipped, but with
6215  " a message.
6216  call inputsave()
6217  let newdirname= input("Please give directory name: ")
6218  call inputrestore()
6219"  call Decho("newdirname<".newdirname.">",'~'.expand("<slnum>"))
6220
6221  if newdirname == ""
6222   let @@= ykeep
6223"   call Dret("s:NetrwMakeDir : user aborted with bare <cr>")
6224   return
6225  endif
6226
6227  if a:usrhost == ""
6228"   call Decho("local mkdir",'~'.expand("<slnum>"))
6229
6230   " Local mkdir:
6231   " sanity checks
6232   let fullnewdir= b:netrw_curdir.'/'.newdirname
6233"   call Decho("fullnewdir<".fullnewdir.">",'~'.expand("<slnum>"))
6234   if isdirectory(s:NetrwFile(fullnewdir))
6235    if !exists("g:netrw_quiet")
6236     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
6237    endif
6238    let @@= ykeep
6239"    call Dret("s:NetrwMakeDir : directory<".newdirname."> exists previously")
6240    return
6241   endif
6242   if s:FileReadable(fullnewdir)
6243    if !exists("g:netrw_quiet")
6244     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
6245    endif
6246    let @@= ykeep
6247"    call Dret("s:NetrwMakeDir : file<".newdirname."> exists previously")
6248    return
6249   endif
6250
6251   " requested new local directory is neither a pre-existing file or
6252   " directory, so make it!
6253   if exists("*mkdir")
6254    if has("unix")
6255     call mkdir(fullnewdir,"p",xor(0777, system("umask")))
6256    else
6257     call mkdir(fullnewdir,"p")
6258    endif
6259   else
6260    let netrw_origdir= s:NetrwGetcwd(1)
6261    if s:NetrwLcd(b:netrw_curdir)
6262"    call Dret("s:NetrwMakeDir : lcd failure")
6263     return
6264    endif
6265"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("<slnum>"))
6266    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(newdirname,1))
6267    if v:shell_error != 0
6268     let @@= ykeep
6269     call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6270"     call Dret("s:NetrwMakeDir : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
6271     return
6272    endif
6273    if !g:netrw_keepdir
6274"     call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
6275     if s:NetrwLcd(netrw_origdir)
6276"     call Dret("s:NetrwBrowse : lcd failure")
6277      return
6278     endif
6279    endif
6280   endif
6281
6282   if v:shell_error == 0
6283    " refresh listing
6284"    call Decho("refresh listing",'~'.expand("<slnum>"))
6285    let svpos= winsaveview()
6286"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6287    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
6288"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6289    call winrestview(svpos)
6290   elseif !exists("g:netrw_quiet")
6291    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
6292   endif
6293"   redraw!
6294
6295  elseif !exists("b:netrw_method") || b:netrw_method == 4
6296   " Remote mkdir:  using ssh
6297"   call Decho("remote mkdir",'~'.expand("<slnum>"))
6298   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
6299   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
6300   call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
6301   if v:shell_error == 0
6302    " refresh listing
6303    let svpos= winsaveview()
6304"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6305    NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6306"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6307    NetrwKeepj call winrestview(svpos)
6308   elseif !exists("g:netrw_quiet")
6309    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
6310   endif
6311"   redraw!
6312
6313  elseif b:netrw_method == 2
6314   " Remote mkdir:  using ftp+.netrc
6315   let svpos= winsaveview()
6316"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6317"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6318   if exists("b:netrw_fname")
6319"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6320    let remotepath= b:netrw_fname
6321   else
6322    let remotepath= ""
6323   endif
6324   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6325   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6326"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6327   NetrwKeepj call winrestview(svpos)
6328
6329  elseif b:netrw_method == 3
6330   " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
6331   let svpos= winsaveview()
6332"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6333"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6334   if exists("b:netrw_fname")
6335"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6336    let remotepath= b:netrw_fname
6337   else
6338    let remotepath= ""
6339   endif
6340   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6341   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6342"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6343   NetrwKeepj call winrestview(svpos)
6344  endif
6345
6346  let @@= ykeep
6347"  call Dret("s:NetrwMakeDir")
6348endfun
6349
6350" ---------------------------------------------------------------------
6351" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
6352fun! s:TreeSqueezeDir(islocal)
6353"  call Dfunc("s:TreeSqueezeDir(islocal=".a:islocal.")")
6354  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6355   " its a tree-listing style
6356   let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
6357   let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
6358   let depth    = strchars(substitute(curdepth,' ','','g'))
6359   let srch     = -1
6360"   call Decho("curdepth<".curdepth.'>','~'.expand("<slnum>"))
6361"   call Decho("depth   =".depth,'~'.expand("<slnum>"))
6362"   call Decho("stopline#".stopline,'~'.expand("<slnum>"))
6363"   call Decho("curline#".line(".")."<".getline('.').'>','~'.expand("<slnum>"))
6364   if depth >= 2
6365    NetrwKeepj norm! 0
6366    let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
6367    let srch      = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
6368"    call Decho("curdepthm1<".curdepthm1.'>','~'.expand("<slnum>"))
6369"    call Decho("case depth>=2: srch<".srch.'>','~'.expand("<slnum>"))
6370   elseif depth == 1
6371    NetrwKeepj norm! 0
6372    let treedepthchr= substitute(s:treedepthstring,' ','','')
6373    let srch        = search('^[^'.treedepthchr.']','bW',stopline)
6374"    call Decho("case depth==1: srch<".srch.'>','~'.expand("<slnum>"))
6375   endif
6376   if srch > 0
6377"    call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
6378    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord()))
6379    exe srch
6380   endif
6381  endif
6382"  call Dret("s:TreeSqueezeDir")
6383endfun
6384
6385" ---------------------------------------------------------------------
6386" s:NetrwMaps: {{{2
6387fun! s:NetrwMaps(islocal)
6388"  call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6389
6390  " mouse <Plug> maps: {{{3
6391  if g:netrw_mousemaps && g:netrw_retmap
6392"   call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
6393   if !hasmapto("<Plug>NetrwReturn")
6394    if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
6395"     call Decho("making map for 2-leftmouse",'~'.expand("<slnum>"))
6396     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
6397    elseif maparg("<c-leftmouse>","n") == ""
6398"     call Decho("making map for c-leftmouse",'~'.expand("<slnum>"))
6399     nmap <unique> <silent> <c-leftmouse>	<Plug>NetrwReturn
6400    endif
6401   endif
6402   nno <silent> <Plug>NetrwReturn	:Rexplore<cr>
6403"   call Decho("made <Plug>NetrwReturn map",'~'.expand("<slnum>"))
6404  endif
6405
6406  " generate default <Plug> maps {{{3
6407  if !hasmapto('<Plug>NetrwHide')              |nmap <buffer> <silent> <nowait> a	<Plug>NetrwHide_a|endif
6408  if !hasmapto('<Plug>NetrwBrowseUpDir')       |nmap <buffer> <silent> <nowait> -	<Plug>NetrwBrowseUpDir|endif
6409  if !hasmapto('<Plug>NetrwOpenFile')          |nmap <buffer> <silent> <nowait> %	<Plug>NetrwOpenFile|endif
6410  if !hasmapto('<Plug>NetrwBadd_cb')           |nmap <buffer> <silent> <nowait> cb	<Plug>NetrwBadd_cb|endif
6411  if !hasmapto('<Plug>NetrwBadd_cB')           |nmap <buffer> <silent> <nowait> cB	<Plug>NetrwBadd_cB|endif
6412  if !hasmapto('<Plug>NetrwLcd')               |nmap <buffer> <silent> <nowait> cd	<Plug>NetrwLcd|endif
6413  if !hasmapto('<Plug>NetrwSetChgwin')         |nmap <buffer> <silent> <nowait> C	<Plug>NetrwSetChgwin|endif
6414  if !hasmapto('<Plug>NetrwRefresh')           |nmap <buffer> <silent> <nowait> <c-l>	<Plug>NetrwRefresh|endif
6415  if !hasmapto('<Plug>NetrwLocalBrowseCheck')  |nmap <buffer> <silent> <nowait> <cr>	<Plug>NetrwLocalBrowseCheck|endif
6416  if !hasmapto('<Plug>NetrwServerEdit')        |nmap <buffer> <silent> <nowait> <c-r>	<Plug>NetrwServerEdit|endif
6417  if !hasmapto('<Plug>NetrwMakeDir')           |nmap <buffer> <silent> <nowait> d	<Plug>NetrwMakeDir|endif
6418  if !hasmapto('<Plug>NetrwBookHistHandler_gb')|nmap <buffer> <silent> <nowait> gb	<Plug>NetrwBookHistHandler_gb|endif
6419" ---------------------------------------------------------------------
6420"  if !hasmapto('<Plug>NetrwForceChgDir')       |nmap <buffer> <silent> <nowait> gd	<Plug>NetrwForceChgDir|endif
6421"  if !hasmapto('<Plug>NetrwForceFile')         |nmap <buffer> <silent> <nowait> gf	<Plug>NetrwForceFile|endif
6422"  if !hasmapto('<Plug>NetrwHidden')            |nmap <buffer> <silent> <nowait> gh	<Plug>NetrwHidden|endif
6423"  if !hasmapto('<Plug>NetrwSetTreetop')        |nmap <buffer> <silent> <nowait> gn	<Plug>NetrwSetTreetop|endif
6424"  if !hasmapto('<Plug>NetrwChgPerm')           |nmap <buffer> <silent> <nowait> gp	<Plug>NetrwChgPerm|endif
6425"  if !hasmapto('<Plug>NetrwBannerCtrl')        |nmap <buffer> <silent> <nowait> I	<Plug>NetrwBannerCtrl|endif
6426"  if !hasmapto('<Plug>NetrwListStyle')         |nmap <buffer> <silent> <nowait> i	<Plug>NetrwListStyle|endif
6427"  if !hasmapto('<Plug>NetrwMarkMoveMF2Arglist')|nmap <buffer> <silent> <nowait> ma	<Plug>NetrwMarkMoveMF2Arglist|endif
6428"  if !hasmapto('<Plug>NetrwMarkMoveArglist2MF')|nmap <buffer> <silent> <nowait> mA	<Plug>NetrwMarkMoveArglist2MF|endif
6429"  if !hasmapto('<Plug>NetrwBookHistHandler_mA')|nmap <buffer> <silent> <nowait> mb	<Plug>NetrwBookHistHandler_mA|endif
6430"  if !hasmapto('<Plug>NetrwBookHistHandler_mB')|nmap <buffer> <silent> <nowait> mB	<Plug>NetrwBookHistHandler_mB|endif
6431"  if !hasmapto('<Plug>NetrwMarkFileCopy')      |nmap <buffer> <silent> <nowait> mc	<Plug>NetrwMarkFileCopy|endif
6432"  if !hasmapto('<Plug>NetrwMarkFileDiff')      |nmap <buffer> <silent> <nowait> md	<Plug>NetrwMarkFileDiff|endif
6433"  if !hasmapto('<Plug>NetrwMarkFileEdit')      |nmap <buffer> <silent> <nowait> me	<Plug>NetrwMarkFileEdit|endif
6434"  if !hasmapto('<Plug>NetrwMarkFile')          |nmap <buffer> <silent> <nowait> mf	<Plug>NetrwMarkFile|endif
6435"  if !hasmapto('<Plug>NetrwUnmarkList')        |nmap <buffer> <silent> <nowait> mF	<Plug>NetrwUnmarkList|endif
6436"  if !hasmapto('<Plug>NetrwMarkFileGrep')      |nmap <buffer> <silent> <nowait> mg	<Plug>NetrwMarkFileGrep|endif
6437"  if !hasmapto('<Plug>NetrwMarkHideSfx')       |nmap <buffer> <silent> <nowait> mh	<Plug>NetrwMarkHideSfx|endif
6438"  if !hasmapto('<Plug>NetrwMarkFileMove')      |nmap <buffer> <silent> <nowait> mm	<Plug>NetrwMarkFileMove|endif
6439"  if !hasmapto('<Plug>NetrwMarkFilePrint')     |nmap <buffer> <silent> <nowait> mp	<Plug>NetrwMarkFilePrint|endif
6440"  if !hasmapto('<Plug>NetrwMarkFileRegexp')    |nmap <buffer> <silent> <nowait> mr	<Plug>NetrwMarkFileRegexp|endif
6441"  if !hasmapto('<Plug>NetrwMarkFileSource')    |nmap <buffer> <silent> <nowait> ms	<Plug>NetrwMarkFileSource|endif
6442"  if !hasmapto('<Plug>NetrwMarkFileTag')       |nmap <buffer> <silent> <nowait> mT	<Plug>NetrwMarkFileTag|endif
6443"  if !hasmapto('<Plug>NetrwMarkFileTgt')       |nmap <buffer> <silent> <nowait> mt	<Plug>NetrwMarkFileTgt|endif
6444"  if !hasmapto('<Plug>NetrwUnMarkFile')        |nmap <buffer> <silent> <nowait> mu	<Plug>NetrwUnMarkFile|endif
6445"  if !hasmapto('<Plug>NetrwMarkFileVimCmd')    |nmap <buffer> <silent> <nowait> mv	<Plug>NetrwMarkFileVimCmd|endif
6446"  if !hasmapto('<Plug>NetrwMarkFileExe_mx')    |nmap <buffer> <silent> <nowait> mx	<Plug>NetrwMarkFileExe_mx|endif
6447"  if !hasmapto('<Plug>NetrwMarkFileExe_mX')    |nmap <buffer> <silent> <nowait> mX	<Plug>NetrwMarkFileExe_mX|endif
6448"  if !hasmapto('<Plug>NetrwMarkFileCompress')  |nmap <buffer> <silent> <nowait> mz	<Plug>NetrwMarkFileCompress|endif
6449"  if !hasmapto('<Plug>NetrwObtain')            |nmap <buffer> <silent> <nowait> O	<Plug>NetrwObtain|endif
6450"  if !hasmapto('<Plug>NetrwSplit_o')           |nmap <buffer> <silent> <nowait> o	<Plug>NetrwSplit_o|endif
6451"  if !hasmapto('<Plug>NetrwPreview')           |nmap <buffer> <silent> <nowait> p	<Plug>NetrwPreview|endif
6452"  if !hasmapto('<Plug>NetrwPrevWinOpen')       |nmap <buffer> <silent> <nowait> P	<Plug>NetrwPrevWinOpen|endif
6453"  if !hasmapto('<Plug>NetrwBookHistHandler_qb')|nmap <buffer> <silent> <nowait> qb	<Plug>NetrwBookHistHandler_qb|endif
6454"  if !hasmapto('<Plug>NetrwFileInfo')          |nmap <buffer> <silent> <nowait> qf	<Plug>NetrwFileInfo|endif
6455"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qF')   |nmap <buffer> <silent> <nowait> qF	<Plug>NetrwMarkFileQFEL_qF|endif
6456"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qL')   |nmap <buffer> <silent> <nowait> qL	<Plug>NetrwMarkFileQFEL_qL|endif
6457"  if !hasmapto('<Plug>NetrwSortStyle')         |nmap <buffer> <silent> <nowait> s	<Plug>NetrwSortStyle|endif
6458"  if !hasmapto('<Plug>NetSortSequence')        |nmap <buffer> <silent> <nowait> S	<Plug>NetSortSequence|endif
6459"  if !hasmapto('<Plug>NetrwSetTgt_Tb')         |nmap <buffer> <silent> <nowait> Tb	<Plug>NetrwSetTgt_Tb|endif
6460"  if !hasmapto('<Plug>NetrwSetTgt_Th')         |nmap <buffer> <silent> <nowait> Th	<Plug>NetrwSetTgt_Th|endif
6461"  if !hasmapto('<Plug>NetrwSplit_t')           |nmap <buffer> <silent> <nowait> t	<Plug>NetrwSplit_t|endif
6462"  if !hasmapto('<Plug>NetrwBookHistHandler_u') |nmap <buffer> <silent> <nowait> u	<Plug>NetrwBookHistHandler_u|endif
6463"  if !hasmapto('<Plug>NetrwBookHistHandler_U') |nmap <buffer> <silent> <nowait> U	<Plug>NetrwBookHistHandler_U|endif
6464"  if !hasmapto('<Plug>NetrwSplit_v')           |nmap <buffer> <silent> <nowait> v	<Plug>NetrwSplit_v|endif
6465"  if !hasmapto('<Plug>NetrwBrowseX')           |nmap <buffer> <silent> <nowait> x	<Plug>NetrwBrowseX|endif
6466"  if !hasmapto('<Plug>NetrwLocalExecute')      |nmap <buffer> <silent> <nowait> X	<Plug>NetrwLocalExecute|endif
6467
6468  if a:islocal
6469"   call Decho("make local maps",'~'.expand("<slnum>"))
6470   " local normal-mode maps {{{3
6471   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(1)<cr>
6472   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6473   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(1)<cr>
6474   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(1,0)<cr>
6475   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(1,1)<cr>
6476   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6477   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6478   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6479   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6480   nnoremap <buffer> <silent> <Plug>NetrwMakeDir		:<c-u>call <SID>NetrwMakeDir("")<cr>
6481   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6482" ---------------------------------------------------------------------
6483   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6484   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6485   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
6486   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(0,<SID>NetrwGetWord())<cr>
6487   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6488   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6489   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(1)<cr>
6490   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6491   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6492   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6493   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6494   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6495   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6496   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6497   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6498   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6499   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6500   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6501   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6502   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6503   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6504   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6505   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6506   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6507   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6508   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6509   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6510   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6511   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6512   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(1)<cr>
6513   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(3)<cr>
6514   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6515   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6516   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6517   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6518   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6519   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6520   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(1)<cr>
6521   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(1)<cr>
6522   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6523   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(4)<cr>
6524   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6525   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6526   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6527   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(5)<cr>
6528   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6529   nnoremap <buffer> <silent> <nowait> X	:<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6530
6531   nnoremap <buffer> <silent> <nowait> r	:<c-u>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>
6532   if !hasmapto('<Plug>NetrwHideEdit')
6533    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6534   endif
6535   nnoremap <buffer> <silent> <Plug>NetrwHideEdit		:call <SID>NetrwHideEdit(1)<cr>
6536   if !hasmapto('<Plug>NetrwRefresh')
6537    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6538   endif
6539   nnoremap <buffer> <silent> <Plug>NetrwRefresh		<c-l>:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr>
6540   if s:didstarstar || !mapcheck("<s-down>","n")
6541    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6542   endif
6543   if s:didstarstar || !mapcheck("<s-up>","n")
6544    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6545   endif
6546   if !hasmapto('<Plug>NetrwTreeSqueeze')
6547    nmap <buffer> <silent> <nowait> <s-cr>			<Plug>NetrwTreeSqueeze
6548   endif
6549   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze		:call <SID>TreeSqueezeDir(1)<cr>
6550   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6551   if g:netrw_mousemaps == 1
6552    nmap <buffer>			<leftmouse>   		<Plug>NetrwLeftmouse
6553    nmap <buffer>			<c-leftmouse>		<Plug>NetrwCLeftmouse
6554    nmap <buffer>			<middlemouse>		<Plug>NetrwMiddlemouse
6555    nmap <buffer>			<s-leftmouse>		<Plug>NetrwSLeftmouse
6556    nmap <buffer>			<s-leftdrag>		<Plug>NetrwSLeftdrag
6557    nmap <buffer>			<2-leftmouse>		<Plug>Netrw2Leftmouse
6558    imap <buffer>			<leftmouse>		<Plug>ILeftmouse
6559    imap <buffer>			<middlemouse>		<Plug>IMiddlemouse
6560    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
6561    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(1)<cr>
6562    nno  <buffer> <silent>		<Plug>NetrwMiddlemouse	<leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
6563    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(1)<cr>
6564    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(1)<cr>
6565    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6566    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6567    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6568   endif
6569   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6570   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6571   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6572   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("")<cr>'
6573   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6574   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6575   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6576   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6577
6578   " support user-specified maps
6579   call netrw#UserMaps(1)
6580
6581  else
6582   " remote normal-mode maps {{{3
6583"   call Decho("make remote maps",'~'.expand("<slnum>"))
6584   call s:RemotePathAnalysis(b:netrw_curdir)
6585   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(0)<cr>
6586   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6587   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(0)<cr>
6588   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(0,0)<cr>
6589   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(0,1)<cr>
6590   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6591   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6592   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6593   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6594   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6595   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6596" ---------------------------------------------------------------------
6597   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6598   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6599   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
6600   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6601   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6602   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(0)<cr>
6603   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6604   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6605   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6606   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6607   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6608   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6609   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6610   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6611   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6612   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6613   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6614   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6615   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6616   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6617   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6618   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6619   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6620   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6621   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6622   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6623   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6624   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6625   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(0)<cr>
6626   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(0)<cr>
6627   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6628   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6629   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6630   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6631   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6632   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6633   nnoremap <buffer> <silent> <nowait> r	:<c-u>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>
6634   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(0)<cr>
6635   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(0)<cr>
6636   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6637   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(1)<cr>
6638   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6639   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6640   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6641   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(2)<cr>
6642   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6643   if !hasmapto('<Plug>NetrwHideEdit')
6644    nmap <buffer> <c-h> <Plug>NetrwHideEdit
6645   endif
6646   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
6647   if !hasmapto('<Plug>NetrwRefresh')
6648    nmap <buffer> <c-l> <Plug>NetrwRefresh
6649   endif
6650   if !hasmapto('<Plug>NetrwTreeSqueeze')
6651    nmap <buffer> <silent> <nowait> <s-cr>	<Plug>NetrwTreeSqueeze
6652   endif
6653   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze	:call <SID>TreeSqueezeDir(0)<cr>
6654
6655   let mapsafepath     = escape(s:path, s:netrw_map_escape)
6656   let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6657
6658   nnoremap <buffer> <silent> <Plug>NetrwRefresh	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6659   if g:netrw_mousemaps == 1
6660    nmap <buffer> <leftmouse>		<Plug>NetrwLeftmouse
6661    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
6662    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6663    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(0)<cr>
6664    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6665    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(0)<cr>
6666    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6667    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(0)<cr>
6668    nmap <middlemouse>			<Plug>NetrwMiddlemouse
6669    nno  <buffer> <silent>		<middlemouse>		<Plug>NetrwMiddlemouse <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
6670    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6671    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6672    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6673    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6674    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6675    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6676    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6677   endif
6678   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6679   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6680   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6681   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6682   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6683   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6684   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6685   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6686
6687   " support user-specified maps
6688   call netrw#UserMaps(0)
6689  endif " }}}3
6690
6691"  call Dret("s:NetrwMaps")
6692endfun
6693
6694" ---------------------------------------------------------------------
6695" s:NetrwCommands: set up commands 				{{{2
6696"  If -buffer, the command is only available from within netrw buffers
6697"  Otherwise, the command is available from any window, so long as netrw
6698"  has been used at least once in the session.
6699fun! s:NetrwCommands(islocal)
6700"  call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6701
6702  com! -nargs=* -complete=file -bang	NetrwMB	call s:NetrwBookmark(<bang>0,<f-args>)
6703  com! -nargs=*			    	NetrwC	call s:NetrwSetChgwin(<q-args>)
6704  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,"win#".winnr()." not a former netrw window",79)|endif
6705  if a:islocal
6706   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(1,<f-args>)
6707  else
6708   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(0,<f-args>)
6709  endif
6710  com! -buffer -nargs=? -complete=file	MT	call s:NetrwMarkTarget(<q-args>)
6711
6712"  call Dret("s:NetrwCommands")
6713endfun
6714
6715" ---------------------------------------------------------------------
6716" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6717"                   glob()ing only works with local files
6718fun! s:NetrwMarkFiles(islocal,...)
6719"  call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6720  let curdir = s:NetrwGetCurdir(a:islocal)
6721  let i      = 1
6722  while i <= a:0
6723   if a:islocal
6724    if v:version > 704 || (v:version == 704 && has("patch656"))
6725     let mffiles= glob(a:{i},0,1,1)
6726    else
6727     let mffiles= glob(a:{i},0,1)
6728    endif
6729   else
6730    let mffiles= [a:{i}]
6731   endif
6732"   call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6733   for mffile in mffiles
6734"    call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6735    call s:NetrwMarkFile(a:islocal,mffile)
6736   endfor
6737   let i= i + 1
6738  endwhile
6739"  call Dret("s:NetrwMarkFiles")
6740endfun
6741
6742" ---------------------------------------------------------------------
6743" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6744fun! s:NetrwMarkTarget(...)
6745"  call Dfunc("s:NetrwMarkTarget() a:0=".a:0)
6746  if a:0 == 0 || (a:0 == 1 && a:1 == "")
6747   let curdir = s:NetrwGetCurdir(1)
6748   let tgt    = b:netrw_curdir
6749  else
6750   let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6751   let tgt    = a:1
6752  endif
6753"  call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
6754  let s:netrwmftgt         = tgt
6755  let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6756  let curislocal           = b:netrw_curdir !~ '^\a\{3,}://'
6757  let svpos                = winsaveview()
6758"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6759  call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./'))
6760"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6761  call winrestview(svpos)
6762"  call Dret("s:NetrwMarkTarget")
6763endfun
6764
6765" ---------------------------------------------------------------------
6766" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6767"                  mark and unmark files.  If a markfile list exists,
6768"                  then the rename and delete functions will use it instead
6769"                  of whatever may happen to be under the cursor at that
6770"                  moment.  When the mouse and gui are available,
6771"                  shift-leftmouse may also be used to mark files.
6772"
6773"  Creates two lists
6774"    s:netrwmarkfilelist    -- holds complete paths to all marked files
6775"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
6776"
6777"  Creates a marked file match string
6778"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
6779"
6780"  Creates a buffer version of islocal
6781"    b:netrw_islocal
6782fun! s:NetrwMarkFile(islocal,fname)
6783"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6784"  call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6785
6786  " sanity check
6787  if empty(a:fname)
6788"   call Dret("s:NetrwMarkFile : emtpy fname")
6789   return
6790  endif
6791  let curdir = s:NetrwGetCurdir(a:islocal)
6792
6793  let ykeep   = @@
6794  let curbufnr= bufnr("%")
6795  if a:fname =~ '^\a'
6796   let leader= '\<'
6797  else
6798   let leader= ''
6799  endif
6800  if a:fname =~ '\a$'
6801   let trailer = '\>[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6802  else
6803   let trailer = '[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6804  endif
6805
6806  if exists("s:netrwmarkfilelist_".curbufnr)
6807   " markfile list pre-exists
6808"   call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6809"   call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6810"   call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6811   let b:netrw_islocal= a:islocal
6812
6813   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6814    " append filename to buffer's markfilelist
6815"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6816    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6817    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6818
6819   else
6820    " remove filename from buffer's markfilelist
6821"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6822    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6823    if s:netrwmarkfilelist_{curbufnr} == []
6824     " local markfilelist is empty; remove it entirely
6825"     call Decho("markfile list now empty",'~'.expand("<slnum>"))
6826     call s:NetrwUnmarkList(curbufnr,curdir)
6827    else
6828     " rebuild match list to display markings correctly
6829"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6830     let s:netrwmarkfilemtch_{curbufnr}= ""
6831     let first                         = 1
6832     for fname in s:netrwmarkfilelist_{curbufnr}
6833      if first
6834       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6835      else
6836       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6837      endif
6838      let first= 0
6839     endfor
6840"     call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6841    endif
6842   endif
6843
6844  else
6845   " initialize new markfilelist
6846"   call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6847
6848"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6849   let s:netrwmarkfilelist_{curbufnr}= []
6850   call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6851"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6852
6853   " build initial markfile matching pattern
6854   if a:fname =~ '/$'
6855    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6856   else
6857    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6858   endif
6859"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6860  endif
6861
6862  " handle global markfilelist
6863  if exists("s:netrwmarkfilelist")
6864   let dname= s:ComposePath(b:netrw_curdir,a:fname)
6865   if index(s:netrwmarkfilelist,dname) == -1
6866    " append new filename to global markfilelist
6867    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6868"    call Decho("append filename<".a:fname."> to global s:markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6869   else
6870    " remove new filename from global markfilelist
6871"    call Decho("remove new filename from global s:markfilelist",'~'.expand("<slnum>"))
6872"    call Decho("..filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6873    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6874"    call Decho("..ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6875    if s:netrwmarkfilelist == []
6876"     call Decho("s:netrwmarkfilelist is empty; unlet it",'~'.expand("<slnum>"))
6877     unlet s:netrwmarkfilelist
6878    endif
6879   endif
6880  else
6881   " initialize new global-directory markfilelist
6882   let s:netrwmarkfilelist= []
6883   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6884"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6885  endif
6886
6887  " set up 2match'ing to netrwmarkfilemtch_# list
6888  if has("syntax") && exists("g:syntax_on") && g:syntax_on
6889   if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6890" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6891    if exists("g:did_drchip_netrwlist_syntax")
6892     exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6893    endif
6894   else
6895" "   call Decho("2match none",'~'.expand("<slnum>"))
6896    2match none
6897   endif
6898  endif
6899  let @@= ykeep
6900"  call Decho("s:netrwmarkfilelist[".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : "")."] (avail in all buffers)",'~'.expand("<slnum>"))
6901"  call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">  (buf#".curbufnr."list)")
6902endfun
6903
6904" ---------------------------------------------------------------------
6905" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6906"                         mA: move the argument list to marked file list     (tomflist=1)
6907"                            Uses the global marked file list
6908fun! s:NetrwMarkFileArgList(islocal,tomflist)
6909"  call Dfunc("s:NetrwMarkFileArgList(islocal=".a:islocal.",tomflist=".a:tomflist.")")
6910
6911  let svpos    = winsaveview()
6912"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6913  let curdir   = s:NetrwGetCurdir(a:islocal)
6914  let curbufnr = bufnr("%")
6915
6916  if a:tomflist
6917   " mA: move argument list to marked file list
6918   while argc()
6919    let fname= argv(0)
6920"    call Decho("exe argdel ".fname,'~'.expand("<slnum>"))
6921    exe "argdel ".fnameescape(fname)
6922    call s:NetrwMarkFile(a:islocal,fname)
6923   endwhile
6924
6925  else
6926   " ma: move marked file list to argument list
6927   if exists("s:netrwmarkfilelist")
6928
6929    " for every filename in the marked list
6930    for fname in s:netrwmarkfilelist
6931"     call Decho("exe argadd ".fname,'~'.expand("<slnum>"))
6932     exe "argadd ".fnameescape(fname)
6933    endfor	" for every file in the marked list
6934
6935    " unmark list and refresh
6936    call s:NetrwUnmarkList(curbufnr,curdir)
6937    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6938"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6939    NetrwKeepj call winrestview(svpos)
6940   endif
6941  endif
6942
6943"  call Dret("s:NetrwMarkFileArgList")
6944endfun
6945
6946" ---------------------------------------------------------------------
6947" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6948"                          compress/decompress files using the programs
6949"                          in g:netrw_compress and g:netrw_uncompress,
6950"                          using g:netrw_compress_suffix to know which to
6951"                          do.  By default:
6952"                            g:netrw_compress        = "gzip"
6953"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6954fun! s:NetrwMarkFileCompress(islocal)
6955"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
6956  let svpos    = winsaveview()
6957"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6958  let curdir   = s:NetrwGetCurdir(a:islocal)
6959  let curbufnr = bufnr("%")
6960
6961  " sanity check
6962  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6963   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6964"   call Dret("s:NetrwMarkFileCompress")
6965   return
6966  endif
6967"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6968
6969  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6970
6971   " for every filename in the marked list
6972   for fname in s:netrwmarkfilelist_{curbufnr}
6973    let sfx= substitute(fname,'^.\{-}\(\.\a\+\)$','\1','')
6974"    call Decho("extracted sfx<".sfx.">",'~'.expand("<slnum>"))
6975    if exists("g:netrw_decompress['".sfx."']")
6976     " fname has a suffix indicating that its compressed; apply associated decompression routine
6977     let exe= g:netrw_decompress[sfx]
6978"     call Decho("fname<".fname."> is compressed so decompress with <".exe.">",'~'.expand("<slnum>"))
6979     let exe= netrw#WinPath(exe)
6980     if a:islocal
6981      if g:netrw_keepdir
6982       let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6983      endif
6984      call system(exe." ".fname)
6985      if v:shell_error
6986       NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6987      endif
6988     else
6989      let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6990      NetrwKeepj call s:RemoteSystem(exe." ".fname)
6991     endif
6992
6993    endif
6994    unlet sfx
6995
6996    if exists("exe")
6997     unlet exe
6998    elseif a:islocal
6999     " fname not a compressed file, so compress it
7000     call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
7001     if v:shell_error
7002      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_compress<".g:netrw_compress."> to something that works",104)
7003     endif
7004    else
7005     " fname not a compressed file, so compress it
7006     NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
7007    endif
7008   endfor	" for every file in the marked list
7009
7010   call s:NetrwUnmarkList(curbufnr,curdir)
7011   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7012"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7013   NetrwKeepj call winrestview(svpos)
7014  endif
7015"  call Dret("s:NetrwMarkFileCompress")
7016endfun
7017
7018" ---------------------------------------------------------------------
7019" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
7020"                      If no marked files, then set up directory as the
7021"                      target.  Currently does not support copying entire
7022"                      directories.  Uses the local-buffer marked file list.
7023"                      Returns 1=success  (used by NetrwMarkFileMove())
7024"                              0=failure
7025fun! s:NetrwMarkFileCopy(islocal,...)
7026"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
7027
7028  let curdir   = s:NetrwGetCurdir(a:islocal)
7029  let curbufnr = bufnr("%")
7030  if b:netrw_curdir !~ '/$'
7031   if !exists("b:netrw_curdir")
7032    let b:netrw_curdir= curdir
7033   endif
7034   let b:netrw_curdir= b:netrw_curdir."/"
7035  endif
7036
7037  " sanity check
7038  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7039   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7040"   call Dret("s:NetrwMarkFileCopy")
7041   return
7042  endif
7043"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7044
7045  if !exists("s:netrwmftgt")
7046   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
7047"   call Dret("s:NetrwMarkFileCopy 0")
7048   return 0
7049  endif
7050"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7051
7052  if a:islocal &&  s:netrwmftgt_islocal
7053   " Copy marked files, local directory to local directory
7054"   call Decho("copy from local to local",'~'.expand("<slnum>"))
7055   if !executable(g:netrw_localcopycmd)
7056    call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
7057"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
7058    return
7059   endif
7060
7061   " copy marked files while within the same directory (ie. allow renaming)
7062   if simplify(s:netrwmftgt) == simplify(b:netrw_curdir)
7063    if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
7064     " only one marked file
7065"     call Decho("case: only one marked file",'~'.expand("<slnum>"))
7066     let args    = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
7067     let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
7068    elseif a:0 == 1
7069"     call Decho("case: handling one input argument",'~'.expand("<slnum>"))
7070     " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
7071     let args    = s:ShellEscape(b:netrw_curdir.a:1)
7072     let oldname = a:1
7073    else
7074     " copy multiple marked files inside the same directory
7075"     call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
7076     let s:recursive= 1
7077     for oldname in s:netrwmarkfilelist_{bufnr("%")}
7078      let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
7079      if ret == 0
7080       break
7081      endif
7082     endfor
7083     unlet s:recursive
7084     call s:NetrwUnmarkList(curbufnr,curdir)
7085"     call Dret("s:NetrwMarkFileCopy ".ret)
7086     return ret
7087    endif
7088
7089    call inputsave()
7090    let newname= input("Copy ".oldname." to : ",oldname,"file")
7091    call inputrestore()
7092    if newname == ""
7093"     call Dret("s:NetrwMarkFileCopy 0")
7094     return 0
7095    endif
7096    let args= s:ShellEscape(oldname)
7097    let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
7098   else
7099    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
7100    let tgt = s:ShellEscape(s:netrwmftgt)
7101   endif
7102   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7103    let args= substitute(args,'/','\\','g')
7104    let tgt = substitute(tgt, '/','\\','g')
7105   endif
7106   if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
7107   if tgt  =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
7108   if args =~ '//'|let args= substitute(args,'//','/','g')|endif
7109   if tgt  =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
7110"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
7111"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
7112   if isdirectory(s:NetrwFile(args))
7113"    call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
7114    let copycmd= g:netrw_localcopydircmd
7115"    call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
7116    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7117     " window's xcopy doesn't copy a directory to a target properly.  Instead, it copies a directory's
7118     " contents to a target.  One must append the source directory name to the target to get xcopy to
7119     " do the right thing.
7120     let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
7121"     call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
7122    endif
7123   else
7124    let copycmd= g:netrw_localcopycmd
7125   endif
7126   if g:netrw_localcopycmd =~ '\s'
7127    let copycmd     = substitute(copycmd,'\s.*$','','')
7128    let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
7129    let copycmd     = netrw#WinPath(copycmd).copycmdargs
7130   else
7131    let copycmd = netrw#WinPath(copycmd)
7132   endif
7133"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
7134"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
7135"   call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
7136"   call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
7137   call system(copycmd.g:netrw_localcopycmdopt." '".args."' '".tgt."'")
7138   if v:shell_error != 0
7139    if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7140     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-cd)",101)
7141    else
7142     call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
7143    endif
7144"    call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
7145    return 0
7146   endif
7147
7148  elseif  a:islocal && !s:netrwmftgt_islocal
7149   " Copy marked files, local directory to remote directory
7150"   call Decho("copy from local to remote",'~'.expand("<slnum>"))
7151   NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
7152
7153  elseif !a:islocal &&  s:netrwmftgt_islocal
7154   " Copy marked files, remote directory to local directory
7155"   call Decho("copy from remote to local",'~'.expand("<slnum>"))
7156   NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
7157
7158  elseif !a:islocal && !s:netrwmftgt_islocal
7159   " Copy marked files, remote directory to remote directory
7160"   call Decho("copy from remote to remote",'~'.expand("<slnum>"))
7161   let curdir = getcwd()
7162   let tmpdir = s:GetTempfile("")
7163   if tmpdir !~ '/'
7164    let tmpdir= curdir."/".tmpdir
7165   endif
7166   if exists("*mkdir")
7167    call mkdir(tmpdir)
7168   else
7169    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(tmpdir,1))
7170    if v:shell_error != 0
7171     call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
7172"     call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
7173     return
7174    endif
7175   endif
7176   if isdirectory(s:NetrwFile(tmpdir))
7177    if s:NetrwLcd(tmpdir)
7178"     call Dret("s:NetrwMarkFileCopy : lcd failure")
7179     return
7180    endif
7181    NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
7182    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
7183    NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
7184    if getcwd() == tmpdir
7185     for fname in s:netrwmarkfilelist_{bufnr('%')}
7186      NetrwKeepj call s:NetrwDelete(fname)
7187     endfor
7188     if s:NetrwLcd(curdir)
7189"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7190      return
7191     endif
7192     if delete(tmpdir,"d")
7193      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
7194     endif
7195    else
7196     if s:NetrwLcd(curdir)
7197"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7198      return
7199     endif
7200    endif
7201   endif
7202  endif
7203
7204  " -------
7205  " cleanup
7206  " -------
7207"  call Decho("cleanup",'~'.expand("<slnum>"))
7208  " remove markings from local buffer
7209  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7210"  call Decho(" g:netrw_fastbrowse  =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
7211"  call Decho(" s:netrwmftgt        =".s:netrwmftgt,'~'.expand("<slnum>"))
7212"  call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
7213"  call Decho(" curdir              =".curdir,'~'.expand("<slnum>"))
7214"  call Decho(" a:islocal           =".a:islocal,'~'.expand("<slnum>"))
7215"  call Decho(" curbufnr            =".curbufnr,'~'.expand("<slnum>"))
7216  if exists("s:recursive")
7217"   call Decho(" s:recursive         =".s:recursive,'~'.expand("<slnum>"))
7218  else
7219"   call Decho(" s:recursive         =n/a",'~'.expand("<slnum>"))
7220  endif
7221  " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
7222  if g:netrw_fastbrowse <= 1
7223   NetrwKeepj call s:LocalBrowseRefresh()
7224  else
7225   " refresh local and targets for fast browsing
7226   if !exists("s:recursive")
7227    " remove markings from local buffer
7228"    call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
7229    NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
7230   endif
7231
7232   " refresh buffers
7233   if s:netrwmftgt_islocal
7234"    call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
7235    NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7236   endif
7237   if a:islocal && s:netrwmftgt != curdir
7238"    call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
7239    NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
7240   endif
7241  endif
7242
7243"  call Dret("s:NetrwMarkFileCopy 1")
7244  return 1
7245endfun
7246
7247" ---------------------------------------------------------------------
7248" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
7249"                      invoke vim's diff mode on the marked files.
7250"                      Either two or three files can be so handled.
7251"                      Uses the global marked file list.
7252fun! s:NetrwMarkFileDiff(islocal)
7253"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
7254  let curbufnr= bufnr("%")
7255
7256  " sanity check
7257  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7258   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7259"   call Dret("s:NetrwMarkFileDiff")
7260   return
7261  endif
7262  let curdir= s:NetrwGetCurdir(a:islocal)
7263"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7264
7265  if exists("s:netrwmarkfilelist_{".curbufnr."}")
7266   let cnt    = 0
7267   for fname in s:netrwmarkfilelist
7268    let cnt= cnt + 1
7269    if cnt == 1
7270"     call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
7271     exe "NetrwKeepj e ".fnameescape(fname)
7272     diffthis
7273    elseif cnt == 2 || cnt == 3
7274     vsplit
7275     wincmd l
7276"     call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
7277     exe "NetrwKeepj e ".fnameescape(fname)
7278     diffthis
7279    else
7280     break
7281    endif
7282   endfor
7283   call s:NetrwUnmarkList(curbufnr,curdir)
7284  endif
7285
7286"  call Dret("s:NetrwMarkFileDiff")
7287endfun
7288
7289" ---------------------------------------------------------------------
7290" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
7291"                       Uses global markfilelist
7292fun! s:NetrwMarkFileEdit(islocal)
7293"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
7294
7295  let curdir   = s:NetrwGetCurdir(a:islocal)
7296  let curbufnr = bufnr("%")
7297
7298  " sanity check
7299  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7300   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7301"   call Dret("s:NetrwMarkFileEdit")
7302   return
7303  endif
7304"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7305
7306  if exists("s:netrwmarkfilelist_{curbufnr}")
7307   call s:SetRexDir(a:islocal,curdir)
7308   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7309   " unmark markedfile list
7310"   call s:NetrwUnmarkList(curbufnr,curdir)
7311   call s:NetrwUnmarkAll()
7312"   call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
7313   exe "sil args ".flist
7314  endif
7315  echo "(use :bn, :bp to navigate files; :Rex to return)"
7316
7317"  call Dret("s:NetrwMarkFileEdit")
7318endfun
7319
7320" ---------------------------------------------------------------------
7321" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
7322fun! s:NetrwMarkFileQFEL(islocal,qfel)
7323"  call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
7324  call s:NetrwUnmarkAll()
7325  let curbufnr= bufnr("%")
7326
7327  if !empty(a:qfel)
7328   for entry in a:qfel
7329    let bufnmbr= entry["bufnr"]
7330"    call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
7331    if !exists("s:netrwmarkfilelist_{curbufnr}")
7332"     call Decho("case: no marked file list",'~'.expand("<slnum>"))
7333     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7334    elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
7335     " s:NetrwMarkFile will remove duplicate entries from the marked file list.
7336     " So, this test lets two or more hits on the same pattern to be ignored.
7337"     call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
7338     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7339    else
7340"     call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
7341    endif
7342   endfor
7343   echo "(use me to edit marked files)"
7344  else
7345   call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
7346  endif
7347
7348"  call Dret("s:NetrwMarkFileQFEL")
7349endfun
7350
7351" ---------------------------------------------------------------------
7352" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
7353"                     mx enbloc=0: Uses the local marked-file list, applies command to each file individually
7354"                     mX enbloc=1: Uses the global marked-file list, applies command to entire list
7355fun! s:NetrwMarkFileExe(islocal,enbloc)
7356"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")")
7357  let svpos    = winsaveview()
7358"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7359  let curdir   = s:NetrwGetCurdir(a:islocal)
7360  let curbufnr = bufnr("%")
7361
7362  if a:enbloc == 0
7363   " individually apply command to files, one at a time
7364    " sanity check
7365    if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7366     NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7367"     call Dret("s:NetrwMarkFileExe")
7368     return
7369    endif
7370"    call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7371
7372    if exists("s:netrwmarkfilelist_{curbufnr}")
7373     " get the command
7374     call inputsave()
7375     let cmd= input("Enter command: ","","file")
7376     call inputrestore()
7377"     call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7378     if cmd == ""
7379"      call Dret("s:NetrwMarkFileExe : early exit, empty command")
7380      return
7381     endif
7382
7383     " apply command to marked files, individually.  Substitute: filename -> %
7384     " If no %, then append a space and the filename to the command
7385     for fname in s:netrwmarkfilelist_{curbufnr}
7386      if a:islocal
7387       if g:netrw_keepdir
7388	let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
7389       endif
7390      else
7391       let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
7392      endif
7393      if cmd =~ '%'
7394       let xcmd= substitute(cmd,'%',fname,'g')
7395      else
7396       let xcmd= cmd.' '.fname
7397      endif
7398      if a:islocal
7399"       call Decho("local: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7400       let ret= system(xcmd)
7401      else
7402"       call Decho("remote: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7403       let ret= s:RemoteSystem(xcmd)
7404      endif
7405      if v:shell_error < 0
7406       NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7407       break
7408      else
7409       echo ret
7410      endif
7411     endfor
7412
7413   " unmark marked file list
7414   call s:NetrwUnmarkList(curbufnr,curdir)
7415
7416   " refresh the listing
7417   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7418"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7419   NetrwKeepj call winrestview(svpos)
7420  else
7421   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7422  endif
7423
7424 else " apply command to global list of files, en bloc
7425
7426  call inputsave()
7427  let cmd= input("Enter command: ","","file")
7428  call inputrestore()
7429"  call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7430  if cmd == ""
7431"   call Dret("s:NetrwMarkFileExe : early exit, empty command")
7432   return
7433  endif
7434  if cmd =~ '%'
7435   let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7436  else
7437   let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7438  endif
7439  if a:islocal
7440   call system(cmd)
7441   if v:shell_error < 0
7442    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7443   endif
7444  else
7445   let ret= s:RemoteSystem(cmd)
7446  endif
7447  call s:NetrwUnmarkAll()
7448
7449  " refresh the listing
7450  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7451"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7452  NetrwKeepj call winrestview(svpos)
7453
7454 endif
7455
7456"  call Dret("s:NetrwMarkFileExe")
7457endfun
7458
7459" ---------------------------------------------------------------------
7460" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7461"                  as the marked file(s) (toggles suffix presence)
7462"                  Uses the local marked file list.
7463fun! s:NetrwMarkHideSfx(islocal)
7464"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7465  let svpos    = winsaveview()
7466"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7467  let curbufnr = bufnr("%")
7468
7469  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7470  if exists("s:netrwmarkfilelist_{curbufnr}")
7471
7472   for fname in s:netrwmarkfilelist_{curbufnr}
7473"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7474     " construct suffix pattern
7475     if fname =~ '\.'
7476      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7477     else
7478      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7479     endif
7480     " determine if its in the hiding list or not
7481     let inhidelist= 0
7482     if g:netrw_list_hide != ""
7483      let itemnum = 0
7484      let hidelist= split(g:netrw_list_hide,',')
7485      for hidepat in hidelist
7486       if sfxpat == hidepat
7487        let inhidelist= 1
7488        break
7489       endif
7490       let itemnum= itemnum + 1
7491      endfor
7492     endif
7493"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7494     if inhidelist
7495      " remove sfxpat from list
7496      call remove(hidelist,itemnum)
7497      let g:netrw_list_hide= join(hidelist,",")
7498     elseif g:netrw_list_hide != ""
7499      " append sfxpat to non-empty list
7500      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7501     else
7502      " set hiding list to sfxpat
7503      let g:netrw_list_hide= sfxpat
7504     endif
7505    endfor
7506
7507   " refresh the listing
7508   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7509"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7510   NetrwKeepj call winrestview(svpos)
7511  else
7512   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7513  endif
7514
7515"  call Dret("s:NetrwMarkHideSfx")
7516endfun
7517
7518" ---------------------------------------------------------------------
7519" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7520"                     Uses the local marked-file list.
7521fun! s:NetrwMarkFileVimCmd(islocal)
7522"  call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")")
7523  let svpos    = winsaveview()
7524"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7525  let curdir   = s:NetrwGetCurdir(a:islocal)
7526  let curbufnr = bufnr("%")
7527
7528  " sanity check
7529  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7530   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7531"   call Dret("s:NetrwMarkFileVimCmd")
7532   return
7533  endif
7534"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7535
7536  if exists("s:netrwmarkfilelist_{curbufnr}")
7537   " get the command
7538   call inputsave()
7539   let cmd= input("Enter vim command: ","","file")
7540   call inputrestore()
7541"   call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7542   if cmd == ""
7543"    "   call Dret("s:NetrwMarkFileVimCmd : early exit, empty command")
7544    return
7545   endif
7546
7547   " apply command to marked files.  Substitute: filename -> %
7548   " If no %, then append a space and the filename to the command
7549   for fname in s:netrwmarkfilelist_{curbufnr}
7550"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7551    if a:islocal
7552     1split
7553     exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7554"     call Decho("local<".fname.">: exe ".cmd,'~'.expand("<slnum>"))
7555     exe cmd
7556     exe "sil! keepalt wq!"
7557    else
7558"     call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET",'~'.expand("<slnum>"))
7559     echo "sorry, \"mv\" not supported yet for remote files"
7560    endif
7561   endfor
7562
7563   " unmark marked file list
7564   call s:NetrwUnmarkList(curbufnr,curdir)
7565
7566   " refresh the listing
7567   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7568"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7569   NetrwKeepj call winrestview(svpos)
7570  else
7571   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7572  endif
7573
7574"  call Dret("s:NetrwMarkFileVimCmd")
7575endfun
7576
7577" ---------------------------------------------------------------------
7578" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7579"                  as the marked file(s) (toggles suffix presence)
7580"                  Uses the local marked file list.
7581fun! s:NetrwMarkHideSfx(islocal)
7582"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7583  let svpos    = winsaveview()
7584"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7585  let curbufnr = bufnr("%")
7586
7587  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7588  if exists("s:netrwmarkfilelist_{curbufnr}")
7589
7590   for fname in s:netrwmarkfilelist_{curbufnr}
7591"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7592     " construct suffix pattern
7593     if fname =~ '\.'
7594      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7595     else
7596      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7597     endif
7598     " determine if its in the hiding list or not
7599     let inhidelist= 0
7600     if g:netrw_list_hide != ""
7601      let itemnum = 0
7602      let hidelist= split(g:netrw_list_hide,',')
7603      for hidepat in hidelist
7604       if sfxpat == hidepat
7605        let inhidelist= 1
7606        break
7607       endif
7608       let itemnum= itemnum + 1
7609      endfor
7610     endif
7611"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7612     if inhidelist
7613      " remove sfxpat from list
7614      call remove(hidelist,itemnum)
7615      let g:netrw_list_hide= join(hidelist,",")
7616     elseif g:netrw_list_hide != ""
7617      " append sfxpat to non-empty list
7618      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7619     else
7620      " set hiding list to sfxpat
7621      let g:netrw_list_hide= sfxpat
7622     endif
7623    endfor
7624
7625   " refresh the listing
7626   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7627"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7628   NetrwKeepj call winrestview(svpos)
7629  else
7630   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7631  endif
7632
7633"  call Dret("s:NetrwMarkHideSfx")
7634endfun
7635
7636" ---------------------------------------------------------------------
7637" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7638"                     Uses the global markfilelist
7639fun! s:NetrwMarkFileGrep(islocal)
7640"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7641  let svpos    = winsaveview()
7642"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7643  let curbufnr = bufnr("%")
7644  let curdir   = s:NetrwGetCurdir(a:islocal)
7645
7646  if exists("s:netrwmarkfilelist")
7647"   call Decho("using s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7648   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7649"   call Decho("keeping copy of s:netrwmarkfilelist in function-local variable,'~'.expand("<slnum>"))"
7650   call s:NetrwUnmarkAll()
7651  else
7652"   call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7653   let netrwmarkfilelist= "*"
7654  endif
7655
7656  " ask user for pattern
7657"  call Decho("ask user for search pattern",'~'.expand("<slnum>"))
7658  call inputsave()
7659  let pat= input("Enter pattern: ","")
7660  call inputrestore()
7661  let patbang = ""
7662  if pat =~ '^!'
7663   let patbang = "!"
7664   let pat     = strpart(pat,2)
7665  endif
7666  if pat =~ '^\i'
7667   let pat    = escape(pat,'/')
7668   let pat    = '/'.pat.'/'
7669  else
7670   let nonisi = pat[0]
7671  endif
7672
7673  " use vimgrep for both local and remote
7674"  call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7675  try
7676   exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7677  catch /^Vim\%((\a\+)\)\=:E480/
7678   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7679"   call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7680   return
7681  endtry
7682  echo "(use :cn, :cp to navigate, :Rex to return)"
7683
7684  2match none
7685"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7686  NetrwKeepj call winrestview(svpos)
7687
7688  if exists("nonisi")
7689   " original, user-supplied pattern did not begin with a character from isident
7690"   call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7691   if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7692    call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7693   endif
7694  endif
7695
7696"  call Dret("s:NetrwMarkFileGrep")
7697endfun
7698
7699" ---------------------------------------------------------------------
7700" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7701"                      uses the global marked file list
7702"                      s:netrwmfloc= 0: target directory is remote
7703"                                  = 1: target directory is local
7704fun! s:NetrwMarkFileMove(islocal)
7705"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7706  let curdir   = s:NetrwGetCurdir(a:islocal)
7707  let curbufnr = bufnr("%")
7708
7709  " sanity check
7710  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7711   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7712"   call Dret("s:NetrwMarkFileMove")
7713   return
7714  endif
7715"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7716
7717  if !exists("s:netrwmftgt")
7718   NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7719"   call Dret("s:NetrwMarkFileCopy 0")
7720   return 0
7721  endif
7722"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7723
7724  if      a:islocal &&  s:netrwmftgt_islocal
7725   " move: local -> local
7726"   call Decho("move from local to local",'~'.expand("<slnum>"))
7727"   call Decho("local to local move",'~'.expand("<slnum>"))
7728   if !executable(g:netrw_localmovecmd)
7729    call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7730"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7731    return
7732   endif
7733   let tgt = s:ShellEscape(s:netrwmftgt)
7734"   call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7735   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7736    let tgt= substitute(tgt, '/','\\','g')
7737"    call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7738    if g:netrw_localmovecmd =~ '\s'
7739     let movecmd     = substitute(g:netrw_localmovecmd,'\s.*$','','')
7740     let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7741     let movecmd     = netrw#WinPath(movecmd).movecmdargs
7742"     call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7743    else
7744     let movecmd = netrw#WinPath(movecmd)
7745"     call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7746    endif
7747   else
7748    let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7749"    call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7750   endif
7751   for fname in s:netrwmarkfilelist_{bufnr("%")}
7752    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7753     let fname= substitute(fname,'/','\\','g')
7754    endif
7755"    call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7756    let ret= system(movecmd.g:netrw_localmovecmdopt." ".s:ShellEscape(fname)." ".tgt)
7757    if v:shell_error != 0
7758     if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7759      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-cd)",100)
7760     else
7761      call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7762     endif
7763     break
7764    endif
7765   endfor
7766
7767  elseif  a:islocal && !s:netrwmftgt_islocal
7768   " move: local -> remote
7769"   call Decho("move from local to remote",'~'.expand("<slnum>"))
7770"   call Decho("copy",'~'.expand("<slnum>"))
7771   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7772   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7773"   call Decho("remove",'~'.expand("<slnum>"))
7774   for fname in mflist
7775    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7776    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7777   endfor
7778   unlet mflist
7779
7780  elseif !a:islocal &&  s:netrwmftgt_islocal
7781   " move: remote -> local
7782"   call Decho("move from remote to local",'~'.expand("<slnum>"))
7783"   call Decho("copy",'~'.expand("<slnum>"))
7784   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7785   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7786"   call Decho("remove",'~'.expand("<slnum>"))
7787   for fname in mflist
7788    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7789    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7790   endfor
7791   unlet mflist
7792
7793  elseif !a:islocal && !s:netrwmftgt_islocal
7794   " move: remote -> remote
7795"   call Decho("move from remote to remote",'~'.expand("<slnum>"))
7796"   call Decho("copy",'~'.expand("<slnum>"))
7797   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7798   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7799"   call Decho("remove",'~'.expand("<slnum>"))
7800   for fname in mflist
7801    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7802    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7803   endfor
7804   unlet mflist
7805  endif
7806
7807  " -------
7808  " cleanup
7809  " -------
7810"  call Decho("cleanup",'~'.expand("<slnum>"))
7811
7812  " remove markings from local buffer
7813  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7814
7815  " refresh buffers
7816  if !s:netrwmftgt_islocal
7817"   call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7818   NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7819  endif
7820  if a:islocal
7821"   call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7822   NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7823  endif
7824  if g:netrw_fastbrowse <= 1
7825"   call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7826   NetrwKeepj call s:LocalBrowseRefresh()
7827  endif
7828
7829"  call Dret("s:NetrwMarkFileMove")
7830endfun
7831
7832" ---------------------------------------------------------------------
7833" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7834"                       using the hardcopy command.  Local marked-file list only.
7835fun! s:NetrwMarkFilePrint(islocal)
7836"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7837  let curbufnr= bufnr("%")
7838
7839  " sanity check
7840  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7841   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7842"   call Dret("s:NetrwMarkFilePrint")
7843   return
7844  endif
7845"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7846  let curdir= s:NetrwGetCurdir(a:islocal)
7847
7848  if exists("s:netrwmarkfilelist_{curbufnr}")
7849   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7850   call s:NetrwUnmarkList(curbufnr,curdir)
7851   for fname in netrwmarkfilelist
7852    if a:islocal
7853     if g:netrw_keepdir
7854      let fname= s:ComposePath(curdir,fname)
7855     endif
7856    else
7857     let fname= curdir.fname
7858    endif
7859    1split
7860    " the autocmds will handle both local and remote files
7861"    call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7862    exe "sil NetrwKeepj e ".fnameescape(fname)
7863"    call Decho("hardcopy",'~'.expand("<slnum>"))
7864    hardcopy
7865    q
7866   endfor
7867   2match none
7868  endif
7869"  call Dret("s:NetrwMarkFilePrint")
7870endfun
7871
7872" ---------------------------------------------------------------------
7873" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7874"                        files when given a regexp (for which a prompt is
7875"                        issued) (matches to name of files).
7876fun! s:NetrwMarkFileRegexp(islocal)
7877"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7878
7879  " get the regular expression
7880  call inputsave()
7881  let regexp= input("Enter regexp: ","","file")
7882  call inputrestore()
7883
7884  if a:islocal
7885   let curdir= s:NetrwGetCurdir(a:islocal)
7886"   call Decho("curdir<".fnameescape(curdir).">")
7887   " get the matching list of files using local glob()
7888"   call Decho("handle local regexp",'~'.expand("<slnum>"))
7889   let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7890   if v:version > 704 || (v:version == 704 && has("patch656"))
7891    let filelist= glob(s:ComposePath(dirname,regexp),0,1,1)
7892   else
7893    let files   = glob(s:ComposePath(dirname,regexp),0,0)
7894    let filelist= split(files,"\n")
7895   endif
7896"   call Decho("files<".string(filelist).">",'~'.expand("<slnum>"))
7897
7898  " mark the list of files
7899  for fname in filelist
7900   if fname =~ '^'.fnameescape(curdir)
7901"    call Decho("fname<".substitute(fname,'^'.fnameescape(curdir).'/','','').">",'~'.expand("<slnum>"))
7902    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^'.fnameescape(curdir).'/','',''))
7903   else
7904"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7905    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7906   endif
7907  endfor
7908
7909  else
7910"   call Decho("handle remote regexp",'~'.expand("<slnum>"))
7911
7912   " convert displayed listing into a filelist
7913   let eikeep = &ei
7914   let areg   = @a
7915   sil NetrwKeepj %y a
7916   setl ei=all ma
7917"   call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7918   1split
7919   NetrwKeepj call s:NetrwEnew()
7920   NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
7921   sil NetrwKeepj norm! "ap
7922   NetrwKeepj 2
7923   let bannercnt= search('^" =====','W')
7924   exe "sil NetrwKeepj 1,".bannercnt."d"
7925   setl bt=nofile
7926   if     g:netrw_liststyle == s:LONGLIST
7927    sil NetrwKeepj %s/\s\{2,}\S.*$//e
7928    call histdel("/",-1)
7929   elseif g:netrw_liststyle == s:WIDELIST
7930    sil NetrwKeepj %s/\s\{2,}/\r/ge
7931    call histdel("/",-1)
7932   elseif g:netrw_liststyle == s:TREELIST
7933    exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7934    sil! NetrwKeepj g/^ .*$/d
7935    call histdel("/",-1)
7936    call histdel("/",-1)
7937   endif
7938   " convert regexp into the more usual glob-style format
7939   let regexp= substitute(regexp,'\*','.*','g')
7940"   call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7941   exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7942   call histdel("/",-1)
7943   let filelist= getline(1,line("$"))
7944   q!
7945   for filename in filelist
7946    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7947   endfor
7948   unlet filelist
7949   let @a  = areg
7950   let &ei = eikeep
7951  endif
7952  echo "  (use me to edit marked files)"
7953
7954"  call Dret("s:NetrwMarkFileRegexp")
7955endfun
7956
7957" ---------------------------------------------------------------------
7958" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7959"                        Uses the local marked file list.
7960fun! s:NetrwMarkFileSource(islocal)
7961"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7962  let curbufnr= bufnr("%")
7963
7964  " sanity check
7965  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7966   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7967"   call Dret("s:NetrwMarkFileSource")
7968   return
7969  endif
7970"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7971  let curdir= s:NetrwGetCurdir(a:islocal)
7972
7973  if exists("s:netrwmarkfilelist_{curbufnr}")
7974   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7975   call s:NetrwUnmarkList(curbufnr,curdir)
7976   for fname in netrwmarkfilelist
7977    if a:islocal
7978     if g:netrw_keepdir
7979      let fname= s:ComposePath(curdir,fname)
7980     endif
7981    else
7982     let fname= curdir.fname
7983    endif
7984    " the autocmds will handle sourcing both local and remote files
7985"    call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7986    exe "so ".fnameescape(fname)
7987   endfor
7988   2match none
7989  endif
7990"  call Dret("s:NetrwMarkFileSource")
7991endfun
7992
7993" ---------------------------------------------------------------------
7994" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
7995"                     Uses the global markfilelist
7996fun! s:NetrwMarkFileTag(islocal)
7997"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
7998  let svpos    = winsaveview()
7999"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8000  let curdir   = s:NetrwGetCurdir(a:islocal)
8001  let curbufnr = bufnr("%")
8002
8003  " sanity check
8004  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
8005   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
8006"   call Dret("s:NetrwMarkFileTag")
8007   return
8008  endif
8009"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
8010
8011  if exists("s:netrwmarkfilelist")
8012"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
8013   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
8014   call s:NetrwUnmarkAll()
8015
8016   if a:islocal
8017
8018"    call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("<slnum>"))
8019    call system(g:netrw_ctags." ".netrwmarkfilelist)
8020    if v:shell_error
8021     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
8022    endif
8023
8024   else
8025    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
8026    call netrw#Obtain(a:islocal,"tags")
8027    let curdir= b:netrw_curdir
8028    1split
8029    NetrwKeepj e tags
8030    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
8031"    call Decho("curdir<".curdir."> path<".path.">",'~'.expand("<slnum>"))
8032    exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
8033    call histdel("/",-1)
8034    wq!
8035   endif
8036   2match none
8037   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8038"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8039   call winrestview(svpos)
8040  endif
8041
8042"  call Dret("s:NetrwMarkFileTag")
8043endfun
8044
8045" ---------------------------------------------------------------------
8046" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
8047"   Sets up two variables,
8048"     s:netrwmftgt         : holds the target directory
8049"     s:netrwmftgt_islocal : 0=target directory is remote
8050"                            1=target directory is local
8051fun! s:NetrwMarkFileTgt(islocal)
8052" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
8053  let svpos  = winsaveview()
8054"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8055  let curdir = s:NetrwGetCurdir(a:islocal)
8056  let hadtgt = exists("s:netrwmftgt")
8057  if !exists("w:netrw_bannercnt")
8058   let w:netrw_bannercnt= b:netrw_bannercnt
8059  endif
8060
8061  " set up target
8062  if line(".") < w:netrw_bannercnt
8063"   call Decho("set up target: line(.) < w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
8064   " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
8065   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
8066"    call Decho("cursor in banner region, and target already is <".b:netrw_curdir.">: removing target",'~'.expand("<slnum>"))
8067    unlet s:netrwmftgt s:netrwmftgt_islocal
8068    if g:netrw_fastbrowse <= 1
8069     call s:LocalBrowseRefresh()
8070    endif
8071    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8072"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8073    call winrestview(svpos)
8074"    call Dret("s:NetrwMarkFileTgt : removed target")
8075    return
8076   else
8077    let s:netrwmftgt= b:netrw_curdir
8078"    call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8079   endif
8080
8081  else
8082   " get word under cursor.
8083   "  * If directory, use it for the target.
8084   "  * If file, use b:netrw_curdir for the target
8085"   call Decho("get word under cursor",'~'.expand("<slnum>"))
8086   let curword= s:NetrwGetWord()
8087   let tgtdir = s:ComposePath(curdir,curword)
8088   if a:islocal && isdirectory(s:NetrwFile(tgtdir))
8089    let s:netrwmftgt = tgtdir
8090"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8091   elseif !a:islocal && tgtdir =~ '/$'
8092    let s:netrwmftgt = tgtdir
8093"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8094   else
8095    let s:netrwmftgt = curdir
8096"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8097   endif
8098  endif
8099  if a:islocal
8100   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
8101   let s:netrwmftgt= simplify(s:netrwmftgt)
8102"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8103  endif
8104  if g:netrw_cygwin
8105   let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
8106   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
8107  endif
8108  let s:netrwmftgt_islocal= a:islocal
8109
8110  " need to do refresh so that the banner will be updated
8111  "  s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
8112  if g:netrw_fastbrowse <= 1
8113"   call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers",'~'.expand("<slnum>"))
8114   call s:LocalBrowseRefresh()
8115  endif
8116"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8117  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8118   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop))
8119  else
8120   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8121  endif
8122"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8123  call winrestview(svpos)
8124  if !hadtgt
8125   sil! NetrwKeepj norm! j
8126  endif
8127
8128"  call Decho("getmatches=".string(getmatches()),'~'.expand("<slnum>"))
8129"  call Decho("s:netrwmarkfilelist=".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : 'n/a'),'~'.expand("<slnum>"))
8130"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
8131endfun
8132
8133" ---------------------------------------------------------------------
8134" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
8135fun! s:NetrwGetCurdir(islocal)
8136"  call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
8137
8138  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8139   let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
8140"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
8141  elseif !exists("b:netrw_curdir")
8142   let b:netrw_curdir= getcwd()
8143"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
8144  endif
8145
8146"  call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>"))
8147  if b:netrw_curdir !~ '\<\a\{3,}://'
8148   let curdir= b:netrw_curdir
8149"   call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
8150   if g:netrw_keepdir == 0
8151    call s:NetrwLcd(curdir)
8152   endif
8153  endif
8154
8155"  call Dret("s:NetrwGetCurdir <".curdir.">")
8156  return b:netrw_curdir
8157endfun
8158
8159" ---------------------------------------------------------------------
8160" s:NetrwOpenFile: query user for a filename and open it {{{2
8161fun! s:NetrwOpenFile(islocal)
8162"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
8163  let ykeep= @@
8164  call inputsave()
8165  let fname= input("Enter filename: ")
8166  call inputrestore()
8167  if fname !~ '[/\\]'
8168   if exists("b:netrw_curdir")
8169    if exists("g:netrw_quiet")
8170     let netrw_quiet_keep = g:netrw_quiet
8171    endif
8172    let g:netrw_quiet = 1
8173    " save position for benefit of Rexplore
8174    let s:rexposn_{bufnr("%")}= winsaveview()
8175"    call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
8176    if b:netrw_curdir =~ '/$'
8177     exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
8178    else
8179     exe "e ".fnameescape(b:netrw_curdir."/".fname)
8180    endif
8181    if exists("netrw_quiet_keep")
8182     let g:netrw_quiet= netrw_quiet_keep
8183    else
8184     unlet g:netrw_quiet
8185    endif
8186   endif
8187  else
8188   exe "NetrwKeepj e ".fnameescape(fname)
8189  endif
8190  let @@= ykeep
8191"  call Dret("s:NetrwOpenFile")
8192endfun
8193
8194" ---------------------------------------------------------------------
8195" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
8196"               For the mapping to this function be made via
8197"               netrwPlugin, you'll need to have had
8198"               g:netrw_usetab set to non-zero.
8199fun! netrw#Shrink()
8200"  call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
8201  let curwin  = winnr()
8202  let wiwkeep = &wiw
8203  set wiw=1
8204
8205  if &ft == "netrw"
8206   if winwidth(0) > g:netrw_wiw
8207    let t:netrw_winwidth= winwidth(0)
8208    exe "vert resize ".g:netrw_wiw
8209    wincmd l
8210    if winnr() == curwin
8211     wincmd h
8212    endif
8213"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8214   else
8215    exe "vert resize ".t:netrw_winwidth
8216"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8217   endif
8218
8219  elseif exists("t:netrw_lexbufnr")
8220   exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
8221   if     winwidth(bufwinnr(t:netrw_lexbufnr)) >  g:netrw_wiw
8222    let t:netrw_winwidth= winwidth(0)
8223    exe "vert resize ".g:netrw_wiw
8224    wincmd l
8225    if winnr() == curwin
8226     wincmd h
8227    endif
8228"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8229   elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
8230    exe "vert resize ".t:netrw_winwidth
8231"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8232   else
8233    call netrw#Lexplore(0,0)
8234   endif
8235
8236  else
8237   call netrw#Lexplore(0,0)
8238  endif
8239  let wiw= wiwkeep
8240
8241"  call Dret("netrw#Shrink")
8242endfun
8243
8244" ---------------------------------------------------------------------
8245" s:NetSortSequence: allows user to edit the sorting sequence {{{2
8246fun! s:NetSortSequence(islocal)
8247"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
8248
8249  let ykeep= @@
8250  let svpos= winsaveview()
8251"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8252  call inputsave()
8253  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
8254  call inputrestore()
8255
8256  " refresh the listing
8257  let g:netrw_sort_sequence= newsortseq
8258  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8259"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8260  NetrwKeepj call winrestview(svpos)
8261  let @@= ykeep
8262
8263"  call Dret("NetSortSequence")
8264endfun
8265
8266" ---------------------------------------------------------------------
8267" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
8268"   User access provided by the <mF> mapping. (see :help netrw-mF)
8269"   Used by many MarkFile functions.
8270fun! s:NetrwUnmarkList(curbufnr,curdir)
8271"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
8272
8273  "  remove all files in local marked-file list from global list
8274  if exists("s:netrwmarkfilelist")
8275   for mfile in s:netrwmarkfilelist_{a:curbufnr}
8276    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
8277    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
8278    call remove(s:netrwmarkfilelist,idx)            " remove from global list
8279   endfor
8280   if s:netrwmarkfilelist == []
8281    unlet s:netrwmarkfilelist
8282   endif
8283
8284   " getting rid of the local marked-file lists is easy
8285   unlet s:netrwmarkfilelist_{a:curbufnr}
8286  endif
8287  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
8288   unlet s:netrwmarkfilemtch_{a:curbufnr}
8289  endif
8290  2match none
8291"  call Dret("s:NetrwUnmarkList")
8292endfun
8293
8294" ---------------------------------------------------------------------
8295" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
8296fun! s:NetrwUnmarkAll()
8297"  call Dfunc("s:NetrwUnmarkAll()")
8298  if exists("s:netrwmarkfilelist")
8299   unlet s:netrwmarkfilelist
8300  endif
8301  sil call s:NetrwUnmarkAll2()
8302  2match none
8303"  call Dret("s:NetrwUnmarkAll")
8304endfun
8305
8306" ---------------------------------------------------------------------
8307" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
8308fun! s:NetrwUnmarkAll2()
8309"  call Dfunc("s:NetrwUnmarkAll2()")
8310  redir => netrwmarkfilelist_let
8311  let
8312  redir END
8313  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
8314  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
8315  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
8316  for flist in netrwmarkfilelist_list
8317   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
8318   unlet s:netrwmarkfilelist_{curbufnr}
8319   unlet s:netrwmarkfilemtch_{curbufnr}
8320  endfor
8321"  call Dret("s:NetrwUnmarkAll2")
8322endfun
8323
8324" ---------------------------------------------------------------------
8325" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
8326"
8327" Marked files are in two types of lists:
8328"    s:netrwmarkfilelist    -- holds complete paths to all marked files
8329"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
8330"
8331" Marked files suitable for use with 2match are in:
8332"    s:netrwmarkfilemtch_#   -- used with 2match to display marked files
8333fun! s:NetrwUnMarkFile(islocal)
8334"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
8335  let svpos    = winsaveview()
8336"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8337  let curbufnr = bufnr("%")
8338
8339  " unmark marked file list
8340  " (although I expect s:NetrwUpload() to do it, I'm just making sure)
8341  if exists("s:netrwmarkfilelist")
8342"   "   call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
8343   unlet s:netrwmarkfilelist
8344  endif
8345
8346  let ibuf= 1
8347  while ibuf < bufnr("$")
8348   if exists("s:netrwmarkfilelist_".ibuf)
8349    unlet s:netrwmarkfilelist_{ibuf}
8350    unlet s:netrwmarkfilemtch_{ibuf}
8351   endif
8352   let ibuf = ibuf + 1
8353  endwhile
8354  2match none
8355
8356"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8357"call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8358call winrestview(svpos)
8359"  call Dret("s:NetrwUnMarkFile")
8360endfun
8361
8362" ---------------------------------------------------------------------
8363" s:NetrwMenu: generates the menu for gvim and netrw {{{2
8364fun! s:NetrwMenu(domenu)
8365
8366  if !exists("g:NetrwMenuPriority")
8367   let g:NetrwMenuPriority= 80
8368  endif
8369
8370  if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8371"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
8372
8373   if !exists("s:netrw_menu_enabled") && a:domenu
8374"    call Decho("initialize menu",'~'.expand("<slnum>"))
8375    let s:netrw_menu_enabled= 1
8376    exe 'sil! menu '.g:NetrwMenuPriority.'.1      '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
8377    exe 'sil! menu '.g:NetrwMenuPriority.'.5      '.g:NetrwTopLvlMenu.'-Sep1-	:'
8378    exe 'sil! menu '.g:NetrwMenuPriority.'.6      '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
8379    exe 'sil! menu '.g:NetrwMenuPriority.'.7      '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
8380    if g:netrw_dirhistmax > 0
8381     exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
8382     exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
8383     exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
8384     exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
8385    else
8386     exe 'sil! menu '.g:NetrwMenuPriority.'.8     '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History	:echo "(disabled)"'."\<cr>"
8387    endif
8388    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1    '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o	o'
8389    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2    '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v	v'
8390    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3    '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t	t'
8391    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4    '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p	p'
8392    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
8393    exe 'sil! menu '.g:NetrwMenuPriority.'.9.6    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
8394    exe 'sil! menu '.g:NetrwMenuPriority.'.9.7    '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
8395    exe 'sil! menu '.g:NetrwMenuPriority.'.9.8    '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
8396    exe 'sil! menu '.g:NetrwMenuPriority.'.9.9    '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
8397    exe 'sil! menu '.g:NetrwMenuPriority.'.10     '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
8398    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
8399    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
8400    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
8401    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
8402    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
8403    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t	t'
8404    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
8405    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1   '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
8406    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
8407    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
8408    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
8409    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
8410    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
8411    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
8412    exe 'sil! menu '.g:NetrwMenuPriority.'.13     '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
8413    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
8414    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
8415    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3   '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
8416    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4   '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
8417    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5   '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
8418    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6   '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
8419    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7   '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
8420    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8   '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
8421    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9   '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
8422    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10  '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
8423    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11  '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
8424    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12  '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
8425    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13  '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
8426    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14  '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
8427    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15  '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
8428    exe 'sil! menu '.g:NetrwMenuPriority.'.15     '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
8429    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i	:let w:netrw_liststyle=0<cr><c-L>'
8430    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i	:let w:netrw_liststyle=1<cr><c-L>'
8431    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i	:let w:netrw_liststyle=2<cr><c-L>'
8432    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i	:let w:netrw_liststyle=3<cr><c-L>'
8433    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>'
8434    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>'
8435    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>'
8436    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3   '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
8437    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>'
8438    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>'
8439    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>'
8440    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>'
8441    exe 'sil! menu '.g:NetrwMenuPriority.'.17     '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
8442    exe 'sil! menu '.g:NetrwMenuPriority.'.18     '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
8443    let s:netrw_menucnt= 28
8444    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
8445    call s:NetrwTgtMenu()      " let bookmarks and history be easy targets
8446
8447   elseif !a:domenu
8448    let s:netrwcnt = 0
8449    let curwin     = winnr()
8450    windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8451    exe curwin."wincmd w"
8452
8453    if s:netrwcnt <= 1
8454"     call Decho("clear menus",'~'.expand("<slnum>"))
8455     exe 'sil! unmenu '.g:NetrwTopLvlMenu
8456"     call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8457     sil! unlet s:netrw_menu_enabled
8458    endif
8459   endif
8460"   call Dret("NetrwMenu")
8461   return
8462  endif
8463
8464endfun
8465
8466" ---------------------------------------------------------------------
8467" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8468"                Used by the O maps (as <SID>NetrwObtain())
8469fun! s:NetrwObtain(islocal)
8470"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8471
8472  let ykeep= @@
8473  if exists("s:netrwmarkfilelist_{bufnr('%')}")
8474   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8475   call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8476   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
8477  else
8478   call netrw#Obtain(a:islocal,s:NetrwGetWord())
8479  endif
8480  let @@= ykeep
8481
8482"  call Dret("NetrwObtain")
8483endfun
8484
8485" ---------------------------------------------------------------------
8486" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
8487"   If there's only one window, then the window will first be split.
8488"   Returns:
8489"     choice = 0 : didn't have to choose
8490"     choice = 1 : saved modified file in window first
8491"     choice = 2 : didn't save modified file, opened window
8492"     choice = 3 : cancel open
8493fun! s:NetrwPrevWinOpen(islocal)
8494"  call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")")
8495
8496  let ykeep= @@
8497  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8498  let curdir = b:netrw_curdir
8499
8500  " get last window number and the word currently under the cursor
8501  let origwin   = winnr()
8502  let lastwinnr = winnr("$")
8503  let curword   = s:NetrwGetWord()
8504  let choice    = 0
8505  let s:treedir = s:NetrwTreeDir(a:islocal)
8506  let curdir    = s:treedir
8507"  call Decho("winnr($)#".lastwinnr." curword<".curword.">",'~'.expand("<slnum>"))
8508
8509  let didsplit = 0
8510  if lastwinnr == 1
8511   " if only one window, open a new one first
8512"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("<slnum>"))
8513   " g:netrw_preview=0: preview window shown in a horizontally split window
8514   " g:netrw_preview=1: preview window shown in a vertically   split window
8515   if g:netrw_preview
8516    " vertically split preview window
8517    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8518"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("<slnum>"))
8519    exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8520   else
8521    " horizontally split preview window
8522    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8523"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8524    exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8525   endif
8526   let didsplit = 1
8527"   call Decho("did split",'~'.expand("<slnum>"))
8528
8529  else
8530   NetrwKeepj call s:SaveBufVars()
8531   let eikeep= &ei
8532   setl ei=all
8533   wincmd p
8534"   call Decho("wincmd p  (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
8535
8536   " prevwinnr: the window number of the "prev" window
8537   " prevbufnr: the buffer number of the buffer in the "prev" window
8538   " bnrcnt   : the qty of windows open on the "prev" buffer
8539   let prevwinnr   = winnr()
8540   let prevbufnr   = bufnr("%")
8541   let prevbufname = bufname("%")
8542   let prevmod     = &mod
8543   let bnrcnt      = 0
8544   NetrwKeepj call s:RestoreBufVars()
8545"   call Decho("after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr,'~'.expand("<slnum>"))
8546
8547   " if the previous window's buffer has been changed (ie. its modified flag is set),
8548   " and it doesn't appear in any other extant window, then ask the
8549   " user if s/he wants to abandon modifications therein.
8550   if prevmod
8551"    call Decho("detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr(),'~'.expand("<slnum>"))
8552    windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8553"    call Decho("prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr,'~'.expand("<slnum>"))
8554    exe prevwinnr."wincmd w"
8555
8556    if bnrcnt == 1 && &hidden == 0
8557     " only one copy of the modified buffer in a window, and
8558     " hidden not set, so overwriting will lose the modified file.  Ask first...
8559     let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8560"     call Decho("prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("<slnum>"))
8561     let &ei= eikeep
8562
8563     if choice == 1
8564      " Yes -- write file & then browse
8565      let v:errmsg= ""
8566      sil w
8567      if v:errmsg != ""
8568       call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8569       exe origwin."wincmd w"
8570       let &ei = eikeep
8571       let @@  = ykeep
8572"       call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">")
8573       return choice
8574      endif
8575
8576     elseif choice == 2
8577      " No -- don't worry about changed file, just browse anyway
8578"      call Decho("don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")",'~'.expand("<slnum>"))
8579      echomsg "**note** changes to ".prevbufname." abandoned"
8580
8581     else
8582      " Cancel -- don't do this
8583"      call Decho("cancel, don't browse, switch to win#".origwin,'~'.expand("<slnum>"))
8584      exe origwin."wincmd w"
8585      let &ei= eikeep
8586      let @@ = ykeep
8587"      call Dret("s:NetrwPrevWinOpen ".choice." : cancelled")
8588      return choice
8589     endif
8590    endif
8591   endif
8592   let &ei= eikeep
8593  endif
8594
8595  " restore b:netrw_curdir (window split/enew may have lost it)
8596  let b:netrw_curdir= curdir
8597  if a:islocal < 2
8598   if a:islocal
8599    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
8600   else
8601    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
8602   endif
8603  endif
8604  let @@= ykeep
8605"  call Dret("s:NetrwPrevWinOpen ".choice)
8606  return choice
8607endfun
8608
8609" ---------------------------------------------------------------------
8610" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8611"                Always assumed to be local -> remote
8612"                call s:NetrwUpload(filename, target)
8613"                call s:NetrwUpload(filename, target, fromdirectory)
8614fun! s:NetrwUpload(fname,tgt,...)
8615"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
8616
8617  if a:tgt =~ '^\a\{3,}://'
8618   let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
8619  else
8620   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
8621  endif
8622"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
8623
8624  if a:0 > 0
8625   let fromdir= a:1
8626  else
8627   let fromdir= getcwd()
8628  endif
8629"  call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
8630
8631  if type(a:fname) == 1
8632   " handle uploading a single file using NetWrite
8633"   call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8634   1split
8635"   call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8636   exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8637"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8638   if a:tgt =~ '/$'
8639    let wfname= substitute(a:fname,'^.*/','','')
8640"    call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8641    exe "w! ".fnameescape(a:tgt.wfname)
8642   else
8643"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8644    exe "w ".fnameescape(a:tgt)
8645"    call Decho("done writing local->remote",'~'.expand("<slnum>"))
8646   endif
8647   q!
8648
8649  elseif type(a:fname) == 3
8650   " handle uploading a list of files via scp
8651"   call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8652   let curdir= getcwd()
8653   if a:tgt =~ '^scp:'
8654    if s:NetrwLcd(fromdir)
8655"     call Dret("s:NetrwUpload : lcd failure")
8656     return
8657    endif
8658    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8659    let args    = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8660    if exists("g:netrw_port") && g:netrw_port != ""
8661     let useport= " ".g:netrw_scpport." ".g:netrw_port
8662    else
8663     let useport= ""
8664    endif
8665    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8666    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8667    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8668    if s:NetrwLcd(curdir)
8669"     call Dret("s:NetrwUpload : lcd failure")
8670     return
8671    endif
8672
8673   elseif a:tgt =~ '^ftp:'
8674    call s:NetrwMethod(a:tgt)
8675
8676    if b:netrw_method == 2
8677     " handle uploading a list of files via ftp+.netrc
8678     let netrw_fname = b:netrw_fname
8679     sil NetrwKeepj new
8680"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8681
8682     NetrwKeepj put =g:netrw_ftpmode
8683"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8684
8685     if exists("g:netrw_ftpextracmd")
8686      NetrwKeepj put =g:netrw_ftpextracmd
8687"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8688     endif
8689
8690     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8691"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8692
8693     if tgtdir == ""
8694      let tgtdir= '/'
8695     endif
8696     NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8697"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8698
8699     for fname in a:fname
8700      NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8701"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8702     endfor
8703
8704     if exists("g:netrw_port") && g:netrw_port != ""
8705      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8706     else
8707"      call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8708      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8709     endif
8710     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8711     sil NetrwKeepj g/Local directory now/d
8712     call histdel("/",-1)
8713     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8714      call netrw#ErrorMsg(s:ERROR,getline(1),14)
8715     else
8716      bw!|q
8717     endif
8718
8719    elseif b:netrw_method == 3
8720     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8721     let netrw_fname= b:netrw_fname
8722     NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8723     let tmpbufnr= bufnr("%")
8724     setl ff=unix
8725
8726     if exists("g:netrw_port") && g:netrw_port != ""
8727      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8728"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8729     else
8730      NetrwKeepj put ='open '.g:netrw_machine
8731"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8732     endif
8733
8734     if exists("g:netrw_uid") && g:netrw_uid != ""
8735      if exists("g:netrw_ftp") && g:netrw_ftp == 1
8736       NetrwKeepj put =g:netrw_uid
8737"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8738       if exists("s:netrw_passwd")
8739        NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8740       endif
8741"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8742      elseif exists("s:netrw_passwd")
8743       NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8744"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8745      endif
8746     endif
8747
8748     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8749"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8750
8751     if exists("b:netrw_fname") && b:netrw_fname != ""
8752      NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8753"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8754     endif
8755
8756     if exists("g:netrw_ftpextracmd")
8757      NetrwKeepj put =g:netrw_ftpextracmd
8758"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8759     endif
8760
8761     for fname in a:fname
8762      NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8763"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8764     endfor
8765
8766     " perform ftp:
8767     " -i       : turns off interactive prompting from ftp
8768     " -n  unix : DON'T use <.netrc>, even though it exists
8769     " -n  win32: quit being obnoxious about password
8770     NetrwKeepj norm! 1G"_dd
8771     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8772     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8773     sil NetrwKeepj g/Local directory now/d
8774     call histdel("/",-1)
8775     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8776      let debugkeep= &debug
8777      setl debug=msg
8778      call netrw#ErrorMsg(s:ERROR,getline(1),15)
8779      let &debug = debugkeep
8780      let mod    = 1
8781     else
8782      bw!|q
8783     endif
8784    elseif !exists("b:netrw_method") || b:netrw_method < 0
8785"     call Dret("s:#NetrwUpload : unsupported method")
8786     return
8787    endif
8788   else
8789    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
8790   endif
8791  endif
8792
8793"  call Dret("s:NetrwUpload")
8794endfun
8795
8796" ---------------------------------------------------------------------
8797" s:NetrwPreview: supports netrw's "p" map {{{2
8798fun! s:NetrwPreview(path) range
8799"  call Dfunc("NetrwPreview(path<".a:path.">)")
8800"  call Decho("g:netrw_alto   =".(exists("g:netrw_alto")?    g:netrw_alto    : 'n/a'),'~'.expand("<slnum>"))
8801"  call Decho("g:netrw_preview=".(exists("g:netrw_preview")? g:netrw_preview : 'n/a'),'~'.expand("<slnum>"))
8802  let ykeep= @@
8803  NetrwKeepj call s:NetrwOptionsSave("s:")
8804  if a:path !~ '^\*\{1,2}/' && a:path !~ '^\a\{3,}://'
8805   NetrwKeepj call s:NetrwOptionsSafe(1)
8806  else
8807   NetrwKeepj call s:NetrwOptionsSafe(0)
8808  endif
8809  if has("quickfix")
8810"   call Decho("has quickfix",'~'.expand("<slnum>"))
8811   if !isdirectory(s:NetrwFile(a:path))
8812"    call Decho("good; not previewing a directory",'~'.expand("<slnum>"))
8813    if g:netrw_preview
8814     " vertical split
8815     let pvhkeep = &pvh
8816     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8817     let &pvh    = winwidth(0) - winsz
8818"     call Decho("g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily)  g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8819    else
8820     " horizontal split
8821     let pvhkeep = &pvh
8822     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8823     let &pvh    = winheight(0) - winsz
8824"     call Decho("!g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily)  g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8825    endif
8826    " g:netrw_preview   g:netrw_alto
8827    "    1 : vert        1: top       -- preview window is vertically   split off and on the left
8828    "    1 : vert        0: bot       -- preview window is vertically   split off and on the right
8829    "    0 :             1: top       -- preview window is horizontally split off and on the top
8830    "    0 :             0: bot       -- preview window is horizontally split off and on the bottom
8831    "
8832    " Note that the file being previewed is already known to not be a directory, hence we can avoid doing a LocalBrowse() check via
8833    " the BufEnter event set up in netrwPlugin.vim
8834"    call Decho("exe ".(g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path),'~'.expand("<slnum>"))
8835    let eikeep = &ei
8836    set ei=BufEnter
8837    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8838    let &ei= eikeep
8839"    call Decho("winnr($)=".winnr("$"),'~'.expand("<slnum>"))
8840    if exists("pvhkeep")
8841     let &pvh= pvhkeep
8842    endif
8843   elseif !exists("g:netrw_quiet")
8844    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
8845   endif
8846  elseif !exists("g:netrw_quiet")
8847   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
8848  endif
8849  NetrwKeepj call s:NetrwOptionsRestore("s:")
8850  let @@= ykeep
8851"  call Dret("NetrwPreview")
8852endfun
8853
8854" ---------------------------------------------------------------------
8855" s:NetrwRefresh: {{{2
8856fun! s:NetrwRefresh(islocal,dirname)
8857"  call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") g:netrw_hide=".g:netrw_hide." g:netrw_sort_direction=".g:netrw_sort_direction)
8858  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
8859  setl ma noro
8860"  call Decho("setl ma noro",'~'.expand("<slnum>"))
8861"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8862  let ykeep      = @@
8863  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8864   if !exists("w:netrw_treetop")
8865    if exists("b:netrw_curdir")
8866     let w:netrw_treetop= b:netrw_curdir
8867    else
8868     let w:netrw_treetop= getcwd()
8869    endif
8870   endif
8871   NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
8872  endif
8873
8874  " save the cursor position before refresh.
8875  let screenposn = winsaveview()
8876"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8877
8878"  call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8879"  call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
8880  sil! NetrwKeepj %d _
8881  if a:islocal
8882   NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
8883  else
8884   NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
8885  endif
8886
8887  " restore position
8888"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8889  NetrwKeepj call winrestview(screenposn)
8890
8891  " restore file marks
8892  if has("syntax") && exists("g:syntax_on") && g:syntax_on
8893   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8894" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8895    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8896   else
8897" "   call Decho("2match none  (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8898    2match none
8899   endif
8900 endif
8901
8902"  restore
8903  let @@= ykeep
8904"  call Dret("s:NetrwRefresh")
8905endfun
8906
8907" ---------------------------------------------------------------------
8908" s:NetrwRefreshDir: refreshes a directory by name {{{2
8909"                    Called by NetrwMarkFileCopy()
8910"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
8911fun! s:NetrwRefreshDir(islocal,dirname)
8912"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) g:netrw_fastbrowse=".g:netrw_fastbrowse)
8913  if g:netrw_fastbrowse == 0
8914   " slowest mode (keep buffers refreshed, local or remote)
8915"   call Decho("slowest mode: keep buffers refreshed, local or remote",'~'.expand("<slnum>"))
8916   let tgtwin= bufwinnr(a:dirname)
8917"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin,'~'.expand("<slnum>"))
8918
8919   if tgtwin > 0
8920    " tgtwin is being displayed, so refresh it
8921    let curwin= winnr()
8922"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")",'~'.expand("<slnum>"))
8923    exe tgtwin."wincmd w"
8924    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8925    exe curwin."wincmd w"
8926
8927   elseif bufnr(a:dirname) > 0
8928    let bn= bufnr(a:dirname)
8929"    call Decho("bd bufnr(".a:dirname.")=".bn,'~'.expand("<slnum>"))
8930    exe "sil keepj bd ".bn
8931   endif
8932
8933  elseif g:netrw_fastbrowse <= 1
8934"   call Decho("medium-speed mode: refresh local buffers only",'~'.expand("<slnum>"))
8935   NetrwKeepj call s:LocalBrowseRefresh()
8936  endif
8937"  call Dret("s:NetrwRefreshDir")
8938endfun
8939
8940" ---------------------------------------------------------------------
8941" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8942" window number to do its editing in.
8943" Supports   [count]C  where the count, if present, is used to specify
8944" a window to use for editing via the <cr> mapping.
8945fun! s:NetrwSetChgwin(...)
8946"  call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
8947  if a:0 > 0
8948"   call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8949   if a:1 == ""    " :NetrwC win#
8950    let g:netrw_chgwin= winnr()
8951   else              " :NetrwC
8952    let g:netrw_chgwin= a:1
8953   endif
8954  elseif v:count > 0 " [count]C
8955   let g:netrw_chgwin= v:count
8956  else               " C
8957   let g:netrw_chgwin= winnr()
8958  endif
8959  echo "editing window now set to window#".g:netrw_chgwin
8960"  call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
8961endfun
8962
8963" ---------------------------------------------------------------------
8964" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8965"          What this function does is to compute a priority for the patterns
8966"          in the g:netrw_sort_sequence.  It applies a substitute to any
8967"          "files" that satisfy each pattern, putting the priority / in
8968"          front.  An "*" pattern handles the default priority.
8969fun! s:NetrwSetSort()
8970"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
8971  let ykeep= @@
8972  if w:netrw_liststyle == s:LONGLIST
8973   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
8974  else
8975   let seqlist  = g:netrw_sort_sequence
8976  endif
8977  " sanity check -- insure that * appears somewhere
8978  if seqlist == ""
8979   let seqlist= '*'
8980  elseif seqlist !~ '\*'
8981   let seqlist= seqlist.',*'
8982  endif
8983  let priority = 1
8984  while seqlist != ""
8985   if seqlist =~ ','
8986    let seq     = substitute(seqlist,',.*$','','e')
8987    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
8988   else
8989    let seq     = seqlist
8990    let seqlist = ""
8991   endif
8992   if priority < 10
8993    let spriority= "00".priority.g:netrw_sepchr
8994   elseif priority < 100
8995    let spriority= "0".priority.g:netrw_sepchr
8996   else
8997    let spriority= priority.g:netrw_sepchr
8998   endif
8999"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
9000
9001   " sanity check
9002   if w:netrw_bannercnt > line("$")
9003    " apparently no files were left after a Hiding pattern was used
9004"    call Dret("SetSort : no files left after hiding")
9005    return
9006   endif
9007   if seq == '*'
9008    let starpriority= spriority
9009   else
9010    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
9011    call histdel("/",-1)
9012    " sometimes multiple sorting patterns will match the same file or directory.
9013    " The following substitute is intended to remove the excess matches.
9014    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
9015    NetrwKeepj call histdel("/",-1)
9016   endif
9017   let priority = priority + 1
9018  endwhile
9019  if exists("starpriority")
9020   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
9021   NetrwKeepj call histdel("/",-1)
9022  endif
9023
9024  " Following line associated with priority -- items that satisfy a priority
9025  " pattern get prefixed by ###/ which permits easy sorting by priority.
9026  " Sometimes files can satisfy multiple priority patterns -- only the latest
9027  " priority pattern needs to be retained.  So, at this point, these excess
9028  " priority prefixes need to be removed, but not directories that happen to
9029  " be just digits themselves.
9030  exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
9031  NetrwKeepj call histdel("/",-1)
9032  let @@= ykeep
9033
9034"  call Dret("SetSort")
9035endfun
9036
9037" ---------------------------------------------------------------------
9038" s:NetrwSetTgt: sets the target to the specified choice index {{{2
9039"    Implements [count]Tb  (bookhist<b>)
9040"               [count]Th  (bookhist<h>)
9041"               See :help netrw-qb for how to make the choice.
9042fun! s:NetrwSetTgt(islocal,bookhist,choice)
9043"  call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
9044
9045  if     a:bookhist == 'b'
9046   " supports choosing a bookmark as a target using a qb-generated list
9047   let choice= a:choice - 1
9048   if exists("g:netrw_bookmarklist[".choice."]")
9049    call netrw#MakeTgt(g:netrw_bookmarklist[choice])
9050   else
9051    echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
9052   endif
9053
9054  elseif a:bookhist == 'h'
9055   " supports choosing a history stack entry as a target using a qb-generated list
9056   let choice= (a:choice % g:netrw_dirhistmax) + 1
9057   if exists("g:netrw_dirhist_".choice)
9058    let histentry = g:netrw_dirhist_{choice}
9059    call netrw#MakeTgt(histentry)
9060   else
9061    echomsg "Sorry, history#".a:choice." not available!"
9062   endif
9063  endif
9064
9065  " refresh the display
9066  if !exists("b:netrw_curdir")
9067   let b:netrw_curdir= getcwd()
9068  endif
9069  call s:NetrwRefresh(a:islocal,b:netrw_curdir)
9070
9071"  call Dret("s:NetrwSetTgt")
9072endfun
9073
9074" =====================================================================
9075" s:NetrwSortStyle: change sorting style (name - time - size - exten) and refresh display {{{2
9076fun! s:NetrwSortStyle(islocal)
9077"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
9078  NetrwKeepj call s:NetrwSaveWordPosn()
9079  let svpos= winsaveview()
9080"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9081
9082  let g:netrw_sort_by= (g:netrw_sort_by =~# '^n')? 'time' : (g:netrw_sort_by =~# '^t')? 'size' : (g:netrw_sort_by =~# '^siz')? 'exten' : 'name'
9083  NetrwKeepj norm! 0
9084  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
9085"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9086  NetrwKeepj call winrestview(svpos)
9087
9088"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
9089endfun
9090
9091" ---------------------------------------------------------------------
9092" s:NetrwSplit: mode {{{2
9093"           =0 : net   and o
9094"           =1 : net   and t
9095"           =2 : net   and v
9096"           =3 : local and o
9097"           =4 : local and t
9098"           =5 : local and v
9099fun! s:NetrwSplit(mode)
9100"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
9101
9102  let ykeep= @@
9103  call s:SaveWinVars()
9104
9105  if a:mode == 0
9106   " remote and o
9107   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
9108   if winsz == 0|let winsz= ""|endif
9109"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
9110   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
9111   let s:didsplit= 1
9112   NetrwKeepj call s:RestoreWinVars()
9113   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
9114   unlet s:didsplit
9115
9116  elseif a:mode == 1
9117   " remote and t
9118   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
9119"   call Decho("tabnew",'~'.expand("<slnum>"))
9120   tabnew
9121   let s:didsplit= 1
9122   NetrwKeepj call s:RestoreWinVars()
9123   NetrwKeepj call s:NetrwBrowse(0,newdir)
9124   unlet s:didsplit
9125
9126  elseif a:mode == 2
9127   " remote and v
9128   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
9129   if winsz == 0|let winsz= ""|endif
9130"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
9131   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
9132   let s:didsplit= 1
9133   NetrwKeepj call s:RestoreWinVars()
9134   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
9135   unlet s:didsplit
9136
9137  elseif a:mode == 3
9138   " local and o
9139   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
9140   if winsz == 0|let winsz= ""|endif
9141"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
9142   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
9143   let s:didsplit= 1
9144   NetrwKeepj call s:RestoreWinVars()
9145   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
9146   unlet s:didsplit
9147
9148  elseif a:mode == 4
9149   " local and t
9150   let cursorword  = s:NetrwGetWord()
9151   let eikeep      = &ei
9152   let netrw_winnr = winnr()
9153   let netrw_line  = line(".")
9154   let netrw_col   = virtcol(".")
9155   NetrwKeepj norm! H0
9156   let netrw_hline = line(".")
9157   setl ei=all
9158   exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
9159   exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
9160   let &ei          = eikeep
9161   let netrw_curdir = s:NetrwTreeDir(0)
9162"   call Decho("tabnew",'~'.expand("<slnum>"))
9163   tabnew
9164   let b:netrw_curdir = netrw_curdir
9165   let s:didsplit     = 1
9166   NetrwKeepj call s:RestoreWinVars()
9167   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
9168   if &ft == "netrw"
9169    setl ei=all
9170    exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
9171    exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
9172    let &ei= eikeep
9173   endif
9174   unlet s:didsplit
9175
9176  elseif a:mode == 5
9177   " local and v
9178   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
9179   if winsz == 0|let winsz= ""|endif
9180"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
9181   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
9182   let s:didsplit= 1
9183   NetrwKeepj call s:RestoreWinVars()
9184   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
9185   unlet s:didsplit
9186
9187  else
9188   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
9189  endif
9190
9191  let @@= ykeep
9192"  call Dret("s:NetrwSplit")
9193endfun
9194
9195" ---------------------------------------------------------------------
9196" s:NetrwTgtMenu: {{{2
9197fun! s:NetrwTgtMenu()
9198  if !exists("s:netrw_menucnt")
9199   return
9200  endif
9201"  call Dfunc("s:NetrwTgtMenu()")
9202
9203  " the following test assures that gvim is running, has menus available, and has menus enabled.
9204  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
9205   if exists("g:NetrwTopLvlMenu")
9206"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
9207    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
9208   endif
9209   if !exists("s:netrw_initbookhist")
9210    call s:NetrwBookHistRead()
9211   endif
9212
9213   " try to cull duplicate entries
9214   let tgtdict={}
9215
9216   " target bookmarked places
9217   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
9218"    call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
9219    let cnt= 1
9220    for bmd in g:netrw_bookmarklist
9221     if has_key(tgtdict,bmd)
9222      let cnt= cnt + 1
9223      continue
9224     endif
9225     let tgtdict[bmd]= cnt
9226     let ebmd= escape(bmd,g:netrw_menu_escape)
9227     " show bookmarks for goto menu
9228"     call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
9229     exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd."	:call netrw#MakeTgt('".bmd."')\<cr>"
9230     let cnt= cnt + 1
9231    endfor
9232   endif
9233
9234   " target directory browsing history
9235   if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
9236"    call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
9237    let histcnt = 1
9238    while histcnt <= g:netrw_dirhistmax
9239     let priority = g:netrw_dirhistcnt + histcnt
9240     if exists("g:netrw_dirhist_{histcnt}")
9241      let histentry  = g:netrw_dirhist_{histcnt}
9242      if has_key(tgtdict,histentry)
9243       let histcnt = histcnt + 1
9244       continue
9245      endif
9246      let tgtdict[histentry] = histcnt
9247      let ehistentry         = escape(histentry,g:netrw_menu_escape)
9248"      call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
9249      exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry."	:call netrw#MakeTgt('".histentry."')\<cr>"
9250     endif
9251     let histcnt = histcnt + 1
9252    endwhile
9253   endif
9254  endif
9255"  call Dret("s:NetrwTgtMenu")
9256endfun
9257
9258" ---------------------------------------------------------------------
9259" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
9260" (full path directory with trailing slash returned)
9261fun! s:NetrwTreeDir(islocal)
9262"  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)
9263"  call Decho("Determine tree directory given current cursor position")
9264"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
9265"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9266"  call Decho("w:netrw_treetop  =".(exists("w:netrw_treetop")?   w:netrw_treetop   : 'n/a'),'~'.expand("<slnum>"))
9267
9268  if exists("s:treedir")
9269   " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
9270   let treedir= s:treedir
9271   unlet s:treedir
9272"   call Dret("s:NetrwTreeDir ".treedir)
9273   return treedir
9274  endif
9275
9276  if !exists("b:netrw_curdir") || b:netrw_curdir == ""
9277   let b:netrw_curdir= getcwd()
9278  endif
9279  let treedir = b:netrw_curdir
9280"  call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>"))
9281
9282  let s:treecurpos= winsaveview()
9283"  call Decho("saving posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9284
9285  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9286"   call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>"))
9287"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9288
9289   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
9290   let curline= substitute(getline('.'),"\t -->.*$",'','')
9291   if curline =~ '/$'
9292"    call Decho("extract tree subdirectory from current line",'~'.expand("<slnum>"))
9293    let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9294"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9295   elseif curline =~ '@$'
9296"    call Decho("handle symbolic link from current line",'~'.expand("<slnum>"))
9297    let treedir= resolve(substitute(substitute(getline('.'),'@.*$','','e'),'^|*\s*','','e'))
9298"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9299   else
9300"    call Decho("do not extract tree subdirectory from current line and set treedir to empty",'~'.expand("<slnum>"))
9301    let treedir= ""
9302   endif
9303
9304   " detect user attempting to close treeroot
9305"   call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>"))
9306"   call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9307"   call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~# '^'.s:treedepthstring)? '=~#' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>"))
9308   if curline !~ '^'.s:treedepthstring && getline('.') != '..'
9309"    call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>"))
9310    " now force a refresh
9311"    call Decho(".force refresh: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9312    sil! NetrwKeepj %d _
9313"    call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9314    return b:netrw_curdir
9315"   else " Decho
9316"    call Decho(".user not attempting to close treeroot",'~'.expand("<slnum>"))
9317   endif
9318
9319"   call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>"))
9320   let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
9321"   call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(potentialdir),'~'.expand("<slnum>"))
9322
9323   " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
9324"   if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
9325"    let newdir          = w:netrw_treetop.'/'.potentialdir
9326" "   call Decho("apply NetrwTreePath to newdir<".newdir.">",'~'.expand("<slnum>"))
9327"    let treedir         = s:NetrwTreePath(newdir)
9328"    let w:netrw_treetop = newdir
9329" "   call Decho("newdir <".newdir.">",'~'.expand("<slnum>"))
9330"   else
9331"    call Decho("apply NetrwTreePath to treetop<".w:netrw_treetop.">",'~'.expand("<slnum>"))
9332    let treedir = s:NetrwTreePath(w:netrw_treetop)
9333"   endif
9334  endif
9335
9336  " sanity maintenance: keep those //s away...
9337  let treedir= substitute(treedir,'//$','/','')
9338"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9339
9340"  call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9341  return treedir
9342endfun
9343
9344" ---------------------------------------------------------------------
9345" s:NetrwTreeDisplay: recursive tree display {{{2
9346fun! s:NetrwTreeDisplay(dir,depth)
9347"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
9348
9349  " insure that there are no folds
9350  setl nofen
9351
9352  " install ../ and shortdir
9353  if a:depth == ""
9354   call setline(line("$")+1,'../')
9355"   call Decho("setline#".line("$")." ../ (depth is zero)",'~'.expand("<slnum>"))
9356  endif
9357  if a:dir =~ '^\a\{3,}://'
9358   if a:dir == w:netrw_treetop
9359    let shortdir= a:dir
9360   else
9361    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
9362   endif
9363   call setline(line("$")+1,a:depth.shortdir)
9364  else
9365   let shortdir= substitute(a:dir,'^.*/','','e')
9366   call setline(line("$")+1,a:depth.shortdir.'/')
9367  endif
9368"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">",'~'.expand("<slnum>"))
9369  " append a / to dir if its missing one
9370  let dir= a:dir
9371
9372  " display subtrees (if any)
9373  let depth= s:treedepthstring.a:depth
9374"  call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>"))
9375
9376  " implement g:netrw_hide for tree listings (uses g:netrw_list_hide)
9377  if     g:netrw_hide == 1
9378   " hide given patterns
9379   let listhide= split(g:netrw_list_hide,',')
9380"   call Decho("listhide=".string(listhide))
9381   for pat in listhide
9382    call filter(w:netrw_treedict[dir],'v:val !~ "'.escape(pat,'\\').'"')
9383   endfor
9384
9385  elseif g:netrw_hide == 2
9386   " show given patterns (only)
9387   let listhide= split(g:netrw_list_hide,',')
9388"   call Decho("listhide=".string(listhide))
9389   let entries=[]
9390   for entry in w:netrw_treedict[dir]
9391    for pat in listhide
9392     if entry =~ pat
9393      call add(entries,entry)
9394      break
9395     endif
9396    endfor
9397   endfor
9398   let w:netrw_treedict[dir]= entries
9399  endif
9400  if depth != ""
9401   " always remove "." and ".." entries when there's depth
9402   call filter(w:netrw_treedict[dir],'v:val !~ "\\.\\.$"')
9403   call filter(w:netrw_treedict[dir],'v:val !~ "\\.$"')
9404  endif
9405
9406"  call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>"))
9407  for entry in w:netrw_treedict[dir]
9408   if dir =~ '/$'
9409    let direntry= substitute(dir.entry,'[@/]$','','e')
9410   else
9411    let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
9412   endif
9413"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9414   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9415"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9416    NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
9417   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9418"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9419    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9420   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9421"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9422    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9423   else
9424"    call Decho("<".entry."> is not a key in treedict (no subtree)",'~'.expand("<slnum>"))
9425    sil! NetrwKeepj call setline(line("$")+1,depth.entry)
9426   endif
9427  endfor
9428"  call Decho("displaying: ".string(getline(w:netrw_bannercnt,'$')))
9429
9430"  call Dret("NetrwTreeDisplay")
9431endfun
9432
9433" ---------------------------------------------------------------------
9434" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
9435fun! s:NetrwRefreshTreeDict(dir)
9436"  call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)")
9437  if !exists("w:netrw_treedict")
9438"   call Dret("s:NetrwRefreshTreeDict : w:netrw_treedict doesn't exist")
9439   return
9440  endif
9441
9442  for entry in w:netrw_treedict[a:dir]
9443   let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
9444"   call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9445
9446   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9447"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9448    NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
9449    let liststar                   = s:NetrwGlob(direntry,'*',1)
9450    let listdotstar                = s:NetrwGlob(direntry,'.*',1)
9451    let w:netrw_treedict[direntry] = liststar + listdotstar
9452"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9453
9454   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9455"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9456    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9457    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9458    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9459    let w:netrw_treedict[direntry]= liststar + listdotstar
9460"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9461
9462   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9463"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9464    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9465    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9466    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9467"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9468
9469   else
9470"    call Decho('not updating w:netrw_treedict['.string(direntry).'] with entry<'.string(entry).'> (no subtree)','~'.expand("<slnum>"))
9471   endif
9472  endfor
9473"  call Dret("s:NetrwRefreshTreeDict")
9474endfun
9475
9476" ---------------------------------------------------------------------
9477" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
9478"                     Called by s:PerformListing()
9479fun! s:NetrwTreeListing(dirname)
9480  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9481"   call Dfunc("NetrwTreeListing() bufname<".expand("%").">")
9482"   call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
9483"   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>"))
9484"   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>"))
9485
9486   " update the treetop
9487"   call Decho("update the treetop",'~'.expand("<slnum>"))
9488   if !exists("w:netrw_treetop")
9489    let w:netrw_treetop= a:dirname
9490"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>"))
9491   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
9492    let w:netrw_treetop= a:dirname
9493"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
9494   endif
9495
9496   if !exists("w:netrw_treedict")
9497    " insure that we have a treedict, albeit empty
9498"    call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
9499    let w:netrw_treedict= {}
9500   endif
9501
9502   " update the dictionary for the current directory
9503"   call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>"))
9504"   call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9505   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
9506   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
9507"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
9508   exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9509
9510   " if past banner, record word
9511   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
9512    let fname= expand("<cword>")
9513   else
9514    let fname= ""
9515   endif
9516"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9517"   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>"))
9518
9519   " display from treetop on down
9520"   call Decho("(s:NetrwTreeListing) w:netrw_treetop<".w:netrw_treetop.">")
9521   NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
9522"   call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
9523
9524   " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
9525   while getline(1) =~ '^\s*$' && byte2line(1) > 0
9526"    call Decho("deleting blank line",'~'.expand("<slnum>"))
9527    1d
9528   endwhile
9529
9530   exe "setl ".g:netrw_bufsettings
9531
9532"   call Dret("NetrwTreeListing : bufname<".expand("%").">")
9533   return
9534  endif
9535endfun
9536
9537" ---------------------------------------------------------------------
9538" s:NetrwTreePath: returns path to current file/directory in tree listing {{{2
9539"                  Normally, treetop is w:netrw_treetop, but a
9540"                  user of the function ( netrw#SetTreetop() )
9541"                  wipes that out prior to calling this function
9542fun! s:NetrwTreePath(treetop)
9543"  call Dfunc("s:NetrwTreePath(treetop<".a:treetop.">) line#".line(".")."<".getline(".").">")
9544  if line(".") < w:netrw_bannercnt + 2
9545   let treedir= a:treetop
9546   if treedir !~ '/$'
9547    let treedir= treedir.'/'
9548   endif
9549"   call Dret("s:NetrwTreePath ".treedir." : line#".line(".")." ≤ ".(w:netrw_bannercnt+2))
9550   return treedir
9551  endif
9552
9553  let svpos = winsaveview()
9554"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9555  let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
9556"  call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
9557  let depth = substitute(depth,'^'.s:treedepthstring,'','')
9558"  call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
9559  let curline= getline('.')
9560"  call Decho("curline<".curline.'>','~'.expand("<slnum>"))
9561  if curline =~ '/$'
9562"   call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9563   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9564"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9565  elseif curline =~ '@\s\+-->'
9566"   call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9567   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9568   let treedir= substitute(treedir,'@\s\+-->.*$','','e')
9569"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9570  else
9571"   call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9572   let treedir= ""
9573  endif
9574  " construct treedir by searching backwards at correct depth
9575"  call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9576"  call Decho("initial      treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
9577  while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
9578   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9579   let treedir= dirname.treedir
9580   let depth  = substitute(depth,'^'.s:treedepthstring,'','')
9581"   call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
9582  endwhile
9583"  call Decho("treedir#1<".treedir.">",'~'.expand("<slnum>"))
9584  if a:treetop =~ '/$'
9585   let treedir= a:treetop.treedir
9586  else
9587   let treedir= a:treetop.'/'.treedir
9588  endif
9589"  call Decho("treedir#2<".treedir.">",'~'.expand("<slnum>"))
9590  let treedir= substitute(treedir,'//$','/','')
9591"  call Decho("treedir#3<".treedir.">",'~'.expand("<slnum>"))
9592"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
9593  call winrestview(svpos)
9594"  call Dret("s:NetrwTreePath <".treedir.">")
9595  return treedir
9596endfun
9597
9598" ---------------------------------------------------------------------
9599" s:NetrwWideListing: {{{2
9600fun! s:NetrwWideListing()
9601
9602  if w:netrw_liststyle == s:WIDELIST
9603"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9604   " look for longest filename (cpf=characters per filename)
9605   " cpf: characters per filename
9606   " fpl: filenames per line
9607   " fpc: filenames per column
9608   setl ma noro
9609   let keepa= @a
9610"   call Decho("setl ma noro",'~'.expand("<slnum>"))
9611   let b:netrw_cpf= 0
9612   if line("$") >= w:netrw_bannercnt
9613    " determine the maximum filename size; use that to set cpf
9614    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
9615    NetrwKeepj call histdel("/",-1)
9616   else
9617    let @a= keepa
9618"    call Dret("NetrwWideListing")
9619    return
9620   endif
9621   " allow for two spaces to separate columns
9622   let b:netrw_cpf= b:netrw_cpf + 2
9623"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
9624
9625   " determine qty files per line (fpl)
9626   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9627   if w:netrw_fpl <= 0
9628    let w:netrw_fpl= 1
9629   endif
9630"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
9631
9632   " make wide display
9633   "   fpc: files per column of wide listing
9634   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9635   NetrwKeepj call histdel("/",-1)
9636   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9637   let newcolstart = w:netrw_bannercnt + fpc
9638   let newcolend   = newcolstart + fpc - 1
9639"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9640   if has("clipboard")
9641"    call Decho("(s:NetrwWideListing) save @* and @+",'~'.expand("<slnum>"))
9642    sil! let keepregstar = @*
9643    sil! let keepregplus = @+
9644   endif
9645   while line("$") >= newcolstart
9646    if newcolend > line("$") | let newcolend= line("$") | endif
9647    let newcolqty= newcolend - newcolstart
9648    exe newcolstart
9649    " COMBAK: both of the visual-mode using lines below are problematic vis-a-vis @*
9650    if newcolqty == 0
9651     exe "sil! NetrwKeepj norm! 0\<c-v>$h\"ax".w:netrw_bannercnt."G$\"ap"
9652    else
9653     exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$h"ax'.w:netrw_bannercnt.'G$"ap'
9654    endif
9655    exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
9656    exe 'sil! NetrwKeepj '.w:netrw_bannercnt
9657   endwhile
9658   if has("clipboard")
9659"    call Decho("(s:NetrwWideListing) restore @* and @+",'~'.expand("<slnum>"))
9660    if @* != keepregstar | sil! let @* = keepregstar | endif
9661    if @+ != keepregplus | sil! let @+ = keepregplus | endif
9662   endif
9663   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9664   NetrwKeepj call histdel("/",-1)
9665   exe 'nno <buffer> <silent> w	:call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9666   exe 'nno <buffer> <silent> b	:call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9667"   call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9668   exe "setl ".g:netrw_bufsettings
9669    let @a= keepa
9670"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9671"   call Dret("NetrwWideListing")
9672   return
9673  else
9674   if hasmapto("w","n")
9675    sil! nunmap <buffer> w
9676   endif
9677   if hasmapto("b","n")
9678    sil! nunmap <buffer> b
9679   endif
9680  endif
9681
9682endfun
9683
9684" ---------------------------------------------------------------------
9685" s:PerformListing: {{{2
9686fun! s:PerformListing(islocal)
9687"  call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9688"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9689"  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)"." ei<".&ei.">",'~'.expand("<slnum>"))
9690  sil! NetrwKeepj %d _
9691"  call DechoBuf(bufnr("%"))
9692
9693  " set up syntax highlighting {{{3
9694"  call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
9695  sil! setl ft=netrw
9696
9697  NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
9698  setl noro ma
9699"  call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
9700
9701"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
9702"   call Decho("Processing your browsing request...",'~'.expand("<slnum>"))
9703"  endif								" Decho
9704
9705"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9706  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
9707   " force a refresh for tree listings
9708"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9709   sil! NetrwKeepj %d _
9710  endif
9711
9712  " save current directory on directory history list
9713  NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
9714
9715  " Set up the banner {{{3
9716  if g:netrw_banner
9717"   call Decho("--set up banner",'~'.expand("<slnum>"))
9718   NetrwKeepj call setline(1,'" ============================================================================')
9719   if exists("g:netrw_pchk")
9720    " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9721    " failure detections.
9722    NetrwKeepj call setline(2,'" Netrw Directory Listing')
9723   else
9724    NetrwKeepj call setline(2,'" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')')
9725   endif
9726   if exists("g:netrw_pchk")
9727    let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9728   else
9729    let curdir= b:netrw_curdir
9730   endif
9731   if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9732    NetrwKeepj call setline(3,'"   '.substitute(curdir,'/','\\','g'))
9733   else
9734    NetrwKeepj call setline(3,'"   '.curdir)
9735   endif
9736   let w:netrw_bannercnt= 3
9737   NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
9738  else
9739"   call Decho("--no banner",'~'.expand("<slnum>"))
9740   NetrwKeepj 1
9741   let w:netrw_bannercnt= 1
9742  endif
9743"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9744"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9745
9746  " construct sortby string: [name|time|size|exten] [reversed]
9747  let sortby= g:netrw_sort_by
9748  if g:netrw_sort_direction =~# "^r"
9749   let sortby= sortby." reversed"
9750  endif
9751
9752  " Sorted by... {{{3
9753  if g:netrw_banner
9754"   call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9755   if g:netrw_sort_by =~# "^n"
9756"   call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9757    " sorted by name (also includes the sorting sequence in the banner)
9758    NetrwKeepj put ='\"   Sorted by      '.sortby
9759    NetrwKeepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
9760    let w:netrw_bannercnt= w:netrw_bannercnt + 2
9761   else
9762"   call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9763    " sorted by time, size, exten
9764    NetrwKeepj put ='\"   Sorted by '.sortby
9765    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9766   endif
9767   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9768"  else " Decho
9769"   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>"))
9770  endif
9771
9772  " show copy/move target, if any {{{3
9773  if g:netrw_banner
9774   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9775"    call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9776    NetrwKeepj put =''
9777    if s:netrwmftgt_islocal
9778     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9779    else
9780     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9781    endif
9782    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9783   else
9784"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
9785   endif
9786   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9787  endif
9788
9789  " Hiding...  -or-  Showing... {{{3
9790  if g:netrw_banner
9791"   call Decho("--handle hiding/showing in banner (g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9792   if g:netrw_list_hide != "" && g:netrw_hide
9793    if g:netrw_hide == 1
9794     NetrwKeepj put ='\"   Hiding:        '.g:netrw_list_hide
9795    else
9796     NetrwKeepj put ='\"   Showing:       '.g:netrw_list_hide
9797    endif
9798    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9799   endif
9800   exe "NetrwKeepj ".w:netrw_bannercnt
9801
9802"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9803   let quickhelp   = g:netrw_quickhelp%len(s:QuickHelp)
9804"   call Decho("quickhelp   =".quickhelp,'~'.expand("<slnum>"))
9805   NetrwKeepj put ='\"   Quick Help: <F1>:help  '.s:QuickHelp[quickhelp]
9806"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9807   NetrwKeepj put ='\" =============================================================================='
9808   let w:netrw_bannercnt= w:netrw_bannercnt + 2
9809"  else " Decho
9810"   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>"))
9811  endif
9812
9813  " bannercnt should index the line just after the banner
9814  if g:netrw_banner
9815   let w:netrw_bannercnt= w:netrw_bannercnt + 1
9816   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9817"   call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9818"  else " Decho
9819"   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>"))
9820  endif
9821
9822  " get list of files
9823"  call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
9824  if a:islocal
9825   NetrwKeepj call s:LocalListing()
9826  else " remote
9827   NetrwKeepj let badresult= s:NetrwRemoteListing()
9828   if badresult
9829"    call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9830"    call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9831    return
9832   endif
9833  endif
9834
9835  " manipulate the directory listing (hide, sort) {{{3
9836  if !exists("w:netrw_bannercnt")
9837   let w:netrw_bannercnt= 0
9838  endif
9839"  call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9840"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9841"  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>"))
9842
9843  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9844"   call Decho("manipulate directory listing (support hide)",'~'.expand("<slnum>"))
9845"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9846   if g:netrw_hide && g:netrw_list_hide != ""
9847    NetrwKeepj call s:NetrwListHide()
9848   endif
9849   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9850"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9851
9852    if g:netrw_sort_by =~# "^n"
9853     " sort by name
9854"     call Decho("sort by name",'~'.expand("<slnum>"))
9855     NetrwKeepj call s:NetrwSetSort()
9856
9857     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9858"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9859      if g:netrw_sort_direction =~# 'n'
9860       " name: sort by name of file
9861       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9862      else
9863       " reverse direction sorting
9864       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9865      endif
9866     endif
9867
9868     " remove priority pattern prefix
9869"     call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9870     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9871     NetrwKeepj call histdel("/",-1)
9872
9873    elseif g:netrw_sort_by =~# "^ext"
9874     " exten: sort by extension
9875     "   The histdel(...,-1) calls remove the last search from the search history
9876"     call Decho("sort by extension",'~'.expand("<slnum>"))
9877     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9878     NetrwKeepj call histdel("/",-1)
9879     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9880     NetrwKeepj call histdel("/",-1)
9881     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9882     NetrwKeepj call histdel("/",-1)
9883     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9884"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9885      if g:netrw_sort_direction =~# 'n'
9886       " normal direction sorting
9887       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9888      else
9889       " reverse direction sorting
9890       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9891      endif
9892     endif
9893     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9894     NetrwKeepj call histdel("/",-1)
9895
9896    elseif a:islocal
9897     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9898"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9899      if g:netrw_sort_direction =~# 'n'
9900"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9901       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9902      else
9903"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9904       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9905      endif
9906"     call Decho("remove leading digits/ (sorting) information from listing",'~'.expand("<slnum>"))
9907     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9908     NetrwKeepj call histdel("/",-1)
9909     endif
9910    endif
9911
9912   elseif g:netrw_sort_direction =~# 'r'
9913"    call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9914    if !g:netrw_banner || w:netrw_bannercnt < line('$')
9915     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9916     call histdel("/",-1)
9917    endif
9918   endif
9919  endif
9920"  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>"))
9921
9922  " convert to wide/tree listing {{{3
9923"  call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9924"  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>"))
9925  NetrwKeepj call s:NetrwWideListing()
9926"  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>"))
9927  NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
9928"  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>"))
9929
9930  " resolve symbolic links if local and (thin or tree)
9931  if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
9932"   call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9933   sil! g/@$/call s:ShowLink()
9934  endif
9935
9936  if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
9937   " place cursor on the top-left corner of the file listing
9938"   call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9939   exe 'sil! '.w:netrw_bannercnt
9940   sil! NetrwKeepj norm! 0
9941"   call Decho("  tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9942  else
9943"   call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9944"   call Decho("  w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9945"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
9946"   call Decho("  g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
9947  endif
9948
9949  " record previous current directory
9950  let w:netrw_prvdir= b:netrw_curdir
9951"  call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
9952
9953  " save certain window-oriented variables into buffer-oriented variables {{{3
9954"  call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9955"  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>"))
9956  NetrwKeepj call s:SetBufWinVars()
9957"  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>"))
9958  NetrwKeepj call s:NetrwOptionsRestore("w:")
9959"  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>"))
9960
9961  " set display to netrw display settings
9962"  call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
9963  exe "setl ".g:netrw_bufsettings
9964"  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>"))
9965  if g:netrw_liststyle == s:LONGLIST
9966"   call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9967   exe "setl ts=".(g:netrw_maxfilenamelen+1)
9968  endif
9969"  call Decho("PerformListing buffer:",'~'.expand("<slnum>"))
9970"  call DechoBuf(bufnr("%"))
9971
9972  if exists("s:treecurpos")
9973"   call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
9974"   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>"))
9975"   call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9976   NetrwKeepj call winrestview(s:treecurpos)
9977   unlet s:treecurpos
9978  endif
9979
9980"  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>"))
9981"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9982"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
9983endfun
9984
9985" ---------------------------------------------------------------------
9986" s:SetupNetrwStatusLine: {{{2
9987fun! s:SetupNetrwStatusLine(statline)
9988"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
9989
9990  if !exists("s:netrw_setup_statline")
9991   let s:netrw_setup_statline= 1
9992"   call Decho("do first-time status line setup",'~'.expand("<slnum>"))
9993
9994   if !exists("s:netrw_users_stl")
9995    let s:netrw_users_stl= &stl
9996   endif
9997   if !exists("s:netrw_users_ls")
9998    let s:netrw_users_ls= &laststatus
9999   endif
10000
10001   " set up User9 highlighting as needed
10002   let keepa= @a
10003   redir @a
10004   try
10005    hi User9
10006   catch /^Vim\%((\a\{3,})\)\=:E411/
10007    if &bg == "dark"
10008     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
10009    else
10010     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
10011    endif
10012   endtry
10013   redir END
10014   let @a= keepa
10015  endif
10016
10017  " set up status line (may use User9 highlighting)
10018  " insure that windows have a statusline
10019  " make sure statusline is displayed
10020  let &stl=a:statline
10021  setl laststatus=2
10022"  call Decho("stl=".&stl,'~'.expand("<slnum>"))
10023  redraw
10024
10025"  call Dret("SetupNetrwStatusLine : stl=".&stl)
10026endfun
10027
10028" =========================================
10029"  Remote Directory Browsing Support:  {{{1
10030" =========================================
10031
10032" ---------------------------------------------------------------------
10033" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
10034"  This function assumes that a long listing will be received.  Size, time,
10035"  and reverse sorts will be requested of the server but not otherwise
10036"  enforced here.
10037fun! s:NetrwRemoteFtpCmd(path,listcmd)
10038"  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 : "???")))
10039"  call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
10040  " sanity check: {{{3
10041  if !exists("w:netrw_method")
10042   if exists("b:netrw_method")
10043    let w:netrw_method= b:netrw_method
10044   else
10045    call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
10046"    call Dret("NetrwRemoteFtpCmd")
10047    return
10048   endif
10049  endif
10050
10051  " WinXX ftp uses unix style input, so set ff to unix	" {{{3
10052  let ffkeep= &ff
10053  setl ma ff=unix noro
10054"  call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
10055
10056  " clear off any older non-banner lines	" {{{3
10057  " note that w:netrw_bannercnt indexes the line after the banner
10058"  call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _  (clear off old non-banner lines)",'~'.expand("<slnum>"))
10059  exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
10060
10061  ".........................................
10062  if w:netrw_method == 2 || w:netrw_method == 5	" {{{3
10063   " ftp + <.netrc>:  Method #2
10064   if a:path != ""
10065    NetrwKeepj put ='cd \"'.a:path.'\"'
10066   endif
10067   if exists("g:netrw_ftpextracmd")
10068    NetrwKeepj put =g:netrw_ftpextracmd
10069"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
10070   endif
10071   NetrwKeepj call setline(line("$")+1,a:listcmd)
10072"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
10073   if exists("g:netrw_port") && g:netrw_port != ""
10074"    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>"))
10075    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)
10076   else
10077"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
10078    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
10079   endif
10080
10081  ".........................................
10082  elseif w:netrw_method == 3	" {{{3
10083   " ftp + machine,id,passwd,filename:  Method #3
10084    setl ff=unix
10085    if exists("g:netrw_port") && g:netrw_port != ""
10086     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
10087    else
10088     NetrwKeepj put ='open '.g:netrw_machine
10089    endif
10090
10091    " handle userid and password
10092    let host= substitute(g:netrw_machine,'\..*$','','')
10093"    call Decho("host<".host.">",'~'.expand("<slnum>"))
10094    if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
10095     call NetUserPass("ftp:".host)
10096    endif
10097    if exists("g:netrw_uid") && g:netrw_uid != ""
10098     if exists("g:netrw_ftp") && g:netrw_ftp == 1
10099      NetrwKeepj put =g:netrw_uid
10100      if exists("s:netrw_passwd") && s:netrw_passwd != ""
10101       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
10102      endif
10103     elseif exists("s:netrw_passwd")
10104      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
10105     endif
10106    endif
10107
10108   if a:path != ""
10109    NetrwKeepj put ='cd \"'.a:path.'\"'
10110   endif
10111   if exists("g:netrw_ftpextracmd")
10112    NetrwKeepj put =g:netrw_ftpextracmd
10113"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
10114   endif
10115   NetrwKeepj call setline(line("$")+1,a:listcmd)
10116
10117   " perform ftp:
10118   " -i       : turns off interactive prompting from ftp
10119   " -n  unix : DON'T use <.netrc>, even though it exists
10120   " -n  win32: quit being obnoxious about password
10121   if exists("w:netrw_bannercnt")
10122"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
10123    call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
10124"   else " Decho
10125"    call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
10126"    g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
10127   endif
10128
10129  ".........................................
10130  elseif w:netrw_method == 9	" {{{3
10131   " sftp username@machine: Method #9
10132   " s:netrw_sftp_cmd
10133   setl ff=unix
10134
10135   " restore settings
10136   let &ff= ffkeep
10137"   call Dret("NetrwRemoteFtpCmd")
10138   return
10139
10140  ".........................................
10141  else	" {{{3
10142   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
10143  endif
10144
10145  " cleanup for Windows " {{{3
10146  if has("win32") || has("win95") || has("win64") || has("win16")
10147   sil! NetrwKeepj %s/\r$//e
10148   NetrwKeepj call histdel("/",-1)
10149  endif
10150  if a:listcmd == "dir"
10151   " infer directory/link based on the file permission string
10152   sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
10153   sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
10154   NetrwKeepj call histdel("/",-1)
10155   NetrwKeepj call histdel("/",-1)
10156   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10157    exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
10158    NetrwKeepj call histdel("/",-1)
10159   endif
10160  endif
10161
10162  " ftp's listing doesn't seem to include ./ or ../ " {{{3
10163  if !search('^\.\/$\|\s\.\/$','wn')
10164   exe 'NetrwKeepj '.w:netrw_bannercnt
10165   NetrwKeepj put ='./'
10166  endif
10167  if !search('^\.\.\/$\|\s\.\.\/$','wn')
10168   exe 'NetrwKeepj '.w:netrw_bannercnt
10169   NetrwKeepj put ='../'
10170  endif
10171
10172  " restore settings " {{{3
10173  let &ff= ffkeep
10174"  call Dret("NetrwRemoteFtpCmd")
10175endfun
10176
10177" ---------------------------------------------------------------------
10178" s:NetrwRemoteListing: {{{2
10179fun! s:NetrwRemoteListing()
10180"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
10181
10182  if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
10183   let w:netrw_bannercnt= s:bannercnt
10184  endif
10185  if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
10186   let w:netrw_bannercnt= s:bannercnt
10187  endif
10188
10189  call s:RemotePathAnalysis(b:netrw_curdir)
10190
10191  " sanity check:
10192  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
10193"   call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
10194   if !executable("ftp")
10195"    call Decho("ftp is not executable",'~'.expand("<slnum>"))
10196    if !exists("g:netrw_quiet")
10197     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
10198    endif
10199    call s:NetrwOptionsRestore("w:")
10200"    call Dret("s:NetrwRemoteListing -1")
10201    return -1
10202   endif
10203
10204  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
10205"   call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
10206   if !exists("g:netrw_quiet")
10207    if g:netrw_list_cmd == ""
10208     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)
10209    else
10210     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
10211    endif
10212   endif
10213
10214   NetrwKeepj call s:NetrwOptionsRestore("w:")
10215"   call Dret("s:NetrwRemoteListing -1")
10216   return -1
10217  endif  " (remote handling sanity check)
10218"  call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
10219
10220  if exists("b:netrw_method")
10221"   call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
10222   let w:netrw_method= b:netrw_method
10223  endif
10224
10225  if s:method == "ftp"
10226   " use ftp to get remote file listing {{{3
10227"   call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
10228   let s:method  = "ftp"
10229   let listcmd = g:netrw_ftp_list_cmd
10230   if g:netrw_sort_by =~# '^t'
10231    let listcmd= g:netrw_ftp_timelist_cmd
10232   elseif g:netrw_sort_by =~# '^s'
10233    let listcmd= g:netrw_ftp_sizelist_cmd
10234   endif
10235"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
10236   call s:NetrwRemoteFtpCmd(s:path,listcmd)
10237"   exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
10238
10239   " report on missing file or directory messages
10240   if search('[Nn]o such file or directory\|Failed to change directory')
10241    let mesg= getline(".")
10242    if exists("w:netrw_bannercnt")
10243     setl ma
10244     exe w:netrw_bannercnt.",$d _"
10245     setl noma
10246    endif
10247    NetrwKeepj call s:NetrwOptionsRestore("w:")
10248    call netrw#ErrorMsg(s:WARNING,mesg,96)
10249"    call Dret("s:NetrwRemoteListing : -1")
10250    return -1
10251   endif
10252
10253   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10254    " shorten the listing
10255"    call Decho("generate short listing",'~'.expand("<slnum>"))
10256    exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
10257
10258    " cleanup
10259    if g:netrw_ftp_browse_reject != ""
10260     exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
10261     NetrwKeepj call histdel("/",-1)
10262    endif
10263    sil! NetrwKeepj %s/\r$//e
10264    NetrwKeepj call histdel("/",-1)
10265
10266    " if there's no ../ listed, then put ../ in
10267    let line1= line(".")
10268    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10269    let line2= search('\.\.\/\%(\s\|$\)','cnW')
10270"    call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2."  w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
10271    if line2 == 0
10272"     call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
10273     sil! NetrwKeepj put='../'
10274    endif
10275    exe "sil! NetrwKeepj ".line1
10276    sil! NetrwKeepj norm! 0
10277
10278"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
10279    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10280"     call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
10281     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
10282     NetrwKeepj call histdel("/",-1)
10283    else " normal ftp cleanup
10284"     call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
10285     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
10286     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
10287     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
10288     NetrwKeepj call histdel("/",-1)
10289     NetrwKeepj call histdel("/",-1)
10290     NetrwKeepj call histdel("/",-1)
10291    endif
10292   endif
10293
10294   else
10295   " use ssh to get remote file listing {{{3
10296"   call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
10297   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
10298"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
10299   if g:netrw_scp_cmd =~ '^pscp'
10300"    call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
10301    exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
10302    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
10303    sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
10304    sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
10305    sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
10306    NetrwKeepj call histdel("/",-1)
10307    NetrwKeepj call histdel("/",-1)
10308    NetrwKeepj call histdel("/",-1)
10309    if g:netrw_liststyle != s:LONGLIST
10310     sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
10311     NetrwKeepj call histdel("/",-1)
10312    endif
10313   else
10314    if s:path == ""
10315"     call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
10316     exe "NetrwKeepj keepalt r! ".listcmd
10317    else
10318"     call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
10319     exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
10320"     call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
10321    endif
10322   endif
10323
10324   " cleanup
10325   if g:netrw_ssh_browse_reject != ""
10326"    call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
10327    exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
10328    NetrwKeepj call histdel("/",-1)
10329   endif
10330  endif
10331
10332  if w:netrw_liststyle == s:LONGLIST
10333   " do a long listing; these substitutions need to be done prior to sorting {{{3
10334"   call Decho("fix long listing:",'~'.expand("<slnum>"))
10335
10336   if s:method == "ftp"
10337    " cleanup
10338    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10339    while getline('.') =~# g:netrw_ftp_browse_reject
10340     sil! NetrwKeepj d
10341    endwhile
10342    " if there's no ../ listed, then put ../ in
10343    let line1= line(".")
10344    sil! NetrwKeepj 1
10345    sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
10346    let line2= line(".")
10347    if line2 == 0
10348     if b:netrw_curdir != '/'
10349      exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
10350     endif
10351    endif
10352    exe "sil! NetrwKeepj ".line1
10353    sil! NetrwKeepj norm! 0
10354   endif
10355
10356   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10357"    call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
10358    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/'
10359   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
10360"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
10361    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
10362    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
10363    exe 'sil NetrwKeepj '.w:netrw_bannercnt
10364    NetrwKeepj call histdel("/",-1)
10365    NetrwKeepj call histdel("/",-1)
10366    NetrwKeepj call histdel("/",-1)
10367   endif
10368  endif
10369
10370"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
10371"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
10372"  endif " Decho
10373
10374"  call Dret("s:NetrwRemoteListing 0")
10375  return 0
10376endfun
10377
10378" ---------------------------------------------------------------------
10379" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
10380fun! s:NetrwRemoteRm(usrhost,path) range
10381"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
10382"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10383  let svpos= winsaveview()
10384"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10385
10386  let all= 0
10387  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10388   " remove all marked files
10389"   call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>"))
10390   for fname in s:netrwmarkfilelist_{bufnr("%")}
10391    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
10392    if ok =~# 'q\%[uit]'
10393     break
10394    elseif ok =~# 'a\%[ll]'
10395     let all= 1
10396    endif
10397   endfor
10398   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10399
10400  else
10401   " remove files specified by range
10402"   call Decho("remove files specified by range",'~'.expand("<slnum>"))
10403
10404   " preparation for removing multiple files/directories
10405   let keepsol = &l:sol
10406   setl nosol
10407   let ctr    = a:firstline
10408
10409   " remove multiple files and directories
10410   while ctr <= a:lastline
10411    exe "NetrwKeepj ".ctr
10412    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
10413    if ok =~# 'q\%[uit]'
10414     break
10415    elseif ok =~# 'a\%[ll]'
10416     let all= 1
10417    endif
10418    let ctr= ctr + 1
10419   endwhile
10420   let &l:sol = keepsol
10421  endif
10422
10423  " refresh the (remote) directory listing
10424"  call Decho("refresh remote directory listing",'~'.expand("<slnum>"))
10425  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10426"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10427  NetrwKeepj call winrestview(svpos)
10428
10429"  call Dret("s:NetrwRemoteRm")
10430endfun
10431
10432" ---------------------------------------------------------------------
10433" s:NetrwRemoteRmFile: {{{2
10434fun! s:NetrwRemoteRmFile(path,rmfile,all)
10435"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
10436
10437  let all= a:all
10438  let ok = ""
10439
10440  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
10441   " attempt to remove file
10442"    call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
10443   if !all
10444    echohl Statement
10445"    call Decho("case all=0:",'~'.expand("<slnum>"))
10446    call inputsave()
10447    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10448    call inputrestore()
10449    echohl NONE
10450    if ok == ""
10451     let ok="no"
10452    endif
10453    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10454    if ok =~# 'a\%[ll]'
10455     let all= 1
10456    endif
10457   endif
10458
10459   if all || ok =~# 'y\%[es]' || ok == ""
10460"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
10461    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10462"     call Decho("case ftp:",'~'.expand("<slnum>"))
10463     let path= a:path
10464     if path =~ '^\a\{3,}://'
10465      let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
10466     endif
10467     sil! NetrwKeepj .,$d _
10468     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
10469    else
10470"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
10471     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
10472"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10473     if !exists("b:netrw_curdir")
10474      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
10475      let ok="q"
10476     else
10477      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
10478"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10479"      call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
10480"      call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
10481      if remotedir != ""
10482       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
10483      else
10484       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
10485      endif
10486"      call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
10487      let ret= system(netrw_rm_cmd)
10488      if v:shell_error != 0
10489       if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
10490	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-cd)",102)
10491       else
10492        call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10493       endif
10494      elseif ret != 0
10495       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10496      endif
10497"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10498     endif
10499    endif
10500   elseif ok =~# 'q\%[uit]'
10501"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10502   endif
10503
10504  else
10505   " attempt to remove directory
10506"    call Decho("attempt to remove directory",'~'.expand("<slnum>"))
10507   if !all
10508    call inputsave()
10509    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10510    call inputrestore()
10511    if ok == ""
10512     let ok="no"
10513    endif
10514    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10515    if ok =~# 'a\%[ll]'
10516     let all= 1
10517    endif
10518   endif
10519
10520   if all || ok =~# 'y\%[es]' || ok == ""
10521    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10522     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
10523    else
10524     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
10525     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
10526"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
10527     let ret= system(netrw_rmdir_cmd)
10528"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10529
10530     if v:shell_error != 0
10531"      call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
10532      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
10533"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
10534      let ret= system(netrw_rmf_cmd)
10535"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10536
10537      if v:shell_error != 0 && !exists("g:netrw_quiet")
10538      	NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
10539      endif
10540     endif
10541    endif
10542
10543   elseif ok =~# 'q\%[uit]'
10544"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10545   endif
10546  endif
10547
10548"  call Dret("s:NetrwRemoteRmFile ".ok)
10549  return ok
10550endfun
10551
10552" ---------------------------------------------------------------------
10553" s:NetrwRemoteRename: rename a remote file or directory {{{2
10554fun! s:NetrwRemoteRename(usrhost,path) range
10555"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
10556
10557  " preparation for removing multiple files/directories
10558  let svpos      = winsaveview()
10559"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10560  let ctr        = a:firstline
10561  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10562
10563  " rename files given by the markfilelist
10564  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10565   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10566"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10567    if exists("subfrom")
10568     let newname= substitute(oldname,subfrom,subto,'')
10569"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10570    else
10571     call inputsave()
10572     let newname= input("Moving ".oldname." to : ",oldname)
10573     call inputrestore()
10574     if newname =~ '^s/'
10575      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10576      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10577      let newname = substitute(oldname,subfrom,subto,'')
10578"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10579     endif
10580    endif
10581
10582    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10583     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10584    else
10585     let oldname= s:ShellEscape(a:path.oldname)
10586     let newname= s:ShellEscape(a:path.newname)
10587"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10588     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10589    endif
10590
10591   endfor
10592   call s:NetrwUnMarkFile(1)
10593
10594  else
10595
10596  " attempt to rename files/directories
10597   let keepsol= &l:sol
10598   setl nosol
10599   while ctr <= a:lastline
10600    exe "NetrwKeepj ".ctr
10601
10602    let oldname= s:NetrwGetWord()
10603"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10604
10605    call inputsave()
10606    let newname= input("Moving ".oldname." to : ",oldname)
10607    call inputrestore()
10608
10609    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10610     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10611    else
10612     let oldname= s:ShellEscape(a:path.oldname)
10613     let newname= s:ShellEscape(a:path.newname)
10614"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10615     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10616    endif
10617
10618    let ctr= ctr + 1
10619   endwhile
10620   let &l:sol= keepsol
10621  endif
10622
10623  " refresh the directory
10624  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10625"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10626  NetrwKeepj call winrestview(svpos)
10627
10628"  call Dret("NetrwRemoteRename")
10629endfun
10630
10631" ==========================================
10632"  Local Directory Browsing Support:    {{{1
10633" ==========================================
10634
10635" ---------------------------------------------------------------------
10636" netrw#FileUrlEdit: handles editing file://* files {{{2
10637"   Should accept:   file://localhost/etc/fstab
10638"                    file:///etc/fstab
10639"                    file:///c:/WINDOWS/clock.avi
10640"                    file:///c|/WINDOWS/clock.avi
10641"                    file://localhost/c:/WINDOWS/clock.avi
10642"                    file://localhost/c|/WINDOWS/clock.avi
10643"                    file://c:/foo.txt
10644"                    file:///c:/foo.txt
10645" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
10646fun! netrw#FileUrlEdit(fname)
10647"  call Dfunc("netrw#FileUrlEdit(fname<".a:fname.">)")
10648  let fname = a:fname
10649  if fname =~ '^file://localhost/'
10650"   call Decho('converting file://localhost/   -to-  file:///','~'.expand("<slnum>"))
10651   let fname= substitute(fname,'^file://localhost/','file:///','')
10652"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10653  endif
10654  if (has("win32") || has("win95") || has("win64") || has("win16"))
10655   if fname  =~ '^file:///\=\a[|:]/'
10656"    call Decho('converting file:///\a|/   -to-  file://\a:/','~'.expand("<slnum>"))
10657    let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10658"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10659   endif
10660  endif
10661  let fname2396 = netrw#RFC2396(fname)
10662  let fname2396e= fnameescape(fname2396)
10663  let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
10664  if (has("win32") || has("win95") || has("win64") || has("win16"))
10665"   call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10666   if plainfname =~ '^/\+\a:'
10667"    call Decho('removing leading "/"s','~'.expand("<slnum>"))
10668    let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10669   endif
10670  endif
10671
10672"  call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10673"  call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
10674  exe "sil doau BufReadPre ".fname2396e
10675  exe 'NetrwKeepj keepalt edit '.plainfname
10676  exe 'sil! NetrwKeepj keepalt bdelete '.fnameescape(a:fname)
10677
10678"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10679"  call Dret("netrw#FileUrlEdit")
10680  exe "sil doau BufReadPost ".fname2396e
10681endfun
10682
10683" ---------------------------------------------------------------------
10684" netrw#LocalBrowseCheck: {{{2
10685fun! netrw#LocalBrowseCheck(dirname)
10686  " This function is called by netrwPlugin.vim's s:LocalBrowse(), s:NetrwRexplore(),
10687  " and by <cr> when atop a listed file/directory (via a buffer-local map)
10688  "
10689  " unfortunate interaction -- split window debugging can't be used here, must use
10690  "                            D-echoRemOn or D-echoTabOn as the BufEnter event triggers
10691  "                            another call to LocalBrowseCheck() when attempts to write
10692  "                            to the DBG buffer are made.
10693  "
10694  " The &ft == "netrw" test was installed because the BufEnter event
10695  " would hit when re-entering netrw windows, creating unexpected
10696  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
10697"  call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">)")
10698"  call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>"))
10699"  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>"))
10700"  call Dredir("ls!","netrw#LocalBrowseCheck")
10701"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10702"  call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
10703
10704  let ykeep= @@
10705  if isdirectory(s:NetrwFile(a:dirname))
10706"   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>"))
10707
10708   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10709"    call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10710"    call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10711    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10712
10713   elseif &ft == "netrw" && line("$") == 1
10714"    call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10715    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10716
10717   elseif exists("s:treeforceredraw")
10718"    call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10719    unlet s:treeforceredraw
10720    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10721   endif
10722"   call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10723"   call Dret("netrw#LocalBrowseCheck")
10724   return
10725  endif
10726
10727  " The following code wipes out currently unused netrw buffers
10728  "       IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10729  "   AND IF the listing style is not a tree listing
10730  if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
10731"   call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10732   let ibuf    = 1
10733   let buflast = bufnr("$")
10734   while ibuf <= buflast
10735    if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10736     exe "sil! keepj keepalt ".ibuf."bw!"
10737    endif
10738    let ibuf= ibuf + 1
10739   endwhile
10740  endif
10741  let @@= ykeep
10742"  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>"))
10743"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10744  " not a directory, ignore it
10745"  call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
10746endfun
10747
10748" ---------------------------------------------------------------------
10749" s:LocalBrowseRefresh: this function is called after a user has {{{2
10750" performed any shell command.  The idea is to cause all local-browsing
10751" buffers to be refreshed after a user has executed some shell command,
10752" on the chance that s/he removed/created a file/directory with it.
10753fun! s:LocalBrowseRefresh()
10754"  call Dfunc("s:LocalBrowseRefresh() tabpagenr($)=".tabpagenr("$"))
10755"  call Decho("s:netrw_browselist =".(exists("s:netrw_browselist")?  string(s:netrw_browselist)  : '<n/a>'),'~'.expand("<slnum>"))
10756"  call Decho("w:netrw_bannercnt  =".(exists("w:netrw_bannercnt")?   string(w:netrw_bannercnt)   : '<n/a>'),'~'.expand("<slnum>"))
10757
10758  " determine which buffers currently reside in a tab
10759  if !exists("s:netrw_browselist")
10760"   call Dret("s:LocalBrowseRefresh : browselist is empty")
10761   return
10762  endif
10763  if !exists("w:netrw_bannercnt")
10764"   call Dret("s:LocalBrowseRefresh : don't refresh when focus not on netrw window")
10765   return
10766  endif
10767  if exists("s:netrw_events") && s:netrw_events == 1
10768   " s:LocalFastBrowser gets called (indirectly) from a
10769   let s:netrw_events= 2
10770"   call Dret("s:LocalBrowseRefresh : avoid initial double refresh")
10771   return
10772  endif
10773  let itab       = 1
10774  let buftablist = []
10775  let ykeep      = @@
10776  while itab <= tabpagenr("$")
10777   let buftablist = buftablist + tabpagebuflist()
10778   let itab       = itab + 1
10779   sil! tabn
10780  endwhile
10781"  call Decho("buftablist".string(buftablist),'~'.expand("<slnum>"))
10782"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("<slnum>"))
10783  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10784  "   | refresh any netrw window
10785  "   | wipe out any non-displaying netrw buffer
10786  let curwinid = win_getid(winnr())
10787  let ibl    = 0
10788  for ibuf in s:netrw_browselist
10789"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("<slnum>"))
10790   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10791    " wipe out any non-displaying netrw buffer
10792    " (ibuf not shown in a current window AND
10793    "  ibuf not in any tab)
10794"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("<slnum>"))
10795    exe "sil! keepj bd ".fnameescape(ibuf)
10796    call remove(s:netrw_browselist,ibl)
10797"    call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10798    continue
10799   elseif index(tabpagebuflist(),ibuf) != -1
10800    " refresh any netrw buffer
10801"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>"))
10802    exe bufwinnr(ibuf)."wincmd w"
10803    if getline(".") =~# 'Quick Help'
10804     " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10805     " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10806     let g:netrw_quickhelp= g:netrw_quickhelp - 1
10807    endif
10808"    call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>"))
10809    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10810     NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10811    endif
10812    NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10813   endif
10814   let ibl= ibl + 1
10815"   call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("<slnum>"))
10816  endfor
10817"  call Decho("restore window: win_gotoid(".curwinid.")")
10818  call win_gotoid(curwinid)
10819  let @@= ykeep
10820
10821"  call Dret("s:LocalBrowseRefresh")
10822endfun
10823
10824" ---------------------------------------------------------------------
10825" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10826"
10827"     g:netrw_    Directory Is
10828"     fastbrowse  Local  Remote
10829"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
10830"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
10831"  fast   2         H      H
10832"
10833"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10834"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
10835"                       (re-using a buffer may not be as accurate)
10836"
10837"  s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds whena med or fast browsing
10838"                   =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10839"                       BufEnter may be first event, then a FocusGained event.  Ignore the first FocusGained event.
10840"                       If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10841"                   =2: autocmds installed (doesn't ignore any FocusGained events)
10842fun! s:LocalFastBrowser()
10843"  call Dfunc("s:LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
10844"  call Decho("s:netrw_events        ".(exists("s:netrw_events")? "exists"            : 'n/a'),'~'.expand("<slnum>"))
10845"  call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")?  "already installed" : "not installed"),'~'.expand("<slnum>"))
10846"  call Decho("autocmd: FocusGained  ".(exists("#FocusGained")?   "already installed" : "not installed"),'~'.expand("<slnum>"))
10847
10848  " initialize browselist, a list of buffer numbers that the local browser has used
10849  if !exists("s:netrw_browselist")
10850"   call Decho("initialize s:netrw_browselist",'~'.expand("<slnum>"))
10851   let s:netrw_browselist= []
10852  endif
10853
10854  " append current buffer to fastbrowse list
10855  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
10856"   call Decho("appendng current buffer to browselist",'~'.expand("<slnum>"))
10857   call add(s:netrw_browselist,bufnr("%"))
10858"   call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10859  endif
10860
10861  " enable autocmd events to handle refreshing/removing local browser buffers
10862  "    If local browse buffer is currently showing: refresh it
10863  "    If local browse buffer is currently hidden : wipe it
10864  "    g:netrw_fastbrowse=0 : slow   speed, never re-use directory listing
10865  "                      =1 : medium speed, re-use directory listing for remote only
10866  "                      =2 : fast   speed, always re-use directory listing when possible
10867  if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
10868   let s:netrw_events= 1
10869   augroup AuNetrwEvent
10870    au!
10871    if (has("win32") || has("win95") || has("win64") || has("win16"))
10872"     call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
10873     au ShellCmdPost			*	call s:LocalBrowseRefresh()
10874    else
10875"     call Decho("installing autocmds: ShellCmdPost FocusGained",'~'.expand("<slnum>"))
10876     au ShellCmdPost,FocusGained	*	call s:LocalBrowseRefresh()
10877    endif
10878   augroup END
10879
10880  " user must have changed fastbrowse to its fast setting, so remove
10881  " the associated autocmd events
10882  elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
10883"   call Decho("remove AuNetrwEvent autcmd group",'~'.expand("<slnum>"))
10884   unlet s:netrw_events
10885   augroup AuNetrwEvent
10886    au!
10887   augroup END
10888   augroup! AuNetrwEvent
10889  endif
10890
10891"  call Dret("s:LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
10892endfun
10893
10894" ---------------------------------------------------------------------
10895"  s:LocalListing: does the job of "ls" for local directories {{{2
10896fun! s:LocalListing()
10897"  call Dfunc("s:LocalListing()")
10898"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10899"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
10900"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10901
10902"  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
10903"  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
10904"  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>"))
10905
10906  " get the list of files contained in the current directory
10907  let dirname    = b:netrw_curdir
10908  let dirnamelen = strlen(b:netrw_curdir)
10909  let filelist   = s:NetrwGlob(dirname,"*",0)
10910  let filelist   = filelist + s:NetrwGlob(dirname,".*",0)
10911"  call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10912
10913  if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
10914"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10915  elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
10916    " include ../ in the glob() entry if its missing
10917"   call Decho("forcibly including on \"..\"",'~'.expand("<slnum>"))
10918   let filelist= filelist+[s:ComposePath(b:netrw_curdir,"../")]
10919"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10920  endif
10921
10922"  call Decho("before while: dirname   <".dirname.">",'~'.expand("<slnum>"))
10923"  call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>"))
10924"  call Decho("before while: filelist  =".string(filelist),'~'.expand("<slnum>"))
10925
10926  if get(g:, 'netrw_dynamic_maxfilenamelen', 0)
10927   let filelistcopy           = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10928   let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
10929"   call Decho("dynamic_maxfilenamelen: filenames             =".string(filelistcopy),'~'.expand("<slnum>"))
10930"   call Decho("dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen,'~'.expand("<slnum>"))
10931  endif
10932"  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>"))
10933
10934  for filename in filelist
10935"   call Decho(" ",'~'.expand("<slnum>"))
10936"   call Decho("for filename in filelist: filename<".filename.">",'~'.expand("<slnum>"))
10937
10938   if getftype(filename) == "link"
10939    " indicate a symbolic link
10940"    call Decho("indicate <".filename."> is a symbolic link with trailing @",'~'.expand("<slnum>"))
10941    let pfile= filename."@"
10942
10943   elseif getftype(filename) == "socket"
10944    " indicate a socket
10945"    call Decho("indicate <".filename."> is a socket with trailing =",'~'.expand("<slnum>"))
10946    let pfile= filename."="
10947
10948   elseif getftype(filename) == "fifo"
10949    " indicate a fifo
10950"    call Decho("indicate <".filename."> is a fifo with trailing |",'~'.expand("<slnum>"))
10951    let pfile= filename."|"
10952
10953   elseif isdirectory(s:NetrwFile(filename))
10954    " indicate a directory
10955"    call Decho("indicate <".filename."> is a directory with trailing /",'~'.expand("<slnum>"))
10956    let pfile= filename."/"
10957
10958   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10959    if (has("win32") || has("win95") || has("win64") || has("win16"))
10960     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10961      " indicate an executable
10962"      call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10963      let pfile= filename."*"
10964     else
10965      " normal file
10966      let pfile= filename
10967     endif
10968    elseif executable(filename)
10969     " indicate an executable
10970"     call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10971     let pfile= filename."*"
10972    else
10973     " normal file
10974     let pfile= filename
10975    endif
10976
10977   else
10978    " normal file
10979    let pfile= filename
10980   endif
10981"   call Decho("pfile<".pfile."> (after *@/ appending)",'~'.expand("<slnum>"))
10982
10983   if pfile =~ '//$'
10984    let pfile= substitute(pfile,'//$','/','e')
10985"    call Decho("change // to /: pfile<".pfile.">",'~'.expand("<slnum>"))
10986   endif
10987   let pfile= strpart(pfile,dirnamelen)
10988   let pfile= substitute(pfile,'^[/\\]','','e')
10989"   call Decho("filename<".filename.">",'~'.expand("<slnum>"))
10990"   call Decho("pfile   <".pfile.">",'~'.expand("<slnum>"))
10991
10992   if w:netrw_liststyle == s:LONGLIST
10993    let sz   = getfsize(filename)
10994    let fsz  = strpart("               ",1,15-strlen(sz)).sz
10995    if g:netrw_sizestyle =~# "[hH]"
10996     let sz= s:NetrwHumanReadable(sz)
10997    endif
10998    let longfile= printf("%-".(g:netrw_maxfilenamelen+1)."s",pfile)
10999    let pfile   = longfile.fsz." ".strftime(g:netrw_timefmt,getftime(filename))
11000"    call Decho("longlist support: sz=".sz." fsz=".fsz,'~'.expand("<slnum>"))
11001   endif
11002
11003   if     g:netrw_sort_by =~# "^t"
11004    " sort by time (handles time up to 1 quintillion seconds, US)
11005    " Decorate listing by prepending a timestamp/  .  Sorting will then be done based on time.
11006"    call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>"))
11007    let t  = getftime(filename)
11008    let ft = strpart("000000000000000000",1,18-strlen(t)).t
11009"    call Decho("exe NetrwKeepj put ='".ft.'/'.pfile."'",'~'.expand("<slnum>"))
11010    let ftpfile= ft.'/'.pfile
11011    sil! NetrwKeepj put=ftpfile
11012
11013   elseif g:netrw_sort_by =~ "^s"
11014    " sort by size (handles file sizes up to 1 quintillion bytes, US)
11015"    call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>"))
11016    let sz   = getfsize(filename)
11017    if g:netrw_sizestyle =~# "[hH]"
11018     let sz= s:NetrwHumanReadable(sz)
11019    endif
11020    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
11021"    call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>"))
11022    let fszpfile= fsz.'/'.pfile
11023    sil! NetrwKeepj put =fszpfile
11024
11025   else
11026    " sort by name
11027"    call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("<slnum>"))
11028    sil! NetrwKeepj put=pfile
11029   endif
11030"   call DechoBuf(bufnr("%"),"bufnr(%)")
11031  endfor
11032
11033  " cleanup any windows mess at end-of-line
11034  sil! NetrwKeepj g/^$/d
11035  sil! NetrwKeepj %s/\r$//e
11036  call histdel("/",-1)
11037"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
11038  exe "setl ts=".(g:netrw_maxfilenamelen+1)
11039
11040"  call Dret("s:LocalListing")
11041endfun
11042
11043" ---------------------------------------------------------------------
11044" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
11045fun! s:NetrwLocalExecute(cmd)
11046"  call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
11047  let ykeep= @@
11048  " sanity check
11049  if !executable(a:cmd)
11050   call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
11051   let @@= ykeep
11052"   call Dret("s:NetrwLocalExecute")
11053   return
11054  endif
11055
11056  let optargs= input(":!".a:cmd,"","file")
11057"  call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
11058  let result= system(a:cmd.optargs)
11059"  call Decho("result,'~'.expand("<slnum>"))
11060
11061  " strip any ansi escape sequences off
11062  let result = substitute(result,"\e\\[[0-9;]*m","","g")
11063
11064  " show user the result(s)
11065  echomsg result
11066  let @@= ykeep
11067
11068"  call Dret("s:NetrwLocalExecute")
11069endfun
11070
11071" ---------------------------------------------------------------------
11072" s:NetrwLocalRename: rename a local file or directory {{{2
11073fun! s:NetrwLocalRename(path) range
11074"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
11075
11076  " preparation for removing multiple files/directories
11077  let ykeep     = @@
11078  let ctr       = a:firstline
11079  let svpos     = winsaveview()
11080  let all       = 0
11081"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11082
11083  " rename files given by the markfilelist
11084  if exists("s:netrwmarkfilelist_{bufnr('%')}")
11085   for oldname in s:netrwmarkfilelist_{bufnr("%")}
11086"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
11087    if exists("subfrom")
11088     let newname= substitute(oldname,subfrom,subto,'')
11089"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
11090    else
11091     call inputsave()
11092     let newname= input("Moving ".oldname." to : ",oldname,"file")
11093     call inputrestore()
11094     if newname =~ ''
11095      " two ctrl-x's : ignore all of string preceding the ctrl-x's
11096      let newname = substitute(newname,'^.*','','')
11097     elseif newname =~ ''
11098      " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
11099      let newname = substitute(newname,'[^/]*','','')
11100     endif
11101     if newname =~ '^s/'
11102      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
11103      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
11104"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
11105      let newname = substitute(oldname,subfrom,subto,'')
11106     endif
11107    endif
11108    if !all && filereadable(newname)
11109     call inputsave()
11110      let response= input("File<".newname."> already exists; do you want to overwrite it? (y/all/n) ")
11111     call inputrestore()
11112     if response == "all"
11113      let all= 1
11114     elseif response != "y" && response != "yes"
11115      " refresh the directory
11116"      call Decho("refresh the directory listing",'~'.expand("<slnum>"))
11117      NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11118"      call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11119      NetrwKeepj call winrestview(svpos)
11120      let @@= ykeep
11121"      call Dret("NetrwLocalRename")
11122      return
11123     endif
11124    endif
11125    call rename(oldname,newname)
11126   endfor
11127   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
11128
11129  else
11130
11131   " attempt to rename files/directories
11132   while ctr <= a:lastline
11133    exe "NetrwKeepj ".ctr
11134
11135    " sanity checks
11136    if line(".") < w:netrw_bannercnt
11137     let ctr= ctr + 1
11138     continue
11139    endif
11140    let curword= s:NetrwGetWord()
11141    if curword == "./" || curword == "../"
11142     let ctr= ctr + 1
11143     continue
11144    endif
11145
11146    NetrwKeepj norm! 0
11147    let oldname= s:ComposePath(a:path,curword)
11148"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
11149
11150    call inputsave()
11151    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
11152    call inputrestore()
11153
11154    call rename(oldname,newname)
11155"    call Decho("renaming <".oldname."> to <".newname.">",'~'.expand("<slnum>"))
11156
11157    let ctr= ctr + 1
11158   endwhile
11159  endif
11160
11161  " refresh the directory
11162"  call Decho("refresh the directory listing",'~'.expand("<slnum>"))
11163  NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11164"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11165  NetrwKeepj call winrestview(svpos)
11166  let @@= ykeep
11167
11168"  call Dret("NetrwLocalRename")
11169endfun
11170
11171" ---------------------------------------------------------------------
11172" s:NetrwLocalRm: {{{2
11173fun! s:NetrwLocalRm(path) range
11174"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
11175"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
11176
11177  " preparation for removing multiple files/directories
11178  let ykeep = @@
11179  let ret   = 0
11180  let all   = 0
11181  let svpos = winsaveview()
11182"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11183
11184  if exists("s:netrwmarkfilelist_{bufnr('%')}")
11185   " remove all marked files
11186"   call Decho("remove all marked files",'~'.expand("<slnum>"))
11187   for fname in s:netrwmarkfilelist_{bufnr("%")}
11188    let ok= s:NetrwLocalRmFile(a:path,fname,all)
11189    if ok =~# 'q\%[uit]' || ok == "no"
11190     break
11191    elseif ok =~# 'a\%[ll]'
11192     let all= 1
11193    endif
11194   endfor
11195   call s:NetrwUnMarkFile(1)
11196
11197  else
11198  " remove (multiple) files and directories
11199"   call Decho("remove files in range [".a:firstline.",".a:lastline."]",'~'.expand("<slnum>"))
11200
11201   let keepsol= &l:sol
11202   setl nosol
11203   let ctr = a:firstline
11204   while ctr <= a:lastline
11205    exe "NetrwKeepj ".ctr
11206
11207    " sanity checks
11208    if line(".") < w:netrw_bannercnt
11209     let ctr= ctr + 1
11210     continue
11211    endif
11212    let curword= s:NetrwGetWord()
11213    if curword == "./" || curword == "../"
11214     let ctr= ctr + 1
11215     continue
11216    endif
11217    let ok= s:NetrwLocalRmFile(a:path,curword,all)
11218    if ok =~# 'q\%[uit]' || ok == "no"
11219     break
11220    elseif ok =~# 'a\%[ll]'
11221     let all= 1
11222    endif
11223    let ctr= ctr + 1
11224   endwhile
11225   let &l:sol= keepsol
11226  endif
11227
11228  " refresh the directory
11229"  call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>"))
11230  if bufname("%") != "NetrwMessage"
11231   NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11232"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11233   NetrwKeepj call winrestview(svpos)
11234  endif
11235  let @@= ykeep
11236
11237"  call Dret("s:NetrwLocalRm")
11238endfun
11239
11240" ---------------------------------------------------------------------
11241" s:NetrwLocalRmFile: remove file fname given the path {{{2
11242"                     Give confirmation prompt unless all==1
11243fun! s:NetrwLocalRmFile(path,fname,all)
11244"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
11245
11246  let all= a:all
11247  let ok = ""
11248  NetrwKeepj norm! 0
11249  let rmfile= s:NetrwFile(s:ComposePath(a:path,a:fname))
11250"  call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
11251
11252  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
11253   " attempt to remove file
11254"   call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
11255   if !all
11256    echohl Statement
11257    call inputsave()
11258    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11259    call inputrestore()
11260    echohl NONE
11261    if ok == ""
11262     let ok="no"
11263    endif
11264"    call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
11265    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11266"    call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
11267    if ok =~# 'a\%[ll]'
11268     let all= 1
11269    endif
11270   endif
11271
11272   if all || ok =~# 'y\%[es]' || ok == ""
11273    let ret= s:NetrwDelete(rmfile)
11274"    call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
11275   endif
11276
11277  else
11278   " attempt to remove directory
11279   if !all
11280    echohl Statement
11281    call inputsave()
11282    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11283    call inputrestore()
11284    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11285    if ok == ""
11286     let ok="no"
11287    endif
11288    if ok =~# 'a\%[ll]'
11289     let all= 1
11290    endif
11291   endif
11292   let rmfile= substitute(rmfile,'[\/]$','','e')
11293
11294   if all || ok =~# 'y\%[es]' || ok == ""
11295    if v:version < 704 || (v:version == 704 && !has("patch1107"))
11296" "    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>"))
11297     call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile))
11298" "    call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>"))
11299
11300     if v:shell_error != 0
11301" "     call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11302      let errcode= s:NetrwDelete(rmfile)
11303" "     call Decho("errcode=".errcode,'~'.expand("<slnum>"))
11304
11305      if errcode != 0
11306       if has("unix")
11307" "       call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11308	call system("rm ".s:ShellEscape(rmfile))
11309	if v:shell_error != 0 && !exists("g:netrw_quiet")
11310	 call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
11311	 let ok="no"
11312	endif
11313       elseif !exists("g:netrw_quiet")
11314	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
11315	let ok="no"
11316       endif
11317      endif
11318     endif
11319    else
11320     if delete(rmfile,"d")
11321      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
11322     endif
11323    endif
11324   endif
11325  endif
11326
11327"  call Dret("s:NetrwLocalRmFile ".ok)
11328  return ok
11329endfun
11330
11331" =====================================================================
11332" Support Functions: {{{1
11333
11334" ---------------------------------------------------------------------
11335" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
11336"   0: marked file list of current buffer
11337"   1: marked file target
11338fun! netrw#Access(ilist)
11339  if     a:ilist == 0
11340   if exists("s:netrwmarkfilelist_".bufnr('%'))
11341    return s:netrwmarkfilelist_{bufnr('%')}
11342   else
11343    return "no-list-buf#".bufnr('%')
11344   endif
11345  elseif a:ilist == 1
11346   return s:netrwmftgt
11347  endif
11348endfun
11349
11350" ---------------------------------------------------------------------
11351" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
11352fun! netrw#Call(funcname,...)
11353  return call("s:".a:funcname,a:000)
11354endfun
11355
11356" ---------------------------------------------------------------------
11357" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
11358"               I expect this function to be used in
11359"                 :PChkAssert netrw#Expose("netrwmarkfilelist")
11360"               for example.
11361fun! netrw#Expose(varname)
11362"   call Dfunc("netrw#Expose(varname<".a:varname.">)")
11363  if exists("s:".a:varname)
11364   exe "let retval= s:".a:varname
11365"   call Decho("retval=".retval,'~'.expand("<slnum>"))
11366   if exists("g:netrw_pchk")
11367"    call Decho("type(g:netrw_pchk=".g:netrw_pchk.")=".type(retval),'~'.expand("<slnum>"))
11368    if type(retval) == 3
11369     let retval = copy(retval)
11370     let i      = 0
11371     while i < len(retval)
11372      let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
11373      let i        = i + 1
11374     endwhile
11375    endif
11376"     call Dret("netrw#Expose ".string(retval)),'~'.expand("<slnum>"))
11377    return string(retval)
11378   else
11379"    call Decho("g:netrw_pchk doesn't exist",'~'.expand("<slnum>"))
11380   endif
11381  else
11382"   call Decho("s:".a:varname." doesn't exist",'~'.expand("<slnum>"))
11383   let retval= "n/a"
11384  endif
11385
11386"  call Dret("netrw#Expose ".string(retval))
11387  return retval
11388endfun
11389
11390" ---------------------------------------------------------------------
11391" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
11392fun! netrw#Modify(varname,newvalue)
11393"  call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
11394  exe "let s:".a:varname."= ".string(a:newvalue)
11395"  call Dret("netrw#Modify")
11396endfun
11397
11398" ---------------------------------------------------------------------
11399"  netrw#RFC2396: converts %xx into characters {{{2
11400fun! netrw#RFC2396(fname)
11401"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
11402  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
11403"  call Dret("netrw#RFC2396 ".fname)
11404  return fname
11405endfun
11406
11407" ---------------------------------------------------------------------
11408" netrw#UserMaps: supports user-specified maps {{{2
11409"                 see :help function()
11410"
11411"                 g:Netrw_UserMaps is a List with members such as:
11412"                       [[keymap sequence, function reference],...]
11413"
11414"                 The referenced function may return a string,
11415"                 	refresh : refresh the display
11416"                 	-other- : this string will be executed
11417"                 or it may return a List of strings.
11418"
11419"                 Each keymap-sequence will be set up with a nnoremap
11420"                 to invoke netrw#UserMaps(a:islocal).
11421"                 Related functions:
11422"                   netrw#Expose(varname)          -- see s:varname variables
11423"                   netrw#Modify(varname,newvalue) -- modify value of s:varname variable
11424"                   netrw#Call(funcname,...)       -- call internal netrw function with optional arguments
11425fun! netrw#UserMaps(islocal)
11426"  call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
11427"  call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
11428
11429   " set up usermaplist
11430   if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
11431"    call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
11432    for umap in g:Netrw_UserMaps
11433"     call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
11434"     call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
11435     " if umap[0] is a string and umap[1] is a string holding a function name
11436     if type(umap[0]) == 1 && type(umap[1]) == 1
11437"      call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
11438      exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
11439      else
11440       call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
11441     endif
11442    endfor
11443   endif
11444"  call Dret("netrw#UserMaps")
11445endfun
11446
11447" ---------------------------------------------------------------------
11448" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
11449fun! netrw#WinPath(path)
11450"  call Dfunc("netrw#WinPath(path<".a:path.">)")
11451  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
11452   " remove cygdrive prefix, if present
11453   let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
11454   " remove trailing slash (Win95)
11455   let path = substitute(path, '\(\\\|/\)$', '', 'g')
11456   " remove escaped spaces
11457   let path = substitute(path, '\ ', ' ', 'g')
11458   " convert slashes to backslashes
11459   let path = substitute(path, '/', '\', 'g')
11460  else
11461   let path= a:path
11462  endif
11463"  call Dret("netrw#WinPath <".path.">")
11464  return path
11465endfun
11466
11467" ---------------------------------------------------------------------
11468" s:NetrwBadd: adds marked files to buffer list or vice versa {{{2
11469"              cb : bl2mf=0  add marked files to buffer list
11470"              cB : bl2mf=1  use bufferlist to mark files
11471"              (mnemonic: cb = copy (marked files) to buffer list)
11472fun! s:NetrwBadd(islocal,bl2mf)
11473"  "  call Dfunc("s:NetrwBadd(islocal=".a:islocal." mf2bl=".mf2bl.")")
11474  if a:bl2mf
11475   " cB: add buffer list to marked files
11476   redir => bufl
11477    ls
11478   redir END
11479   let bufl = map(split(bufl,"\n"),'substitute(v:val,''^.\{-}"\(.*\)".\{-}$'',''\1'','''')')
11480   for fname in bufl
11481    call s:NetrwMarkFile(a:islocal,fname)
11482   endfor
11483  else
11484   " cb: add marked files to buffer list
11485   for fname in s:netrwmarkfilelist_{bufnr("%")}
11486" "   call Decho("badd ".fname,'~'.expand("<slnum>"))
11487    exe "badd ".fnameescape(fname)
11488   endfor
11489   let curbufnr = bufnr("%")
11490   let curdir   = s:NetrwGetCurdir(a:islocal)
11491   call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
11492  endif
11493"  call Dret("s:NetrwBadd")
11494endfun
11495
11496" ---------------------------------------------------------------------
11497"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
11498fun! s:ComposePath(base,subdir)
11499"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
11500
11501  if has("amiga")
11502"   call Decho("amiga",'~'.expand("<slnum>"))
11503   let ec = a:base[s:Strlen(a:base)-1]
11504   if ec != '/' && ec != ':'
11505    let ret = a:base."/" . a:subdir
11506   else
11507    let ret = a:base.a:subdir
11508   endif
11509
11510   " COMBAK: test on windows with changing to root directory: :e C:/
11511  elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11512"   call Decho("windows",'~'.expand("<slnum>"))
11513   let ret= a:subdir
11514
11515  elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11516"   call Decho("windows",'~'.expand("<slnum>"))
11517   if a:base =~ '[/\\]$'
11518    let ret= a:base.a:subdir
11519   else
11520    let ret= a:base.'/'.a:subdir
11521   endif
11522
11523  elseif a:base =~ '^\a\{3,}://'
11524"   call Decho("remote linux/macos",'~'.expand("<slnum>"))
11525   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
11526   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
11527   if a:subdir == '../'
11528    if curpath =~ '[^/]/[^/]\+/$'
11529     let curpath= substitute(curpath,'[^/]\+/$','','')
11530    else
11531     let curpath=""
11532    endif
11533    let ret= urlbase.curpath
11534   else
11535    let ret= urlbase.curpath.a:subdir
11536   endif
11537"   call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
11538"   call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
11539"   call Decho("ret<".ret.">",'~'.expand("<slnum>"))
11540
11541  else
11542"   call Decho("local linux/macos",'~'.expand("<slnum>"))
11543   let ret = substitute(a:base."/".a:subdir,"//","/","g")
11544   if a:base =~ '^//'
11545    " keeping initial '//' for the benefit of network share listing support
11546    let ret= '/'.ret
11547   endif
11548   let ret= simplify(ret)
11549  endif
11550
11551"  call Dret("s:ComposePath ".ret)
11552  return ret
11553endfun
11554
11555" ---------------------------------------------------------------------
11556" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
11557"   Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
11558fun! s:DeleteBookmark(fname)
11559"  call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
11560  call s:MergeBookmarks()
11561
11562  if exists("g:netrw_bookmarklist")
11563   let indx= index(g:netrw_bookmarklist,a:fname)
11564   if indx == -1
11565    let indx= 0
11566    while indx < len(g:netrw_bookmarklist)
11567     if g:netrw_bookmarklist[indx] =~ a:fname
11568      call remove(g:netrw_bookmarklist,indx)
11569      let indx= indx - 1
11570     endif
11571     let indx= indx + 1
11572    endwhile
11573   else
11574    " remove exact match
11575    call remove(g:netrw_bookmarklist,indx)
11576   endif
11577  endif
11578
11579"  call Dret("s:DeleteBookmark")
11580endfun
11581
11582" ---------------------------------------------------------------------
11583" s:FileReadable: o/s independent filereadable {{{2
11584fun! s:FileReadable(fname)
11585"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
11586
11587  if g:netrw_cygwin
11588   let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
11589  else
11590   let ret= filereadable(s:NetrwFile(a:fname))
11591  endif
11592
11593"  call Dret("s:FileReadable ".ret)
11594  return ret
11595endfun
11596
11597" ---------------------------------------------------------------------
11598"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
11599"                 Places correct suffix on end of temporary filename,
11600"                 using the suffix provided with fname
11601fun! s:GetTempfile(fname)
11602"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
11603
11604  if !exists("b:netrw_tmpfile")
11605   " get a brand new temporary filename
11606   let tmpfile= tempname()
11607"   call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
11608
11609   let tmpfile= substitute(tmpfile,'\','/','ge')
11610"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
11611
11612   " sanity check -- does the temporary file's directory exist?
11613   if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
11614"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11615    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
11616"    call Dret("s:GetTempfile getcwd<".getcwd().">")
11617    return ""
11618   endif
11619
11620   " let netrw#NetSource() know about the tmpfile
11621   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
11622"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
11623
11624   " o/s dependencies
11625   if g:netrw_cygwin != 0
11626    let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
11627   elseif has("win32") || has("win95") || has("win64") || has("win16")
11628    if !exists("+shellslash") || !&ssl
11629     let tmpfile = substitute(tmpfile,'/','\','g')
11630    endif
11631   else
11632    let tmpfile = tmpfile
11633   endif
11634   let b:netrw_tmpfile= tmpfile
11635"   call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
11636  else
11637   " re-use temporary filename
11638   let tmpfile= b:netrw_tmpfile
11639"   call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
11640  endif
11641
11642  " use fname's suffix for the temporary file
11643  if a:fname != ""
11644   if a:fname =~ '\.[^./]\+$'
11645"    call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11646    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11647     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11648    elseif a:fname =~ '.txz$'
11649     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11650    else
11651     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11652    endif
11653"    call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11654    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11655"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11656    let tmpfile .= suffix
11657"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11658    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
11659   endif
11660  endif
11661
11662"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11663"  call Dret("s:GetTempfile <".tmpfile.">")
11664  return tmpfile
11665endfun
11666
11667" ---------------------------------------------------------------------
11668" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
11669"               a correct command for use with a system() call
11670fun! s:MakeSshCmd(sshcmd)
11671"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
11672  if s:user == ""
11673   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
11674  else
11675   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
11676  endif
11677  if exists("g:netrw_port") && g:netrw_port != ""
11678   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
11679  elseif exists("s:port") && s:port != ""
11680   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
11681  else
11682   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
11683  endif
11684"  call Dret("s:MakeSshCmd <".sshcmd.">")
11685  return sshcmd
11686endfun
11687
11688" ---------------------------------------------------------------------
11689" s:MakeBookmark: enters a bookmark into Netrw's bookmark system   {{{2
11690fun! s:MakeBookmark(fname)
11691"  call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
11692
11693  if !exists("g:netrw_bookmarklist")
11694   let g:netrw_bookmarklist= []
11695  endif
11696
11697  if index(g:netrw_bookmarklist,a:fname) == -1
11698   " curdir not currently in g:netrw_bookmarklist, so include it
11699   if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11700    call add(g:netrw_bookmarklist,a:fname.'/')
11701   elseif a:fname !~ '/'
11702    call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11703   else
11704    call add(g:netrw_bookmarklist,a:fname)
11705   endif
11706   call sort(g:netrw_bookmarklist)
11707  endif
11708
11709"  call Dret("s:MakeBookmark")
11710endfun
11711
11712" ---------------------------------------------------------------------
11713" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11714fun! s:MergeBookmarks()
11715"  call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
11716  " get bookmarks from .netrwbook file
11717  let savefile= s:NetrwHome()."/.netrwbook"
11718  if filereadable(s:NetrwFile(savefile))
11719"   call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11720   NetrwKeepj call s:NetrwBookHistSave()
11721"   call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11722   NetrwKeepj call delete(savefile)
11723  endif
11724"  call Dret("s:MergeBookmarks")
11725endfun
11726
11727" ---------------------------------------------------------------------
11728" s:NetrwBMShow: {{{2
11729fun! s:NetrwBMShow()
11730"  call Dfunc("s:NetrwBMShow()")
11731  redir => bmshowraw
11732   menu
11733  redir END
11734  let bmshowlist = split(bmshowraw,'\n')
11735  if bmshowlist != []
11736   let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"')
11737   if bmshowfuncs != []
11738    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11739    if bmshowfunc =~# '^call.*BMShow()'
11740     exe "sil! NetrwKeepj ".bmshowfunc
11741    endif
11742   endif
11743  endif
11744"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
11745endfun
11746
11747" ---------------------------------------------------------------------
11748" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
11749fun! s:NetrwCursor()
11750  if !exists("w:netrw_liststyle")
11751   let w:netrw_liststyle= g:netrw_liststyle
11752  endif
11753"  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)
11754
11755  if &ft != "netrw"
11756   " if the current window isn't a netrw directory listing window, then use user cursorline/column
11757   " settings.  Affects when netrw is used to read/write a file using scp/ftp/etc.
11758"   call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
11759   let &l:cursorline   = s:netrw_usercul
11760   let &l:cursorcolumn = s:netrw_usercuc
11761
11762  elseif g:netrw_cursor == 4
11763   " all styles: cursorline, cursorcolumn
11764"   call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
11765   setl cursorline
11766   setl cursorcolumn
11767
11768  elseif g:netrw_cursor == 3
11769   " thin-long-tree: cursorline, user's cursorcolumn
11770   " wide          : cursorline, cursorcolumn
11771   if w:netrw_liststyle == s:WIDELIST
11772"    call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11773    setl cursorline
11774    setl cursorcolumn
11775   else
11776"    call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11777    setl cursorline
11778    let &l:cursorcolumn   = s:netrw_usercuc
11779   endif
11780
11781  elseif g:netrw_cursor == 2
11782   " thin-long-tree: cursorline, user's cursorcolumn
11783   " wide          : cursorline, user's cursorcolumn
11784"   call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11785   let &l:cursorcolumn = s:netrw_usercuc
11786   setl cursorline
11787
11788  elseif g:netrw_cursor == 1
11789   " thin-long-tree: user's cursorline, user's cursorcolumn
11790   " wide          : cursorline,        user's cursorcolumn
11791   let &l:cursorcolumn = s:netrw_usercuc
11792   if w:netrw_liststyle == s:WIDELIST
11793"    call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11794    setl cursorline
11795   else
11796"    call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11797    let &l:cursorline   = s:netrw_usercul
11798   endif
11799
11800  else
11801   " all styles: user's cursorline, user's cursorcolumn
11802"   call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11803   let &l:cursorline   = s:netrw_usercul
11804   let &l:cursorcolumn = s:netrw_usercuc
11805  endif
11806
11807"  call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
11808endfun
11809
11810" ---------------------------------------------------------------------
11811" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11812fun! s:RestoreCursorline()
11813"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
11814  if exists("s:netrw_usercul")
11815   let &l:cursorline   = s:netrw_usercul
11816  endif
11817  if exists("s:netrw_usercuc")
11818   let &l:cursorcolumn = s:netrw_usercuc
11819  endif
11820"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
11821endfun
11822
11823" ---------------------------------------------------------------------
11824" s:NetrwDelete: Deletes a file. {{{2
11825"           Uses Steve Hall's idea to insure that Windows paths stay
11826"           acceptable.  No effect on Unix paths.
11827"  Examples of use:  let result= s:NetrwDelete(path)
11828fun! s:NetrwDelete(path)
11829"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
11830
11831  let path = netrw#WinPath(a:path)
11832  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
11833   if exists("+shellslash")
11834    let sskeep= &shellslash
11835    setl noshellslash
11836    let result      = delete(path)
11837    let &shellslash = sskeep
11838   else
11839"    call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11840    let result= delete(path)
11841   endif
11842  else
11843"   call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11844   let result= delete(path)
11845  endif
11846  if result < 0
11847   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
11848  endif
11849
11850"  call Dret("s:NetrwDelete ".result)
11851  return result
11852endfun
11853
11854" ---------------------------------------------------------------------
11855" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
11856fun! s:NetrwEnew(...)
11857"  call Dfunc("s:NetrwEnew() a:0=".a:0." win#".winnr()." winnr($)=".winnr("$")." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
11858"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
11859
11860  " grab a function-local-variable copy of buffer variables
11861"  call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
11862  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
11863  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
11864  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
11865  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
11866  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11867  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
11868  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
11869  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
11870  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11871  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11872  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
11873  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
11874  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
11875  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
11876  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
11877  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
11878
11879  NetrwKeepj call s:NetrwOptionsRestore("w:")
11880"  call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>"))
11881  " when tree listing uses file TreeListing... a new buffer is made.
11882  " Want the old buffer to be unlisted.
11883  " COMBAK: this causes a problem, see P43
11884"  setl nobl
11885  let netrw_keepdiff= &l:diff
11886  noswapfile NetrwKeepj keepalt enew!
11887  let &l:diff= netrw_keepdiff
11888"  call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
11889  NetrwKeepj call s:NetrwOptionsSave("w:")
11890
11891  " copy function-local-variables to buffer variable equivalents
11892"  call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
11893  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
11894  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
11895  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
11896  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
11897  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
11898  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
11899  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
11900  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
11901  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11902  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11903  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
11904  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
11905  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
11906  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
11907  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
11908  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
11909
11910  if a:0 > 0
11911   let b:netrw_curdir= a:1
11912   if b:netrw_curdir =~ '/$'
11913    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11914     setl nobl
11915     file NetrwTreeListing
11916     setl nobl bt=nowrite bh=hide
11917     nno <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
11918     nno <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
11919    else
11920     call s:NetrwBufRename(b:netrw_curdir)
11921    endif
11922   endif
11923  endif
11924  if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
11925   let &l:bexpr = "netrw#BalloonHelp()"
11926  endif
11927
11928"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
11929endfun
11930
11931" ---------------------------------------------------------------------
11932" s:NetrwExe: executes a string using "!" {{{2
11933fun! s:NetrwExe(cmd)
11934"  call Dfunc("s:NetrwExe(a:cmd<".a:cmd.">)")
11935  if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin
11936"    call Decho("using win32:",expand("<slnum>"))
11937    let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
11938    set shell& shellcmdflag& shellxquote& shellxescape&
11939    set shellquote& shellpipe& shellredir& shellslash&
11940    exe a:cmd
11941    let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
11942  else
11943"   call Decho("exe ".a:cmd,'~'.expand("<slnum>"))
11944   exe a:cmd
11945  endif
11946  if v:shell_error
11947   call netrw#ErrorMsg(s:WARNING,"shell signalled an error",106)
11948  endif
11949"  call Dret("s:NetrwExe : v:shell_error=".v:shell_error)
11950endfun
11951
11952" ---------------------------------------------------------------------
11953" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
11954fun! s:NetrwInsureWinVars()
11955  if !exists("w:netrw_liststyle")
11956"   call Dfunc("s:NetrwInsureWinVars() win#".winnr())
11957   let curbuf = bufnr("%")
11958   let curwin = winnr()
11959   let iwin   = 1
11960   while iwin <= winnr("$")
11961    exe iwin."wincmd w"
11962    if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
11963     " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
11964     let winvars= w:
11965     break
11966    endif
11967    let iwin= iwin + 1
11968   endwhile
11969   exe "keepalt ".curwin."wincmd w"
11970   if exists("winvars")
11971"    call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
11972    for k in keys(winvars)
11973     let w:{k}= winvars[k]
11974    endfor
11975   endif
11976"   call Dret("s:NetrwInsureWinVars win#".winnr())
11977  endif
11978endfun
11979
11980" ---------------------------------------------------------------------
11981" s:NetrwLcd: handles changing the (local) directory {{{2
11982"   Returns: 0=success
11983"           -1=failed
11984fun! s:NetrwLcd(newdir)
11985"  call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
11986"  call Decho("changing local directory",'~'.expand("<slnum>"))
11987
11988  let err472= 0
11989  try
11990   exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
11991  catch /^Vim\%((\a\+)\)\=:E344/
11992     " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
11993     " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
11994     " 'root' (ie. '\').  The share name may start with either backslashes ('\\Foo') or
11995     " forward slashes ('//Foo'), depending on whether backslashes have been converted to
11996     " forward slashes by earlier code; so check for both.
11997     if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
11998       if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
11999         let dirname = '\'
12000	 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
12001       endif
12002     endif
12003  catch /^Vim\%((\a\+)\)\=:E472/
12004   let err472= 1
12005  endtry
12006
12007  if err472
12008   call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
12009   if exists("w:netrw_prvdir")
12010    let a:newdir= w:netrw_prvdir
12011   else
12012    call s:NetrwOptionsRestore("w:")
12013"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
12014    exe "setl ".g:netrw_bufsettings
12015"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
12016    let a:newdir= dirname
12017   endif
12018"   call Dret("s:NetrwBrowse -1 : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
12019   return -1
12020  endif
12021
12022"  call Decho("getcwd        <".getcwd().">")
12023"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
12024"  call Dret("s:NetrwLcd 0")
12025  return 0
12026endfun
12027
12028" ------------------------------------------------------------------------
12029" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
12030" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
12031fun! s:NetrwSaveWordPosn()
12032"  call Dfunc("NetrwSaveWordPosn()")
12033  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
12034"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
12035endfun
12036
12037" ---------------------------------------------------------------------
12038" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
12039"                       1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
12040fun! s:NetrwHumanReadable(sz)
12041"  call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
12042
12043  if g:netrw_sizestyle == 'h'
12044   if a:sz >= 1000000000
12045    let sz = printf("%.1f",a:sz/1000000000.0)."g"
12046   elseif a:sz >= 10000000
12047    let sz = printf("%d",a:sz/1000000)."m"
12048   elseif a:sz >= 1000000
12049    let sz = printf("%.1f",a:sz/1000000.0)."m"
12050   elseif a:sz >= 10000
12051    let sz = printf("%d",a:sz/1000)."k"
12052   elseif a:sz >= 1000
12053    let sz = printf("%.1f",a:sz/1000.0)."k"
12054   else
12055    let sz= a:sz
12056   endif
12057
12058  elseif g:netrw_sizestyle == 'H'
12059   if a:sz >= 1073741824
12060    let sz = printf("%.1f",a:sz/1073741824.0)."G"
12061   elseif a:sz >= 10485760
12062    let sz = printf("%d",a:sz/1048576)."M"
12063   elseif a:sz >= 1048576
12064    let sz = printf("%.1f",a:sz/1048576.0)."M"
12065   elseif a:sz >= 10240
12066    let sz = printf("%d",a:sz/1024)."K"
12067   elseif a:sz >= 1024
12068    let sz = printf("%.1f",a:sz/1024.0)."K"
12069   else
12070    let sz= a:sz
12071   endif
12072
12073  else
12074   let sz= a:sz
12075  endif
12076
12077"  call Dret("s:NetrwHumanReadable ".sz)
12078  return sz
12079endfun
12080
12081" ---------------------------------------------------------------------
12082" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
12083"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
12084fun! s:NetrwRestoreWordPosn()
12085"  call Dfunc("NetrwRestoreWordPosn()")
12086  sil! call search(s:netrw_saveword,'w')
12087"  call Dret("NetrwRestoreWordPosn")
12088endfun
12089
12090" ---------------------------------------------------------------------
12091" s:RestoreBufVars: {{{2
12092fun! s:RestoreBufVars()
12093"  call Dfunc("s:RestoreBufVars()")
12094
12095  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
12096  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
12097  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
12098  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
12099  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
12100  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
12101
12102"  call Dret("s:RestoreBufVars")
12103endfun
12104
12105" ---------------------------------------------------------------------
12106" s:RemotePathAnalysis: {{{2
12107fun! s:RemotePathAnalysis(dirname)
12108"  call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
12109
12110  "                method   ://    user  @      machine      :port            /path
12111  let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
12112  let s:method  = substitute(a:dirname,dirpat,'\1','')
12113  let s:user    = substitute(a:dirname,dirpat,'\3','')
12114  let s:machine = substitute(a:dirname,dirpat,'\4','')
12115  let s:port    = substitute(a:dirname,dirpat,'\5','')
12116  let s:path    = substitute(a:dirname,dirpat,'\6','')
12117  let s:fname   = substitute(s:path,'^.*/\ze.','','')
12118  if s:machine =~ '@'
12119   let dirpat    = '^\(.*\)@\(.\{-}\)$'
12120   let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')
12121   let s:machine = substitute(s:machine,dirpat,'\2','')
12122  endif
12123
12124"  call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
12125"  call Decho("set up s:user   <".s:user   .">",'~'.expand("<slnum>"))
12126"  call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
12127"  call Decho("set up s:port   <".s:port.">",'~'.expand("<slnum>"))
12128"  call Decho("set up s:path   <".s:path   .">",'~'.expand("<slnum>"))
12129"  call Decho("set up s:fname  <".s:fname  .">",'~'.expand("<slnum>"))
12130
12131"  call Dret("s:RemotePathAnalysis")
12132endfun
12133
12134" ---------------------------------------------------------------------
12135" s:RemoteSystem: runs a command on a remote host using ssh {{{2
12136"                 Returns status
12137" Runs system() on
12138"    [cd REMOTEDIRPATH;] a:cmd
12139" Note that it doesn't do s:ShellEscape(a:cmd)!
12140fun! s:RemoteSystem(cmd)
12141"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
12142  if !executable(g:netrw_ssh_cmd)
12143   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
12144  elseif !exists("b:netrw_curdir")
12145   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
12146  else
12147   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
12148   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
12149   if remotedir != ""
12150    let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
12151   else
12152    let cmd= cmd.' '
12153   endif
12154   let cmd= cmd.a:cmd
12155"   call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
12156   let ret= system(cmd)
12157  endif
12158"  call Dret("s:RemoteSystem ".ret)
12159  return ret
12160endfun
12161
12162" ---------------------------------------------------------------------
12163" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
12164fun! s:RestoreWinVars()
12165"  call Dfunc("s:RestoreWinVars()")
12166  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
12167  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
12168  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
12169  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
12170  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
12171  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
12172  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
12173  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
12174  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
12175  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
12176  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
12177  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
12178  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
12179  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
12180  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
12181  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
12182  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
12183  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
12184"  call Dret("s:RestoreWinVars")
12185endfun
12186
12187" ---------------------------------------------------------------------
12188" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
12189"
12190"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
12191"             is true) and a command, :Rexplore, which call this function.
12192"
12193"             s:netrw_posn is set up by s:NetrwBrowseChgDir()
12194"
12195"             s:rexposn_BUFNR used to save/restore cursor position
12196fun! s:NetrwRexplore(islocal,dirname)
12197  if exists("s:netrwdrag")
12198   return
12199  endif
12200"  call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
12201"  call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
12202"  call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
12203
12204  if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
12205   " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
12206"   call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
12207   exe "NetrwKeepj e ".w:netrw_rexfile
12208   unlet w:netrw_rexfile
12209"   call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%").">  (ft=".&ft.")")
12210   return
12211"  else " Decho
12212"   call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
12213"   call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
12214  endif
12215
12216  " ---------------------------
12217  " :Rex issued while in a file
12218  " ---------------------------
12219
12220  " record current file so :Rex can return to it from netrw
12221  let w:netrw_rexfile= expand("%")
12222"  call Decho("set w:netrw_rexfile<".w:netrw_rexfile.">  (win#".winnr().")",'~'.expand("<slnum>"))
12223
12224  if !exists("w:netrw_rexlocal")
12225"   call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
12226   return
12227  endif
12228"  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>"))
12229  if w:netrw_rexlocal
12230   NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
12231  else
12232   NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
12233  endif
12234  if exists("s:initbeval")
12235   setl beval
12236  endif
12237  if exists("s:rexposn_".bufnr("%"))
12238"   call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
12239   " restore position in directory listing
12240"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
12241   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
12242   if exists("s:rexposn_".bufnr('%'))
12243    unlet s:rexposn_{bufnr('%')}
12244   endif
12245  else
12246"   call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
12247  endif
12248
12249  if has("syntax") && exists("g:syntax_on") && g:syntax_on
12250   if exists("s:explore_match")
12251    exe "2match netrwMarkFile /".s:explore_match."/"
12252   endif
12253  endif
12254
12255"  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>"))
12256"  call Dret("s:NetrwRexplore : ft=".&ft)
12257endfun
12258
12259" ---------------------------------------------------------------------
12260" s:SaveBufVars: save selected b: variables to s: variables {{{2
12261"                use s:RestoreBufVars() to restore b: variables from s: variables
12262fun! s:SaveBufVars()
12263"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
12264
12265  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
12266  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
12267  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
12268  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
12269  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
12270  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
12271
12272"  call Dret("s:SaveBufVars")
12273endfun
12274
12275" ---------------------------------------------------------------------
12276" s:SavePosn: saves position associated with current buffer into a dictionary {{{2
12277fun! s:SavePosn(posndict)
12278"  call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12279
12280  if !exists("a:posndict[bufnr('%')]")
12281   let a:posndict[bufnr("%")]= []
12282  endif
12283"  call Decho("before push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12284  call add(a:posndict[bufnr("%")],winsaveview())
12285"  call Decho("after  push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12286
12287"  call Dret("s:SavePosn posndict")
12288  return a:posndict
12289endfun
12290
12291" ---------------------------------------------------------------------
12292" s:RestorePosn: restores position associated with current buffer using dictionary {{{2
12293fun! s:RestorePosn(posndict)
12294"  call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12295  if exists("a:posndict")
12296   if has_key(a:posndict,bufnr("%"))
12297"    call Decho("before pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12298    let posnlen= len(a:posndict[bufnr("%")])
12299    if posnlen > 0
12300     let posnlen= posnlen - 1
12301"     call Decho("restoring posn posndict[".bufnr("%")."][".posnlen."]=".string(a:posndict[bufnr("%")][posnlen]),'~'.expand("<slnum>"))
12302     call winrestview(a:posndict[bufnr("%")][posnlen])
12303     call remove(a:posndict[bufnr("%")],posnlen)
12304"     call Decho("after  pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12305    endif
12306   endif
12307  endif
12308"  call Dret("s:RestorePosn")
12309endfun
12310
12311" ---------------------------------------------------------------------
12312" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
12313fun! s:SaveWinVars()
12314"  call Dfunc("s:SaveWinVars() win#".winnr())
12315  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
12316  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
12317  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
12318  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
12319  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
12320  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
12321  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
12322  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
12323  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
12324  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
12325  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
12326  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
12327  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
12328  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
12329  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
12330  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
12331  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
12332  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
12333"  call Dret("s:SaveWinVars")
12334endfun
12335
12336" ---------------------------------------------------------------------
12337" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
12338"   To allow separate windows to have their own activities, such as
12339"   Explore **/pattern, several variables have been made window-oriented.
12340"   However, when the user splits a browser window (ex: ctrl-w s), these
12341"   variables are not inherited by the new window.  SetBufWinVars() and
12342"   UseBufWinVars() get around that.
12343fun! s:SetBufWinVars()
12344"  call Dfunc("s:SetBufWinVars() win#".winnr())
12345  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
12346  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
12347  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
12348  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
12349  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
12350  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
12351  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
12352  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
12353  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
12354  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
12355"  call Dret("s:SetBufWinVars")
12356endfun
12357
12358" ---------------------------------------------------------------------
12359" s:SetRexDir: set directory for :Rexplore {{{2
12360fun! s:SetRexDir(islocal,dirname)
12361"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
12362  let w:netrw_rexdir         = a:dirname
12363  let w:netrw_rexlocal       = a:islocal
12364  let s:rexposn_{bufnr("%")} = winsaveview()
12365"  call Decho("setting w:netrw_rexdir  =".w:netrw_rexdir,'~'.expand("<slnum>"))
12366"  call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>"))
12367"  call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
12368"  call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>"))
12369"  call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
12370endfun
12371
12372" ---------------------------------------------------------------------
12373" s:ShowLink: used to modify thin and tree listings to show links {{{2
12374fun! s:ShowLink()
12375" "  call Dfunc("s:ShowLink()")
12376" "  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
12377" "  call Decho(printf("line#%4d: %s",line("."),getline(".")),'~'.expand("<slnum>"))
12378  if exists("b:netrw_curdir")
12379   norm! $?\a
12380   let fname   = b:netrw_curdir.'/'.s:NetrwGetWord()
12381   let resname = resolve(fname)
12382" "   call Decho("fname         <".fname.">",'~'.expand("<slnum>"))
12383" "   call Decho("resname       <".resname.">",'~'.expand("<slnum>"))
12384" "   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
12385   if resname =~ '^\M'.b:netrw_curdir.'/'
12386    let dirlen  = strlen(b:netrw_curdir)
12387    let resname = strpart(resname,dirlen+1)
12388" "    call Decho("resname<".resname.">  (b:netrw_curdir elided)",'~'.expand("<slnum>"))
12389   endif
12390   let modline = getline(".")."\t --> ".resname
12391" "   call Decho("fname  <".fname.">",'~'.expand("<slnum>"))
12392" "   call Decho("modline<".modline.">",'~'.expand("<slnum>"))
12393   setl noro ma
12394   call setline(".",modline)
12395   setl ro noma nomod
12396  endif
12397" "  call Dret("s:ShowLink".((exists("fname")? ' : '.fname : 'n/a')))
12398endfun
12399
12400" ---------------------------------------------------------------------
12401" s:ShowStyle: {{{2
12402fun! s:ShowStyle()
12403  if !exists("w:netrw_liststyle")
12404   let liststyle= g:netrw_liststyle
12405  else
12406   let liststyle= w:netrw_liststyle
12407  endif
12408  if     liststyle == s:THINLIST
12409   return s:THINLIST.":thin"
12410  elseif liststyle == s:LONGLIST
12411   return s:LONGLIST.":long"
12412  elseif liststyle == s:WIDELIST
12413   return s:WIDELIST.":wide"
12414  elseif liststyle == s:TREELIST
12415   return s:TREELIST.":tree"
12416  else
12417   return 'n/a'
12418  endif
12419endfun
12420
12421" ---------------------------------------------------------------------
12422" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
12423"           Solution from Nicolai Weibull, vim docs (:help strlen()),
12424"           Tony Mechelynck, and my own invention.
12425fun! s:Strlen(x)
12426"  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
12427
12428  if v:version >= 703 && exists("*strdisplaywidth")
12429   let ret= strdisplaywidth(a:x)
12430
12431  elseif type(g:Align_xstrlen) == 1
12432   " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
12433   exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
12434
12435  elseif g:Align_xstrlen == 1
12436   " number of codepoints (Latin a + combining circumflex is two codepoints)
12437   " (comment from TM, solution from NW)
12438   let ret= strlen(substitute(a:x,'.','c','g'))
12439
12440  elseif g:Align_xstrlen == 2
12441   " number of spacing codepoints (Latin a + combining circumflex is one spacing
12442   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
12443   " (comment from TM, solution from TM)
12444   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
12445
12446  elseif g:Align_xstrlen == 3
12447   " virtual length (counting, for instance, tabs as anything between 1 and
12448   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
12449   " preceded by lam, one otherwise, etc.)
12450   " (comment from TM, solution from me)
12451   let modkeep= &l:mod
12452   exe "norm! o\<esc>"
12453   call setline(line("."),a:x)
12454   let ret= virtcol("$") - 1
12455   d
12456   NetrwKeepj norm! k
12457   let &l:mod= modkeep
12458
12459  else
12460   " at least give a decent default
12461    let ret= strlen(a:x)
12462  endif
12463"  "" call Dret("s:Strlen ".ret)
12464  return ret
12465endfun
12466
12467" ---------------------------------------------------------------------
12468" s:ShellEscape: shellescape(), or special windows handling {{{2
12469fun! s:ShellEscape(s, ...)
12470  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
12471    return printf('"%s"', substitute(a:s, '"', '""', 'g'))
12472  endif
12473  let f = a:0 > 0 ? a:1 : 0
12474  return shellescape(a:s, f)
12475endfun
12476
12477" ---------------------------------------------------------------------
12478" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
12479fun! s:TreeListMove(dir)
12480"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
12481  let curline      = getline('.')
12482  let prvline      = (line(".") > 1)?         getline(line(".")-1) : ''
12483  let nxtline      = (line(".") < line("$"))? getline(line(".")+1) : ''
12484  let curindent    = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
12485  let indentm1     = substitute(curindent,'^'.s:treedepthstring,'','')
12486  let treedepthchr = substitute(s:treedepthstring,' ','','g')
12487  let stopline     = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
12488"  call Decho("prvline  <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
12489"  call Decho("curline  <".curline."> #".line(".")    , '~'.expand("<slnum>"))
12490"  call Decho("nxtline  <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
12491"  call Decho("curindent<".curindent.">"              , '~'.expand("<slnum>"))
12492"  call Decho("indentm1 <".indentm1.">"               , '~'.expand("<slnum>"))
12493  "  COMBAK : need to handle when on a directory
12494  "  COMBAK : need to handle ]] and ][.  In general, needs work!!!
12495  if curline !~ '/$'
12496   if     a:dir == '[[' && prvline != ''
12497    NetrwKeepj norm! 0
12498    let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
12499"    call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
12500   elseif a:dir == '[]' && nxtline != ''
12501    NetrwKeepj norm! 0
12502"    call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>"))
12503    let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
12504    if nl != 0
12505     NetrwKeepj norm! k
12506    else
12507     NetrwKeepj norm! G
12508    endif
12509"    call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
12510   endif
12511  endif
12512
12513"  call Dret("s:TreeListMove")
12514endfun
12515
12516" ---------------------------------------------------------------------
12517" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
12518"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
12519"                      can't be called except via emenu.  But due to locale, that menu line may not be called
12520"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
12521fun! s:UpdateBuffersMenu()
12522"  call Dfunc("s:UpdateBuffersMenu()")
12523  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
12524   try
12525    sil emenu Buffers.Refresh\ menu
12526   catch /^Vim\%((\a\+)\)\=:E/
12527    let v:errmsg= ""
12528    sil NetrwKeepj call s:NetrwBMShow()
12529   endtry
12530  endif
12531"  call Dret("s:UpdateBuffersMenu")
12532endfun
12533
12534" ---------------------------------------------------------------------
12535" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
12536"              Matching function to s:SetBufWinVars()
12537fun! s:UseBufWinVars()
12538"  call Dfunc("s:UseBufWinVars()")
12539  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
12540  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
12541  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
12542  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
12543  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
12544  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
12545  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
12546  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
12547  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
12548  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
12549"  call Dret("s:UseBufWinVars")
12550endfun
12551
12552" ---------------------------------------------------------------------
12553" s:UserMaps: supports user-defined UserMaps {{{2
12554"               * calls a user-supplied funcref(islocal,curdir)
12555"               * interprets result
12556"             See netrw#UserMaps()
12557fun! s:UserMaps(islocal,funcname)
12558"  call Dfunc("s:UserMaps(islocal=".a:islocal.",funcname<".a:funcname.">)")
12559
12560  if !exists("b:netrw_curdir")
12561   let b:netrw_curdir= getcwd()
12562  endif
12563  let Funcref = function(a:funcname)
12564  let result  = Funcref(a:islocal)
12565
12566  if     type(result) == 1
12567   " if result from user's funcref is a string...
12568"   call Decho("result string from user funcref<".result.">",'~'.expand("<slnum>"))
12569   if result == "refresh"
12570"    call Decho("refreshing display",'~'.expand("<slnum>"))
12571    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12572   elseif result != ""
12573"    call Decho("executing result<".result.">",'~'.expand("<slnum>"))
12574    exe result
12575   endif
12576
12577  elseif type(result) == 3
12578   " if result from user's funcref is a List...
12579"   call Decho("result List from user funcref<".string(result).">",'~'.expand("<slnum>"))
12580   for action in result
12581    if action == "refresh"
12582"     call Decho("refreshing display",'~'.expand("<slnum>"))
12583     call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12584    elseif action != ""
12585"     call Decho("executing action<".action.">",'~'.expand("<slnum>"))
12586     exe action
12587    endif
12588   endfor
12589  endif
12590
12591"  call Dret("s:UserMaps")
12592endfun
12593
12594" ==========================
12595" Settings Restoration: {{{1
12596" ==========================
12597let &cpo= s:keepcpo
12598unlet s:keepcpo
12599
12600" ===============
12601" Modelines: {{{1
12602" ===============
12603" vim:ts=8 fdm=marker
12604