1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		Aug 16, 2021
4" Version:	171
5" Maintainer:	Charles E Campbell <NcampObell@SdrPchip.AorgM-NOSPAM>
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 = "v171"
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_atcursor(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_clipboard"   , 1)
326call s:NetrwInit("g:netrw_compress"    , "gzip")
327call s:NetrwInit("g:netrw_ctags"       , "ctags")
328if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
329 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
330 let g:netrw_cursor= g:netrw_cursorline
331endif
332call s:NetrwInit("g:netrw_cursor"      , 2)
333let s:netrw_usercul = &cursorline
334let s:netrw_usercuc = &cursorcolumn
335"call Decho("(netrw) COMBAK: cuc=".&l:cuc." cul=".&l:cul." initialization of s:netrw_cu[cl]")
336call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
337" Default values - d-g ---------- {{{3
338call s:NetrwInit("s:didstarstar",0)
339call s:NetrwInit("g:netrw_dirhistcnt"      , 0)
340call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }')
341call s:NetrwInit("g:netrw_dirhistmax"       , 10)
342call s:NetrwInit("g:netrw_errorlvl"  , s:NOTE)
343call s:NetrwInit("g:netrw_fastbrowse"       , 1)
344call 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$')
345if !exists("g:netrw_ftp_list_cmd")
346 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
347  let g:netrw_ftp_list_cmd     = "ls -lF"
348  let g:netrw_ftp_timelist_cmd = "ls -tlF"
349  let g:netrw_ftp_sizelist_cmd = "ls -slF"
350 else
351  let g:netrw_ftp_list_cmd     = "dir"
352  let g:netrw_ftp_timelist_cmd = "dir"
353  let g:netrw_ftp_sizelist_cmd = "dir"
354 endif
355endif
356call s:NetrwInit("g:netrw_ftpmode",'binary')
357" Default values - h-lh ---------- {{{3
358call s:NetrwInit("g:netrw_hide",1)
359if !exists("g:netrw_ignorenetrc")
360 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
361  let g:netrw_ignorenetrc= 1
362 else
363  let g:netrw_ignorenetrc= 0
364 endif
365endif
366call s:NetrwInit("g:netrw_keepdir",1)
367if !exists("g:netrw_list_cmd")
368 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
369  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
370   " provide a pscp-based listing command
371   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
372  endif
373  if exists("g:netrw_list_cmd_options")
374   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
375  else
376   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
377  endif
378 elseif executable(g:netrw_ssh_cmd)
379  " provide a scp-based default listing command
380  if exists("g:netrw_list_cmd_options")
381   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
382  else
383   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
384  endif
385 else
386"  call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
387  let g:netrw_list_cmd= ""
388 endif
389endif
390call s:NetrwInit("g:netrw_list_hide","")
391" Default values - lh-lz ---------- {{{3
392if exists("g:netrw_local_copycmd")
393 let g:netrw_localcopycmd= g:netrw_local_copycmd
394 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_copycmd is deprecated in favor of g:netrw_localcopycmd",84)
395endif
396if !exists("g:netrw_localcmdshell")
397 let g:netrw_localcmdshell= ""
398endif
399if !exists("g:netrw_localcopycmd")
400 if has("win32") || has("win95") || has("win64") || has("win16")
401  if g:netrw_cygwin
402   let g:netrw_localcopycmd= "cp"
403  else
404   let g:netrw_localcopycmd   = expand("$COMSPEC")
405   let g:netrw_localcopycmdopt= " /c copy"
406  endif
407 elseif has("unix") || has("macunix")
408  let g:netrw_localcopycmd= "cp"
409 else
410  let g:netrw_localcopycmd= ""
411 endif
412endif
413if !exists("g:netrw_localcopydircmd")
414 if has("win32") || has("win95") || has("win64") || has("win16")
415  if g:netrw_cygwin
416   let g:netrw_localcopydircmd   = "cp"
417   let g:netrw_localcopydircmdopt= " -R"
418  else
419   let g:netrw_localcopydircmd   = expand("$COMSPEC")
420   let g:netrw_localcopydircmdopt= " /c xcopy /e /c /h /i /k"
421  endif
422 elseif has("unix")
423  let g:netrw_localcopydircmd   = "cp"
424  let g:netrw_localcopydircmdopt= " -R"
425 elseif has("macunix")
426  let g:netrw_localcopydircmd   = "cp"
427  let g:netrw_localcopydircmdopt= " -R"
428 else
429  let g:netrw_localcopydircmd= ""
430 endif
431endif
432if exists("g:netrw_local_mkdir")
433 let g:netrw_localmkdir= g:netrw_local_mkdir
434 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
435endif
436if has("win32") || has("win95") || has("win64") || has("win16")
437  if g:netrw_cygwin
438   call s:NetrwInit("g:netrw_localmkdir","mkdir")
439  else
440   let g:netrw_localmkdir   = expand("$COMSPEC")
441   let g:netrw_localmkdiropt= " /c mkdir"
442  endif
443else
444 call s:NetrwInit("g:netrw_localmkdir","mkdir")
445endif
446call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
447if exists("g:netrw_local_movecmd")
448 let g:netrw_localmovecmd= g:netrw_local_movecmd
449 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
450endif
451if !exists("g:netrw_localmovecmd")
452 if has("win32") || has("win95") || has("win64") || has("win16")
453  if g:netrw_cygwin
454   let g:netrw_localmovecmd= "mv"
455  else
456   let g:netrw_localmovecmd   = expand("$COMSPEC")
457   let g:netrw_localmovecmdopt= " /c move"
458  endif
459 elseif has("unix") || has("macunix")
460  let g:netrw_localmovecmd= "mv"
461 else
462  let g:netrw_localmovecmd= ""
463 endif
464endif
465" following serves as an example for how to insert a version&patch specific test
466"if v:version < 704 || (v:version == 704 && !has("patch1107"))
467"endif
468call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
469" sanity checks
470if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
471 let g:netrw_liststyle= s:THINLIST
472endif
473if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
474 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
475endif
476" Default values - m-r ---------- {{{3
477call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
478call s:NetrwInit("g:netrw_maxfilenamelen", 32)
479call s:NetrwInit("g:netrw_menu"          , 1)
480call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
481call s:NetrwInit("g:netrw_mousemaps"     , (exists("+mouse") && &mouse =~# '[anh]'))
482call s:NetrwInit("g:netrw_retmap"        , 0)
483if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
484 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
485elseif has("win32") || has("win95") || has("win64") || has("win16")
486 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
487else
488 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
489endif
490call s:NetrwInit("g:netrw_preview"       , 0)
491call s:NetrwInit("g:netrw_scpport"       , "-P")
492call s:NetrwInit("g:netrw_servername"    , "NETRWSERVER")
493call s:NetrwInit("g:netrw_sshport"       , "-p")
494call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
495call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
496call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
497call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
498" Default values - q-s ---------- {{{3
499call s:NetrwInit("g:netrw_quickhelp",0)
500let s:QuickHelp= ["-:go up dir  D:delete  R:rename  s:sort-by  x:special",
501   \              "(create new)  %:file  d:directory",
502   \              "(windows split&open) o:horz  v:vert  p:preview",
503   \              "i:style  qf:file info  O:obtain  r:reverse",
504   \              "(marks)  mf:mark file  mt:set target  mm:move  mc:copy",
505   \              "(bookmarks)  mb:make  mB:delete  qb:list  gb:go to",
506   \              "(history)  qb:list  u:go up  U:go down",
507   \              "(targets)  mt:target Tb:use bookmark  Th:use history"]
508" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
509call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
510if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
511 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
512else
513 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
514endif
515call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
516call s:NetrwInit("g:netrw_sort_options"  , "")
517call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
518if !exists("g:netrw_sort_sequence")
519 if has("unix")
520  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
521 else
522  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
523 endif
524endif
525call s:NetrwInit("g:netrw_special_syntax"   , 0)
526call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
527call s:NetrwInit("g:netrw_suppress_gx_mesg",  1)
528call s:NetrwInit("g:netrw_use_noswf"        , 1)
529call s:NetrwInit("g:netrw_sizestyle"        ,"b")
530" Default values - t-w ---------- {{{3
531call s:NetrwInit("g:netrw_timefmt","%c")
532if !exists("g:netrw_xstrlen")
533 if exists("g:Align_xstrlen")
534  let g:netrw_xstrlen= g:Align_xstrlen
535 elseif exists("g:drawit_xstrlen")
536  let g:netrw_xstrlen= g:drawit_xstrlen
537 elseif &enc == "latin1" || !has("multi_byte")
538  let g:netrw_xstrlen= 0
539 else
540  let g:netrw_xstrlen= 1
541 endif
542endif
543call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
544call s:NetrwInit("g:netrw_win95ftp",1)
545call s:NetrwInit("g:netrw_winsize",50)
546call s:NetrwInit("g:netrw_wiw",1)
547if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
548" ---------------------------------------------------------------------
549" Default values for netrw's script variables: {{{2
550call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
551if has("win32") || has("win95") || has("win64") || has("win16")
552 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
553else
554 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
555endif
556call s:NetrwInit("g:netrw_menu_escape",'.&? \')
557call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
558call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
559if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
560 let s:treedepthstring= "│ "
561else
562 let s:treedepthstring= "| "
563endif
564call s:NetrwInit("s:netrw_posn",'{}')
565
566" BufEnter event ignored by decho when following variable is true
567"  Has a side effect that doau BufReadPost doesn't work, so
568"  files read by network transfer aren't appropriately highlighted.
569"let g:decho_bufenter = 1	"Decho
570
571" ======================
572"  Netrw Initialization: {{{1
573" ======================
574if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
575" call Decho("installed beval events",'~'.expand("<slnum>"))
576 let &l:bexpr = "netrw#BalloonHelp()"
577" call Decho("&l:bexpr<".&l:bexpr."> buf#".bufnr())
578 au FileType netrw	setl beval
579 au WinLeave *		if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
580 au VimEnter * 		let s:initbeval= &beval
581"else " Decho
582" if v:version < 700           | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>"))     | endif
583" if !has("balloon_eval")      | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>"))        | endif
584" if exists("s:initbeval")     | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>"))                | endif
585" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>"))            | endif
586" if !has("syntax")            | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
587" if exists("g:syntax_on")     | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>"))                | endif
588endif
589au WinEnter *	if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
590
591if g:netrw_keepj =~# "keepj"
592 com! -nargs=*	NetrwKeepj	keepj <args>
593else
594 let g:netrw_keepj= ""
595 com! -nargs=*	NetrwKeepj	<args>
596endif
597
598" ==============================
599"  Netrw Utility Functions: {{{1
600" ==============================
601
602" ---------------------------------------------------------------------
603" netrw#BalloonHelp: {{{2
604if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
605" call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
606 fun! netrw#BalloonHelp()
607   if &ft != "netrw"
608    return ""
609   endif
610   if exists("s:popuperr_id") && popup_getpos(s:popuperr_id) != {}
611    " popup error window is still showing
612    " s:pouperr_id and s:popuperr_text are set up in netrw#ErrorMsg()
613    if exists("s:popuperr_text") && s:popuperr_text != "" && v:beval_text != s:popuperr_text
614     " text under mouse hasn't changed; only close window when it changes
615     call popup_close(s:popuperr_id)
616     unlet s:popuperr_text
617    else
618     let s:popuperr_text= v:beval_text
619    endif
620    let mesg= ""
621   elseif !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
622    let mesg= ""
623   elseif     v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
624    let mesg = "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
625   elseif     getline(v:beval_lnum) =~ '^"\s*/'
626    let mesg = "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
627   elseif     v:beval_text == "Sorted" || v:beval_text == "by"
628    let mesg = 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
629   elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
630    let mesg = "S: edit sorting sequence"
631   elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
632    let mesg = "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
633   elseif v:beval_text == "Quick" || v:beval_text == "Help"
634    let mesg = "Help: press <F1>"
635   elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
636    let mesg = "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
637   else
638    let mesg= ""
639   endif
640   return mesg
641 endfun
642"else " Decho
643" if v:version < 700            |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
644" if !has("balloon_eval")       |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>"))       |endif
645" if !has("syntax")             |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>"))                  |endif
646" if !exists("g:syntax_on")     |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>"))                  |endif
647" if  exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>"))           |endif
648endif
649
650" ------------------------------------------------------------------------
651" netrw#Explore: launch the local browser in the directory of the current file {{{2
652"          indx:  == -1: Nexplore
653"                 == -2: Pexplore
654"                 ==  +: this is overloaded:
655"                      * If Nexplore/Pexplore is in use, then this refers to the
656"                        indx'th item in the w:netrw_explore_list[] of items which
657"                        matched the */pattern **/pattern *//pattern **//pattern
658"                      * If Hexplore or Vexplore, then this will override
659"                        g:netrw_winsize to specify the qty of rows or columns the
660"                        newly split window should have.
661"          dosplit==0: the window will be split iff the current file has been modified and hidden not set
662"          dosplit==1: the window will be split before running the local browser
663"          style == 0: Explore     style == 1: Explore!
664"                == 2: Hexplore    style == 3: Hexplore!
665"                == 4: Vexplore    style == 5: Vexplore!
666"                == 6: Texplore
667fun! netrw#Explore(indx,dosplit,style,...)
668"  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)
669"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
670  if !exists("b:netrw_curdir")
671   let b:netrw_curdir= getcwd()
672"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
673  endif
674
675  " record current file for Rexplore's benefit
676  if &ft != "netrw"
677   let w:netrw_rexfile= expand("%:p")
678  endif
679
680  " record current directory
681  let curdir     = simplify(b:netrw_curdir)
682  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
683  if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
684   let curdir= substitute(curdir,'\','/','g')
685  endif
686"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">",'~'.expand("<slnum>"))
687
688  " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
689  " will end up with backslashes here.  Solution: strip off backslashes that precede white space and
690  " try Explore again.
691  if a:0 > 0
692"   call Decho('considering retry: a:1<'.a:1.'>: '.
693     \ ((a:1 =~ "\\\s")?                   'has backslash whitespace' : 'does not have backslash whitespace').', '.
694     \ ((filereadable(s:NetrwFile(a:1)))?  'is readable'              : 'is not readable').', '.
695     \ ((isdirectory(s:NetrwFile(a:1))))?  'is a directory'           : 'is not a directory',
696     \ '~'.expand("<slnum>"))
697   if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
698"    call Decho("re-trying Explore with <".substitute(a:1,'\\\(\s\)','\1','g').">",'~'.expand("<slnum>"))
699    call netrw#Explore(a:indx,a:dosplit,a:style,substitute(a:1,'\\\(\s\)','\1','g'))
700"    call Dret("netrw#Explore : returning from retry")
701    return
702"   else " Decho
703"    call Decho("retry not needed",'~'.expand("<slnum>"))
704   endif
705  endif
706
707  " save registers
708  sil! let keepregslash= @/
709
710  " if   dosplit
711  " -or- file has been modified AND file not hidden when abandoned
712  " -or- Texplore used
713  if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
714"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified",'~'.expand("<slnum>"))
715   call s:SaveWinVars()
716   let winsz= g:netrw_winsize
717   if a:indx > 0
718    let winsz= a:indx
719   endif
720
721   if a:style == 0      " Explore, Sexplore
722"    call Decho("style=0: Explore or Sexplore",'~'.expand("<slnum>"))
723    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
724    if winsz == 0|let winsz= ""|endif
725    exe "noswapfile ".winsz."wincmd s"
726"    call Decho("exe noswapfile ".winsz."wincmd s",'~'.expand("<slnum>"))
727
728   elseif a:style == 1  "Explore!, Sexplore!
729"    call Decho("style=1: Explore! or Sexplore!",'~'.expand("<slnum>"))
730    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
731    if winsz == 0|let winsz= ""|endif
732    exe "keepalt noswapfile ".winsz."wincmd v"
733"    call Decho("exe keepalt noswapfile ".winsz."wincmd v",'~'.expand("<slnum>"))
734
735   elseif a:style == 2  " Hexplore
736"    call Decho("style=2: Hexplore",'~'.expand("<slnum>"))
737    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
738    if winsz == 0|let winsz= ""|endif
739    exe "keepalt noswapfile bel ".winsz."wincmd s"
740"    call Decho("exe keepalt noswapfile bel ".winsz."wincmd s",'~'.expand("<slnum>"))
741
742   elseif a:style == 3  " Hexplore!
743"    call Decho("style=3: Hexplore!",'~'.expand("<slnum>"))
744    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
745    if winsz == 0|let winsz= ""|endif
746    exe "keepalt noswapfile abo ".winsz."wincmd s"
747"    call Decho("exe keepalt noswapfile abo ".winsz."wincmd s",'~'.expand("<slnum>"))
748
749   elseif a:style == 4  " Vexplore
750"    call Decho("style=4: Vexplore",'~'.expand("<slnum>"))
751    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
752    if winsz == 0|let winsz= ""|endif
753    exe "keepalt noswapfile lefta ".winsz."wincmd v"
754"    call Decho("exe keepalt noswapfile lefta ".winsz."wincmd v",'~'.expand("<slnum>"))
755
756   elseif a:style == 5  " Vexplore!
757"    call Decho("style=5: Vexplore!",'~'.expand("<slnum>"))
758    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
759    if winsz == 0|let winsz= ""|endif
760    exe "keepalt noswapfile rightb ".winsz."wincmd v"
761"    call Decho("exe keepalt noswapfile rightb ".winsz."wincmd v",'~'.expand("<slnum>"))
762
763   elseif a:style == 6  " Texplore
764    call s:SaveBufVars()
765"    call Decho("style  = 6: Texplore",'~'.expand("<slnum>"))
766    exe "keepalt tabnew ".fnameescape(curdir)
767"    call Decho("exe keepalt tabnew ".fnameescape(curdir),'~'.expand("<slnum>"))
768    call s:RestoreBufVars()
769   endif
770   call s:RestoreWinVars()
771"  else " Decho
772"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6",'~'.expand("<slnum>"))
773  endif
774  NetrwKeepj norm! 0
775
776  if a:0 > 0
777"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">",'~'.expand("<slnum>"))
778   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
779"    call Decho("..case a:1<".a:1.">: starts with ~ and unix or cygwin",'~'.expand("<slnum>"))
780    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
781"    call Decho("..using dirname<".dirname.">  (case: ~ && unix||cygwin)",'~'.expand("<slnum>"))
782   elseif a:1 == '.'
783"    call Decho("..case a:1<".a:1.">: matches .",'~'.expand("<slnum>"))
784    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
785    if dirname !~ '/$'
786     let dirname= dirname."/"
787    endif
788"    call Decho("..using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")",'~'.expand("<slnum>"))
789   elseif a:1 =~ '\$'
790"    call Decho("..case a:1<".a:1.">: matches ending $",'~'.expand("<slnum>"))
791    let dirname= simplify(expand(a:1))
792"    call Decho("..using user-specified dirname<".dirname."> with $env-var",'~'.expand("<slnum>"))
793   elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
794"    call Decho("..case a:1<".a:1.">: other, not pattern or filepattern",'~'.expand("<slnum>"))
795    let dirname= simplify(a:1)
796"    call Decho("..using user-specified dirname<".dirname.">",'~'.expand("<slnum>"))
797   else
798"    call Decho("..case a:1: pattern or filepattern",'~'.expand("<slnum>"))
799    let dirname= a:1
800   endif
801  else
802   " clear explore
803"   call Decho("case a:0=".a:0.": clearing Explore list",'~'.expand("<slnum>"))
804   call s:NetrwClearExplore()
805"   call Dret("netrw#Explore : cleared list")
806   return
807  endif
808
809"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
810  if dirname =~ '\.\./\=$'
811   let dirname= simplify(fnamemodify(dirname,':p:h'))
812  elseif dirname =~ '\.\.' || dirname == '.'
813   let dirname= simplify(fnamemodify(dirname,':p'))
814  endif
815"  call Decho("dirname<".dirname.">  (after simplify)",'~'.expand("<slnum>"))
816
817  if dirname =~ '^\*//'
818   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
819"   call Decho("case starpat=1: Explore *//pattern",'~'.expand("<slnum>"))
820   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
821   let starpat= 1
822"   call Decho("..Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
823   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
824
825  elseif dirname =~ '^\*\*//'
826   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
827"   call Decho("case starpat=2: Explore **//pattern",'~'.expand("<slnum>"))
828   let pattern= substitute(dirname,'^\*\*//','','')
829   let starpat= 2
830"   call Decho("..Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
831
832  elseif dirname =~ '/\*\*/'
833   " handle .../**/.../filepat
834"   call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
835   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
836   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
837    let b:netrw_curdir = prefixdir
838   else
839    let b:netrw_curdir= getcwd().'/'.prefixdir
840   endif
841   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
842   let starpat= 4
843"   call Decho("..pwd<".getcwd()."> dirname<".dirname.">",'~'.expand("<slnum>"))
844"   call Decho("..case Explore ../**/../filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
845
846  elseif dirname =~ '^\*/'
847   " case starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
848   let starpat= 3
849"   call Decho("case starpat=3: Explore */filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
850
851  elseif dirname=~ '^\*\*/'
852   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
853   let starpat= 4
854"   call Decho("case starpat=4: Explore **/filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
855
856  else
857   let starpat= 0
858"   call Decho("case starpat=0: default",'~'.expand("<slnum>"))
859  endif
860
861  if starpat == 0 && a:indx >= 0
862   " [Explore Hexplore Vexplore Sexplore] [dirname]
863"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname.">, handles Explore Hexplore Vexplore Sexplore",'~'.expand("<slnum>"))
864   if dirname == ""
865    let dirname= curfiledir
866"    call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>"))
867   endif
868   if dirname =~# '^scp://' || dirname =~ '^ftp://'
869    call netrw#Nread(2,dirname)
870   else
871    if dirname == ""
872     let dirname= getcwd()
873    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
874     " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
875     " depending on whether backslashes have been converted to forward slashes by earlier code).
876     if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
877      let dirname= b:netrw_curdir."/".dirname
878     endif
879    elseif dirname !~ '^/'
880     let dirname= b:netrw_curdir."/".dirname
881    endif
882"    call Decho("..calling LocalBrowseCheck(dirname<".dirname.">)",'~'.expand("<slnum>"))
883    call netrw#LocalBrowseCheck(dirname)
884"    call Decho(" modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
885"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
886   endif
887   if exists("w:netrw_bannercnt")
888    " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
889    " If one wants to return the same place in the netrw window, use :Rex instead.
890    exe w:netrw_bannercnt
891   endif
892
893"   call Decho("curdir<".curdir.">",'~'.expand("<slnum>"))
894   " ---------------------------------------------------------------------
895   " Jan 24, 2013: not sure why the following was present.  See P08-Ingelrest
896"   if has("win32") || has("win95") || has("win64") || has("win16")
897"    NetrwKeepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
898"   else
899"    NetrwKeepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
900"   endif
901   " ---------------------------------------------------------------------
902
903  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
904  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
905  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
906  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
907  elseif a:indx <= 0
908   " Nexplore, Pexplore, Explore: handle starpat
909"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx,'~'.expand("<slnum>"))
910   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
911"    call Decho("..set up <s-up> and <s-down> maps",'~'.expand("<slnum>"))
912    let s:didstarstar= 1
913    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
914    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
915   endif
916
917   if has("path_extra")
918"    call Decho("..starpat=".starpat.": has +path_extra",'~'.expand("<slnum>"))
919    if !exists("w:netrw_explore_indx")
920     let w:netrw_explore_indx= 0
921    endif
922
923    let indx = a:indx
924"    call Decho("..starpat=".starpat.": set indx= [a:indx=".indx."]",'~'.expand("<slnum>"))
925
926    if indx == -1
927     " Nexplore
928"     call Decho("..case Nexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
929     if !exists("w:netrw_explore_list") " sanity check
930      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
931      sil! let @/ = keepregslash
932"      call Dret("netrw#Explore")
933      return
934     endif
935     let indx= w:netrw_explore_indx
936     if indx < 0                        | let indx= 0                           | endif
937     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
938     let curfile= w:netrw_explore_list[indx]
939"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
940     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
941      let indx= indx + 1
942"      call Decho("....indx=".indx." (Nexplore while loop)",'~'.expand("<slnum>"))
943     endwhile
944     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
945"     call Decho("....Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
946
947    elseif indx == -2
948     " Pexplore
949"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
950     if !exists("w:netrw_explore_list") " sanity check
951      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
952      sil! let @/ = keepregslash
953"      call Dret("netrw#Explore")
954      return
955     endif
956     let indx= w:netrw_explore_indx
957     if indx < 0                        | let indx= 0                           | endif
958     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
959     let curfile= w:netrw_explore_list[indx]
960"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
961     while indx >= 0 && curfile == w:netrw_explore_list[indx]
962      let indx= indx - 1
963"      call Decho("....indx=".indx." (Pexplore while loop)",'~'.expand("<slnum>"))
964     endwhile
965     if indx < 0                        | let indx= 0                           | endif
966"     call Decho("....Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
967
968    else
969     " Explore -- initialize
970     " build list of files to Explore with Nexplore/Pexplore
971"     call Decho("..starpat=".starpat.": case Explore: initialize (indx=".indx.")",'~'.expand("<slnum>"))
972     NetrwKeepj keepalt call s:NetrwClearExplore()
973     let w:netrw_explore_indx= 0
974     if !exists("b:netrw_curdir")
975      let b:netrw_curdir= getcwd()
976     endif
977"     call Decho("....starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
978
979     " switch on starpat to build the w:netrw_explore_list of files
980     if starpat == 1
981      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
982"      call Decho("..case starpat=".starpat.": build *//pattern list  (curdir-only srch for files containing pattern)  &hls=".&hls,'~'.expand("<slnum>"))
983"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
984      try
985       exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
986      catch /^Vim\%((\a\+)\)\=:E480/
987       keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
988"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
989       return
990      endtry
991      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
992      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
993
994     elseif starpat == 2
995      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
996"      call Decho("..case starpat=".starpat.": build **//pattern list  (recursive descent files containing pattern)",'~'.expand("<slnum>"))
997"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
998      try
999       exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
1000      catch /^Vim\%((\a\+)\)\=:E480/
1001       keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
1002       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1003       sil! let @/ = keepregslash
1004"       call Dret("netrw#Explore : no files matched pattern")
1005       return
1006      endtry
1007      let s:netrw_curdir       = b:netrw_curdir
1008      let w:netrw_explore_list = getqflist()
1009      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
1010      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1011
1012     elseif starpat == 3
1013      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
1014"      call Decho("..case starpat=".starpat.": build */filepat list  (curdir-only srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1015      let filepat= substitute(dirname,'^\*/','','')
1016      let filepat= substitute(filepat,'^[%#<]','\\&','')
1017"      call Decho("....b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
1018"      call Decho("....filepat<".filepat.">",'~'.expand("<slnum>"))
1019      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
1020      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
1021
1022     elseif starpat == 4
1023      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
1024"      call Decho("..case starpat=".starpat.": build **/filepat list  (recursive descent srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1025      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
1026      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
1027     endif " switch on starpat to build w:netrw_explore_list
1028
1029     let w:netrw_explore_listlen = len(w:netrw_explore_list)
1030"     call Decho("....w:netrw_explore_list<".string(w:netrw_explore_list).">",'~'.expand("<slnum>"))
1031"     call Decho("....w:netrw_explore_listlen=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1032
1033     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1034      keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1035      sil! let @/ = keepregslash
1036"      call Dret("netrw#Explore : no files matched")
1037      return
1038     endif
1039    endif  " if indx ... endif
1040
1041    " NetrwStatusLine support - for exploring support
1042    let w:netrw_explore_indx= indx
1043"    call Decho("....w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1044
1045    " wrap the indx around, but issue a note
1046    if indx >= w:netrw_explore_listlen || indx < 0
1047"     call Decho("....wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")",'~'.expand("<slnum>"))
1048     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1049     let w:netrw_explore_indx= indx
1050     keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
1051    endif
1052
1053    exe "let dirfile= w:netrw_explore_list[".indx."]"
1054"    call Decho("....dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">",'~'.expand("<slnum>"))
1055    let newdir= substitute(dirfile,'/[^/]*$','','e')
1056"    call Decho("....newdir<".newdir.">",'~'.expand("<slnum>"))
1057
1058"    call Decho("....calling LocalBrowseCheck(newdir<".newdir.">)",'~'.expand("<slnum>"))
1059    call netrw#LocalBrowseCheck(newdir)
1060    if !exists("w:netrw_liststyle")
1061     let w:netrw_liststyle= g:netrw_liststyle
1062    endif
1063    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1064     keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1065    else
1066     keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1067    endif
1068    let w:netrw_explore_mtchcnt = indx + 1
1069    let w:netrw_explore_bufnr   = bufnr("%")
1070    let w:netrw_explore_line    = line(".")
1071    keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
1072"    call Decho("....explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line,'~'.expand("<slnum>"))
1073
1074   else
1075"    call Decho("..your vim does not have +path_extra",'~'.expand("<slnum>"))
1076    if !exists("g:netrw_quiet")
1077     keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1078    endif
1079    sil! let @/ = keepregslash
1080"    call Dret("netrw#Explore : missing +path_extra")
1081    return
1082   endif
1083
1084  else
1085"   call Decho("..default case: Explore newdir<".dirname.">",'~'.expand("<slnum>"))
1086   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1087    sil! unlet w:netrw_treedict
1088    sil! unlet w:netrw_treetop
1089   endif
1090   let newdir= dirname
1091   if !exists("b:netrw_curdir")
1092    NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1093   else
1094    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
1095   endif
1096  endif
1097
1098  " visual display of **/ **// */ Exploration files
1099"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"),'~'.expand("<slnum>"))
1100"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">",'~'.expand("<slnum>"))
1101  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
1102"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"),'~'.expand("<slnum>"))
1103   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1104    " only update match list when current directory isn't the same as before
1105"    call Decho("only update match list when current directory not the same as before",'~'.expand("<slnum>"))
1106    let s:explore_prvdir = b:netrw_curdir
1107    let s:explore_match  = ""
1108    let dirlen           = strlen(b:netrw_curdir)
1109    if b:netrw_curdir !~ '/$'
1110     let dirlen= dirlen + 1
1111    endif
1112    let prvfname= ""
1113    for fname in w:netrw_explore_list
1114"     call Decho("fname<".fname.">",'~'.expand("<slnum>"))
1115     if fname =~ '^'.b:netrw_curdir
1116      if s:explore_match == ""
1117       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1118      else
1119       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1120      endif
1121     elseif fname !~ '^/' && fname != prvfname
1122      if s:explore_match == ""
1123       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1124      else
1125       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1126      endif
1127     endif
1128     let prvfname= fname
1129    endfor
1130"    call Decho("explore_match<".s:explore_match.">",'~'.expand("<slnum>"))
1131    if has("syntax") && exists("g:syntax_on") && g:syntax_on
1132     exe "2match netrwMarkFile /".s:explore_match."/"
1133    endif
1134   endif
1135   echo "<s-up>==Pexplore  <s-down>==Nexplore"
1136  else
1137   2match none
1138   if exists("s:explore_match")  | unlet s:explore_match  | endif
1139   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
1140   echo " "
1141"   call Decho("cleared explore match list",'~'.expand("<slnum>"))
1142  endif
1143
1144  " since Explore may be used to initialize netrw's browser,
1145  " there's no danger of a late FocusGained event on initialization.
1146  " Consequently, set s:netrw_events to 2.
1147  let s:netrw_events= 2
1148  sil! let @/ = keepregslash
1149"  call Dret("netrw#Explore : @/<".@/.">")
1150endfun
1151
1152" ---------------------------------------------------------------------
1153" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
1154fun! netrw#Lexplore(count,rightside,...)
1155"  call Dfunc("netrw#Lexplore(count=".a:count." rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
1156  let curwin= winnr()
1157
1158  if a:0 > 0 && a:1 != ""
1159   " if a netrw window is already on the left-side of the tab
1160   " and a directory has been specified, explore with that
1161   " directory.
1162"   call Decho("case has input argument(s) (a:1<".a:1.">)")
1163   let a1 = expand(a:1)
1164"   call Decho("a:1<".a:1.">  curwin#".curwin,'~'.expand("<slnum>"))
1165   exe "1wincmd w"
1166   if &ft == "netrw"
1167"    call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
1168    exe "Explore ".fnameescape(a1)
1169    exe curwin."wincmd w"
1170    if exists("t:netrw_lexposn")
1171"     call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
1172     unlet t:netrw_lexposn
1173    endif
1174"    call Dret("netrw#Lexplore")
1175    return
1176   endif
1177   exe curwin."wincmd w"
1178  else
1179   let a1= ""
1180"   call Decho("no input arguments")
1181  endif
1182
1183  if exists("t:netrw_lexbufnr")
1184   " check if t:netrw_lexbufnr refers to a netrw window
1185   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1186"   call Decho("lexwinnr= bufwinnr(t:netrw_lexbufnr#".t:netrw_lexbufnr.")=".lexwinnr)
1187  else
1188   let lexwinnr= 0
1189"   call Decho("t:netrw_lexbufnr doesn't exist")
1190  endif
1191"  call Decho("lexwinnr=".lexwinnr,'~'.expand("<slnum>"))
1192
1193  if lexwinnr > 0
1194   " close down netrw explorer window
1195"   call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
1196   exe lexwinnr."wincmd w"
1197   let g:netrw_winsize = -winwidth(0)
1198   let t:netrw_lexposn = winsaveview()
1199"   call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1200"   call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
1201   close
1202   if lexwinnr < curwin
1203    let curwin= curwin - 1
1204   endif
1205   if lexwinnr != curwin
1206    exe curwin."wincmd w"
1207   endif
1208   unlet t:netrw_lexbufnr
1209"   call Decho("unlet t:netrw_lexbufnr")
1210
1211  else
1212   " open netrw explorer window
1213"   call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
1214   exe "1wincmd w"
1215   let keep_altv    = g:netrw_altv
1216   let g:netrw_altv = 0
1217   if a:count != 0
1218    let netrw_winsize   = g:netrw_winsize
1219    let g:netrw_winsize = a:count
1220   endif
1221   let curfile= expand("%")
1222"   call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
1223   exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1224"   call Decho("new buf#".bufnr("%")." win#".winnr())
1225   if a:0 > 0 && a1 != ""
1226"    call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
1227    call netrw#Explore(0,0,0,a1)
1228    exe "Explore ".fnameescape(a1)
1229   elseif curfile =~ '^\a\{3,}://'
1230"    call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
1231    call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
1232   else
1233"    call Decho("case 3: Explore .",'~'.expand("<slnum>"))
1234    call netrw#Explore(0,0,0,".")
1235   endif
1236   if a:count != 0
1237    let g:netrw_winsize = netrw_winsize
1238   endif
1239   setlocal winfixwidth
1240   let g:netrw_altv     = keep_altv
1241   let t:netrw_lexbufnr = bufnr("%")
1242   " done to prevent build-up of hidden buffers due to quitting and re-invocation of :Lexplore.
1243   " Since the intended use of :Lexplore is to have an always-present explorer window, the extra
1244   " effort to mis-use :Lex is warranted.
1245   set bh=wipe
1246"   call Decho("let t:netrw_lexbufnr=".t:netrw_lexbufnr)
1247"   call Decho("t:netrw_lexposn".(exists("t:netrw_lexposn")? string(t:netrw_lexposn) : " n/a"))
1248   if exists("t:netrw_lexposn")
1249"    call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1250"    call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1251    call winrestview(t:netrw_lexposn)
1252    unlet t:netrw_lexposn
1253   endif
1254  endif
1255
1256  " set up default window for editing via <cr>
1257  if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
1258   if a:rightside
1259    let g:netrw_chgwin= 1
1260   else
1261    let g:netrw_chgwin= 2
1262   endif
1263"   call Decho("let g:netrw_chgwin=".g:netrw_chgwin)
1264  endif
1265
1266"  call Dret("netrw#Lexplore")
1267endfun
1268
1269" ---------------------------------------------------------------------
1270" netrw#Clean: remove netrw {{{2
1271" supports :NetrwClean  -- remove netrw from first directory on runtimepath
1272"          :NetrwClean! -- remove netrw from all directories on runtimepath
1273fun! netrw#Clean(sys)
1274"  call Dfunc("netrw#Clean(sys=".a:sys.")")
1275
1276  if a:sys
1277   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
1278  else
1279   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
1280  endif
1281"  call Decho("choice=".choice,'~'.expand("<slnum>"))
1282  let diddel= 0
1283  let diddir= ""
1284
1285  if choice == 1
1286   for dir in split(&rtp,',')
1287    if filereadable(dir."/plugin/netrwPlugin.vim")
1288"     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1289     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
1290     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1291     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
1292     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
1293     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
1294     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
1295     let diddir= dir
1296     let diddel= diddel + 1
1297     if !a:sys|break|endif
1298    endif
1299   endfor
1300  endif
1301
1302   echohl WarningMsg
1303  if diddel == 0
1304   echomsg "netrw is either not installed or not removable"
1305  elseif diddel == 1
1306   echomsg "removed one copy of netrw from <".diddir.">"
1307  else
1308   echomsg "removed ".diddel." copies of netrw"
1309  endif
1310   echohl None
1311
1312"  call Dret("netrw#Clean")
1313endfun
1314
1315" ---------------------------------------------------------------------
1316" netrw#MakeTgt: make a target out of the directory name provided {{{2
1317fun! netrw#MakeTgt(dname)
1318"  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1319   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
1320  let svpos               = winsaveview()
1321"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1322  let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
1323"  call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
1324  if s:netrwmftgt_islocal
1325   let netrwmftgt= simplify(a:dname)
1326  else
1327   let netrwmftgt= a:dname
1328  endif
1329  if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
1330   " re-selected target, so just clear it
1331   unlet s:netrwmftgt s:netrwmftgt_islocal
1332  else
1333   let s:netrwmftgt= netrwmftgt
1334  endif
1335  if g:netrw_fastbrowse <= 1
1336   call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
1337  endif
1338"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
1339  call winrestview(svpos)
1340"  call Dret("netrw#MakeTgt")
1341endfun
1342
1343" ---------------------------------------------------------------------
1344" netrw#Obtain: {{{2
1345"   netrw#Obtain(islocal,fname[,tgtdirectory])
1346"     islocal=0  obtain from remote source
1347"            =1  obtain from local source
1348"     fname  :   a filename or a list of filenames
1349"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
1350fun! netrw#Obtain(islocal,fname,...)
1351"  call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
1352  " NetrwStatusLine support - for obtaining support
1353
1354  if type(a:fname) == 1
1355   let fnamelist= [ a:fname ]
1356  elseif type(a:fname) == 3
1357   let fnamelist= a:fname
1358  else
1359   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1360"   call Dret("netrw#Obtain")
1361   return
1362  endif
1363"  call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
1364  if a:0 > 0
1365   let tgtdir= a:1
1366  else
1367   let tgtdir= getcwd()
1368  endif
1369"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
1370
1371  if exists("b:netrw_islocal") && b:netrw_islocal
1372   " obtain a file from local b:netrw_curdir to (local) tgtdir
1373"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1374   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1375    let topath= s:ComposePath(tgtdir,"")
1376    if (has("win32") || has("win95") || has("win64") || has("win16"))
1377     " transfer files one at time
1378"     call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1379     for fname in fnamelist
1380"      call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1381      call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1382      if v:shell_error != 0
1383       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1384"       call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1385       return
1386      endif
1387     endfor
1388    else
1389     " transfer files with one command
1390"     call Decho("transfer files with one command",'~'.expand("<slnum>"))
1391     let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1392"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1393     call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".filelist." ".s:ShellEscape(topath))
1394     if v:shell_error != 0
1395      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1396"      call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1397      return
1398     endif
1399    endif
1400   elseif !exists("b:netrw_curdir")
1401    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
1402   else
1403    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
1404   endif
1405
1406  else
1407   " obtain files from remote b:netrw_curdir to local tgtdir
1408"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1409   if type(a:fname) == 1
1410    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
1411   endif
1412   call s:NetrwMethod(b:netrw_curdir)
1413
1414   if b:netrw_method == 4
1415    " obtain file using scp
1416"    call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1417    if exists("g:netrw_port") && g:netrw_port != ""
1418     let useport= " ".g:netrw_scpport." ".g:netrw_port
1419    else
1420     let useport= ""
1421    endif
1422    if b:netrw_fname =~ '/'
1423     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1424    else
1425     let path= ""
1426    endif
1427    let filelist= join(map(deepcopy(fnamelist),'escape(s:ShellEscape(g:netrw_machine.":".path.v:val,1)," ")'))
1428    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
1429
1430   elseif b:netrw_method == 2
1431    " obtain file using ftp + .netrc
1432"     call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1433     call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1434     let tmpbufnr= bufnr("%")
1435     setl ff=unix
1436     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1437      NetrwKeepj put =g:netrw_ftpmode
1438"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1439     endif
1440
1441     if exists("b:netrw_fname") && b:netrw_fname != ""
1442      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1443"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1444     endif
1445
1446     if exists("g:netrw_ftpextracmd")
1447      NetrwKeepj put =g:netrw_ftpextracmd
1448"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1449     endif
1450     for fname in fnamelist
1451      call setline(line("$")+1,'get "'.fname.'"')
1452"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1453     endfor
1454     if exists("g:netrw_port") && g:netrw_port != ""
1455      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1456     else
1457      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1458     endif
1459     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1460     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1461      let debugkeep= &debug
1462      setl debug=msg
1463      call netrw#ErrorMsg(s:ERROR,getline(1),4)
1464      let &debug= debugkeep
1465     endif
1466
1467   elseif b:netrw_method == 3
1468    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1469"    call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1470    call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1471    let tmpbufnr= bufnr("%")
1472    setl ff=unix
1473
1474    if exists("g:netrw_port") && g:netrw_port != ""
1475     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1476"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1477    else
1478     NetrwKeepj put ='open '.g:netrw_machine
1479"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1480    endif
1481
1482    if exists("g:netrw_uid") && g:netrw_uid != ""
1483     if exists("g:netrw_ftp") && g:netrw_ftp == 1
1484      NetrwKeepj put =g:netrw_uid
1485"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1486      if exists("s:netrw_passwd") && s:netrw_passwd != ""
1487       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1488      endif
1489"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1490     elseif exists("s:netrw_passwd")
1491      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1492"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1493     endif
1494    endif
1495
1496    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1497     NetrwKeepj put =g:netrw_ftpmode
1498"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1499    endif
1500
1501    if exists("b:netrw_fname") && b:netrw_fname != ""
1502     NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1503"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1504    endif
1505
1506    if exists("g:netrw_ftpextracmd")
1507     NetrwKeepj put =g:netrw_ftpextracmd
1508"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1509    endif
1510
1511    if exists("g:netrw_ftpextracmd")
1512     NetrwKeepj put =g:netrw_ftpextracmd
1513"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1514    endif
1515    for fname in fnamelist
1516     NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1517    endfor
1518"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1519
1520    " perform ftp:
1521    " -i       : turns off interactive prompting from ftp
1522    " -n  unix : DON'T use <.netrc>, even though it exists
1523    " -n  win32: quit being obnoxious about password
1524    "  Note: using "_dd to delete to the black hole register; avoids messing up @@
1525    NetrwKeepj norm! 1G"_dd
1526    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1527    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1528    if getline(1) !~ "^$"
1529"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1530     if !exists("g:netrw_quiet")
1531      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1532     endif
1533    endif
1534
1535   elseif b:netrw_method == 9
1536    " obtain file using sftp
1537"    call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1538    if a:fname =~ '/'
1539     let localfile= substitute(a:fname,'^.*/','','')
1540    else
1541     let localfile= a:fname
1542    endif
1543    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))
1544
1545   elseif !exists("b:netrw_method") || b:netrw_method < 0
1546    " probably a badly formed url; protocol not recognized
1547"    call Dret("netrw#Obtain : unsupported method")
1548    return
1549
1550   else
1551    " protocol recognized but not supported for Obtain (yet?)
1552    if !exists("g:netrw_quiet")
1553     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1554    endif
1555"    call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1556    return
1557   endif
1558
1559   " restore status line
1560   if type(a:fname) == 1 && exists("s:netrw_users_stl")
1561    NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
1562   endif
1563
1564  endif
1565
1566  " cleanup
1567  if exists("tmpbufnr")
1568   if bufnr("%") != tmpbufnr
1569    exe tmpbufnr."bw!"
1570   else
1571    q!
1572   endif
1573  endif
1574
1575"  call Dret("netrw#Obtain")
1576endfun
1577
1578" ---------------------------------------------------------------------
1579" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1580fun! netrw#Nread(mode,fname)
1581"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
1582  let svpos= winsaveview()
1583"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1584  call netrw#NetRead(a:mode,a:fname)
1585"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1586  call winrestview(svpos)
1587
1588  if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
1589   if exists("w:netrw_bannercnt")
1590    " start with cursor just after the banner
1591    exe w:netrw_bannercnt
1592   endif
1593  endif
1594"  call Dret("netrw#Nread")
1595endfun
1596
1597" ------------------------------------------------------------------------
1598" s:NetrwOptionsSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1599"             Options get restored by s:NetrwOptionsRestore()
1600"
1601"             Option handling:
1602"              * save user's options                                     (s:NetrwOptionsSave)
1603"              * set netrw-safe options                                  (s:NetrwOptionsSafe)
1604"                - change an option only when user option != safe option (s:netrwSetSafeSetting)
1605"              * restore user's options                                  (s:netrwOPtionsRestore)
1606"                - restore a user option when != safe option             (s:NetrwRestoreSetting)
1607"             vt: (variable type) normally its either "w:" or "s:"
1608fun! s:NetrwOptionsSave(vt)
1609"  call Dfunc("s:NetrwOptionsSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1610"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1611"  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." hid=".&hid,'~'.expand("<slnum>"))
1612"  call Decho("(s:NetrwOptionsSave) lines=".&lines)
1613
1614  if !exists("{a:vt}netrw_optionsave")
1615   let {a:vt}netrw_optionsave= 1
1616  else
1617"   call Dret("s:NetrwOptionsSave : options already saved")
1618   return
1619  endif
1620"  call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
1621
1622  " Save current settings and current directory
1623"  call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
1624  let s:yykeep          = @@
1625  if exists("&l:acd")|let {a:vt}netrw_acdkeep  = &l:acd|endif
1626  let {a:vt}netrw_aikeep    = &l:ai
1627  let {a:vt}netrw_awkeep    = &l:aw
1628  let {a:vt}netrw_bhkeep    = &l:bh
1629  let {a:vt}netrw_blkeep    = &l:bl
1630  let {a:vt}netrw_btkeep    = &l:bt
1631  let {a:vt}netrw_bombkeep  = &l:bomb
1632  let {a:vt}netrw_cedit     = &cedit
1633  let {a:vt}netrw_cikeep    = &l:ci
1634  let {a:vt}netrw_cinkeep   = &l:cin
1635  let {a:vt}netrw_cinokeep  = &l:cino
1636  let {a:vt}netrw_comkeep   = &l:com
1637  let {a:vt}netrw_cpokeep   = &l:cpo
1638  let {a:vt}netrw_cuckeep   = &l:cuc
1639  let {a:vt}netrw_culkeep   = &l:cul
1640"  call Decho("(s:NetrwOptionsSave) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
1641  let {a:vt}netrw_diffkeep  = &l:diff
1642  let {a:vt}netrw_fenkeep   = &l:fen
1643  if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
1644   let {a:vt}netrw_ffkeep    = &l:ff
1645  endif
1646  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
1647  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
1648  let {a:vt}netrw_gokeep    = &l:go           " guioptions
1649  let {a:vt}netrw_hidkeep   = &l:hidden
1650  let {a:vt}netrw_imkeep    = &l:im
1651  let {a:vt}netrw_iskkeep   = &l:isk
1652  let {a:vt}netrw_lines     = &lines
1653  let {a:vt}netrw_lskeep    = &l:ls
1654  let {a:vt}netrw_makeep    = &l:ma
1655  let {a:vt}netrw_magickeep = &l:magic
1656  let {a:vt}netrw_modkeep   = &l:mod
1657  let {a:vt}netrw_nukeep    = &l:nu
1658  let {a:vt}netrw_rnukeep   = &l:rnu
1659  let {a:vt}netrw_repkeep   = &l:report
1660  let {a:vt}netrw_rokeep    = &l:ro
1661  let {a:vt}netrw_selkeep   = &l:sel
1662  let {a:vt}netrw_spellkeep = &l:spell
1663  if !g:netrw_use_noswf
1664   let {a:vt}netrw_swfkeep  = &l:swf
1665  endif
1666  let {a:vt}netrw_tskeep    = &l:ts
1667  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
1668  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
1669  let {a:vt}netrw_wrapkeep  = &l:wrap
1670  let {a:vt}netrw_writekeep = &l:write
1671
1672  " save a few selected netrw-related variables
1673"  call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
1674  if g:netrw_keepdir
1675   let {a:vt}netrw_dirkeep  = getcwd()
1676"   call Decho("saving to ".a:vt."netrw_dirkeep<".{a:vt}netrw_dirkeep.">",'~'.expand("<slnum>"))
1677  endif
1678  sil! let {a:vt}netrw_slashkeep= @/
1679
1680"  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>"))
1681"  call Dret("s:NetrwOptionsSave : tab#".tabpagenr()." win#".winnr())
1682endfun
1683
1684" ---------------------------------------------------------------------
1685" s:NetrwOptionsSafe: sets options to help netrw do its job {{{2
1686"                     Use  s:NetrwSaveOptions() to save user settings
1687"                     Use  s:NetrwOptionsRestore() to restore user settings
1688fun! s:NetrwOptionsSafe(islocal)
1689"  call Dfunc("s:NetrwOptionsSafe(islocal=".a:islocal.") win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1690"  call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1691"  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>"))
1692  if exists("+acd") | call s:NetrwSetSafeSetting("&l:acd",0)|endif
1693  call s:NetrwSetSafeSetting("&l:ai",0)
1694  call s:NetrwSetSafeSetting("&l:aw",0)
1695  call s:NetrwSetSafeSetting("&l:bl",0)
1696  call s:NetrwSetSafeSetting("&l:bomb",0)
1697  if a:islocal
1698   call s:NetrwSetSafeSetting("&l:bt","nofile")
1699  else
1700   call s:NetrwSetSafeSetting("&l:bt","acwrite")
1701  endif
1702  call s:NetrwSetSafeSetting("&l:ci",0)
1703  call s:NetrwSetSafeSetting("&l:cin",0)
1704  if g:netrw_fastbrowse > a:islocal
1705   call s:NetrwSetSafeSetting("&l:bh","hide")
1706  else
1707   call s:NetrwSetSafeSetting("&l:bh","delete")
1708  endif
1709  call s:NetrwSetSafeSetting("&l:cino","")
1710  call s:NetrwSetSafeSetting("&l:com","")
1711  if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif
1712  if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif
1713  setl fo=nroql2
1714  " call s:NetrwSetSafeSetting("&go","begmr")
1715  if &go =~ '\ca' | call s:NetrwSetSafeSetting("&go",substitute(&go,'\ca','','g')) | endif
1716  call s:NetrwSetSafeSetting("&l:hid",0)
1717  call s:NetrwSetSafeSetting("&l:im",0)
1718  setl isk+=@ isk+=* isk+=/
1719  call s:NetrwSetSafeSetting("&l:magic",1)
1720  if g:netrw_use_noswf
1721   call s:NetrwSetSafeSetting("swf",0)
1722  endif
1723  call s:NetrwSetSafeSetting("&l:report",10000)
1724  call s:NetrwSetSafeSetting("&l:sel","inclusive")
1725  call s:NetrwSetSafeSetting("&l:spell",0)
1726  call s:NetrwSetSafeSetting("&l:tw",0)
1727  call s:NetrwSetSafeSetting("&l:wig","")
1728  setl cedit&
1729
1730  " set up cuc and cul based on g:netrw_cursor and listing style
1731  " COMBAK -- cuc cul related
1732  call s:NetrwCursor(0)
1733
1734  " allow the user to override safe options
1735"  call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
1736  if &ft == "netrw"
1737"   call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1738   keepalt NetrwKeepj doau FileType netrw
1739  endif
1740
1741"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1742"  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>"))
1743"  call Dret("s:NetrwOptionsSafe")
1744endfun
1745
1746" ---------------------------------------------------------------------
1747" s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2
1748fun! s:NetrwOptionsRestore(vt)
1749"  call Dfunc("s:NetrwOptionsRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
1750"  call Decho("(s:NetrwOptionsRestore) lines=".&lines)
1751"  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>"))
1752  if !exists("{a:vt}netrw_optionsave")
1753"   call Decho("case ".a:vt."netrw_optionsave : doesn't exist",'~'.expand("<slnum>"))
1754"   call Decho("..doing filetype detect anyway")
1755   filetype detect
1756"   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>"))
1757"   call Decho("..ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1758"   call Dret("s:NetrwOptionsRestore : ".a:vt."netrw_optionsave doesn't exist")
1759   return
1760  endif
1761  unlet {a:vt}netrw_optionsave
1762
1763  if exists("+acd")
1764   if exists("{a:vt}netrw_acdkeep")
1765"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1766    let curdir = getcwd()
1767    let &l:acd = {a:vt}netrw_acdkeep
1768    unlet {a:vt}netrw_acdkeep
1769    if &l:acd
1770     call s:NetrwLcd(curdir)
1771    endif
1772   endif
1773  endif
1774"  call Decho("(s:NetrwOptionsRestore) #1 lines=".&lines)
1775  call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai")
1776  call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw")
1777  call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl")
1778  call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt")
1779  call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb")
1780"  call Decho("(s:NetrwOptionsRestore) #2 lines=".&lines)
1781  call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit")
1782  call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci")
1783  call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin")
1784  call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino")
1785  call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com")
1786"  call Decho("(s:NetrwOptionsRestore) #3 lines=".&lines)
1787  call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo")
1788  call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff")
1789  call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen")
1790  if exists("g:netrw_ffkeep") && g:netrw_ffkeep
1791   call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff")
1792  endif
1793"  call Decho("(s:NetrwOptionsRestore) #4 lines=".&lines)
1794  call s:NetrwRestoreSetting(a:vt."netrw_fokeep"   ,"&l:fo")
1795  call s:NetrwRestoreSetting(a:vt."netrw_gdkeep"   ,"&l:gd")
1796  call s:NetrwRestoreSetting(a:vt."netrw_gokeep"   ,"&l:go")
1797  call s:NetrwRestoreSetting(a:vt."netrw_hidkeep"  ,"&l:hidden")
1798"  call Decho("(s:NetrwOptionsRestore) #5 lines=".&lines)
1799  call s:NetrwRestoreSetting(a:vt."netrw_imkeep"   ,"&l:im")
1800  call s:NetrwRestoreSetting(a:vt."netrw_iskkeep"  ,"&l:isk")
1801"  call Decho("(s:NetrwOptionsRestore) #6 lines=".&lines)
1802  call s:NetrwRestoreSetting(a:vt."netrw_lines"    ,"&lines")
1803"  call Decho("(s:NetrwOptionsRestore) #7 lines=".&lines)
1804  call s:NetrwRestoreSetting(a:vt."netrw_lskeep"   ,"&l:ls")
1805  call s:NetrwRestoreSetting(a:vt."netrw_makeep"   ,"&l:ma")
1806  call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic")
1807  call s:NetrwRestoreSetting(a:vt."netrw_modkeep"  ,"&l:mod")
1808  call s:NetrwRestoreSetting(a:vt."netrw_nukeep"   ,"&l:nu")
1809"  call Decho("(s:NetrwOptionsRestore) #8 lines=".&lines)
1810  call s:NetrwRestoreSetting(a:vt."netrw_rnukeep"  ,"&l:rnu")
1811  call s:NetrwRestoreSetting(a:vt."netrw_repkeep"  ,"&l:report")
1812  call s:NetrwRestoreSetting(a:vt."netrw_rokeep"   ,"&l:ro")
1813  call s:NetrwRestoreSetting(a:vt."netrw_selkeep"  ,"&l:sel")
1814"  call Decho("(s:NetrwOptionsRestore) #9 lines=".&lines)
1815  call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell")
1816  call s:NetrwRestoreSetting(a:vt."netrw_twkeep"   ,"&l:tw")
1817  call s:NetrwRestoreSetting(a:vt."netrw_wigkeep"  ,"&l:wig")
1818  call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep" ,"&l:wrap")
1819  call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write")
1820"  call Decho("(s:NetrwOptionsRestore) #10 lines=".&lines)
1821  call s:NetrwRestoreSetting("s:yykeep","@@")
1822  " former problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1823  " Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces
1824  "        rather than by appending a tab which previously was using "&ts" to set the desired spacing.  (Sep 28, 2018)
1825  call s:NetrwRestoreSetting(a:vt."netrw_tskeep","&l:ts")
1826
1827  if exists("{a:vt}netrw_swfkeep")
1828   if &directory == ""
1829    " user hasn't specified a swapfile directory;
1830    " netrw will temporarily set the swapfile directory
1831    " to the current directory as returned by getcwd().
1832    let &l:directory= getcwd()
1833    sil! let &l:swf = {a:vt}netrw_swfkeep
1834    setl directory=
1835    unlet {a:vt}netrw_swfkeep
1836   elseif &l:swf != {a:vt}netrw_swfkeep
1837    if !g:netrw_use_noswf
1838     " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1839     sil! let &l:swf= {a:vt}netrw_swfkeep
1840    endif
1841    unlet {a:vt}netrw_swfkeep
1842   endif
1843  endif
1844  if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
1845   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1846   if exists("{a:vt}netrw_dirkeep")
1847    call s:NetrwLcd(dirkeep)
1848    unlet {a:vt}netrw_dirkeep
1849   endif
1850  endif
1851  call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/")
1852
1853"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1854"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
1855"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1856"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
1857"  call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
1858  " Moved the filetype detect here from NetrwGetFile() because remote files
1859  " were having their filetype detect-generated settings overwritten by
1860  " NetrwOptionRestore.
1861  if &ft != "netrw"
1862"   call Decho("before: filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1863   filetype detect
1864"   call Decho("after : filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1865  endif
1866"  call Decho("(s:NetrwOptionsRestore) lines=".&lines)
1867"  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>"))
1868"  call Dret("s:NetrwOptionsRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
1869endfun
1870
1871" ---------------------------------------------------------------------
1872" s:NetrwSetSafeSetting: sets an option to a safe setting {{{2
1873"                        but only when the options' value and the safe setting differ
1874"                        Doing this means that netrw will not come up as having changed a
1875"                        setting last when it really didn't actually change it.
1876"
1877"                        Called from s:NetrwOptionsSafe
1878"                          ex. call s:NetrwSetSafeSetting("&l:sel","inclusive")
1879fun! s:NetrwSetSafeSetting(setting,safesetting)
1880"  call Dfunc("s:NetrwSetSafeSetting(setting<".a:setting."> safesetting<".a:safesetting.">)")
1881
1882  if a:setting =~ '^&'
1883"   call Decho("fyi: a:setting starts with &")
1884   exe "let settingval= ".a:setting
1885"   call Decho("fyi: settingval<".settingval.">")
1886
1887   if settingval != a:safesetting
1888"    call Decho("set setting<".a:setting."> to option value<".a:safesetting.">")
1889    if type(a:safesetting) == 0
1890     exe "let ".a:setting."=".a:safesetting
1891    elseif type(a:safesetting) == 1
1892     exe "let ".a:setting."= '".a:safesetting."'"
1893    else
1894     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:setting." with a safesetting of type#".type(a:safesetting),105)
1895    endif
1896   endif
1897  endif
1898
1899"  call Dret("s:NetrwSetSafeSetting")
1900endfun
1901
1902" ------------------------------------------------------------------------
1903" s:NetrwRestoreSetting: restores specified setting using associated keepvar, {{{2
1904"                        but only if the setting value differs from the associated keepvar.
1905"                        Doing this means that netrw will not come up as having changed a
1906"                        setting last when it really didn't actually change it.
1907"
1908"                        Used by s:NetrwOptionsRestore() to restore each netrw-senstive setting
1909"                        keepvars are set up by s:NetrwOptionsSave
1910fun! s:NetrwRestoreSetting(keepvar,setting)
1911"""  call Dfunc("s:NetrwRestoreSetting(a:keepvar<".a:keepvar."> a:setting<".a:setting.">)")
1912
1913  " typically called from s:NetrwOptionsRestore
1914  "   call s:NetrwRestoreSettings(keep-option-variable-name,'associated-option')
1915  "   ex. call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
1916  "  Restores option (but only if different) from a:keepvar
1917  if exists(a:keepvar)
1918   exe "let keepvarval= ".a:keepvar
1919   exe "let setting= ".a:setting
1920
1921""   call Decho("fyi: a:keepvar<".a:keepvar."> exists")
1922""   call Decho("fyi: keepvarval=".keepvarval)
1923""   call Decho("fyi: a:setting<".a:setting."> setting<".setting.">")
1924
1925   if setting != keepvarval
1926""    call Decho("restore setting<".a:setting."> (currently=".setting.") to keepvarval<".keepvarval.">")
1927    if type(a:setting) == 0
1928     exe "let ".a:setting."= ".keepvarval
1929    elseif type(a:setting) == 1
1930     exe "let ".a:setting."= '".substitute(keepvarval,"'","''","g")."'"
1931    else
1932     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105)
1933    endif
1934   endif
1935
1936   exe "unlet ".a:keepvar
1937  endif
1938
1939""  call Dret("s:NetrwRestoreSetting")
1940endfun
1941
1942" ---------------------------------------------------------------------
1943" NetrwStatusLine: {{{2
1944fun! NetrwStatusLine()
1945
1946" vvv NetrwStatusLine() debugging vvv
1947"  let g:stlmsg=""
1948"  if !exists("w:netrw_explore_bufnr")
1949"   let g:stlmsg="!X<explore_bufnr>"
1950"  elseif w:netrw_explore_bufnr != bufnr("%")
1951"   let g:stlmsg="explore_bufnr!=".bufnr("%")
1952"  endif
1953"  if !exists("w:netrw_explore_line")
1954"   let g:stlmsg=" !X<explore_line>"
1955"  elseif w:netrw_explore_line != line(".")
1956"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1957"  endif
1958"  if !exists("w:netrw_explore_list")
1959"   let g:stlmsg=" !X<explore_list>"
1960"  endif
1961" ^^^ NetrwStatusLine() debugging ^^^
1962
1963  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")
1964   " restore user's status line
1965   let &stl        = s:netrw_users_stl
1966   let &laststatus = s:netrw_users_ls
1967   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1968   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1969   return ""
1970  else
1971   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
1972  endif
1973endfun
1974
1975" ===============================
1976"  Netrw Transfer Functions: {{{1
1977" ===============================
1978
1979" ------------------------------------------------------------------------
1980" netrw#NetRead: responsible for reading a file over the net {{{2
1981"   mode: =0 read remote file and insert before current line
1982"         =1 read remote file and insert after current line
1983"         =2 replace with remote file
1984"         =3 obtain file, but leave in temporary format
1985fun! netrw#NetRead(mode,...)
1986"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
1987
1988  " NetRead: save options {{{3
1989  call s:NetrwOptionsSave("w:")
1990  call s:NetrwOptionsSafe(0)
1991  call s:RestoreCursorline()
1992  " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
1993  " However, this setting is not wanted for a remote editing session.  The buffer should be "nofile", still.
1994  setl bl
1995"  call Decho("buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
1996
1997  " NetRead: interpret mode into a readcmd {{{3
1998  if     a:mode == 0 " read remote file before current line
1999   let readcmd = "0r"
2000  elseif a:mode == 1 " read file after current line
2001   let readcmd = "r"
2002  elseif a:mode == 2 " replace with remote file
2003   let readcmd = "%r"
2004  elseif a:mode == 3 " skip read of file (leave as temporary)
2005   let readcmd = "t"
2006  else
2007   exe a:mode
2008   let readcmd = "r"
2009  endif
2010  let ichoice = (a:0 == 0)? 0 : 1
2011"  call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
2012
2013  " NetRead: get temporary filename {{{3
2014  let tmpfile= s:GetTempfile("")
2015  if tmpfile == ""
2016"   call Dret("netrw#NetRead : unable to get a tempfile!")
2017   return
2018  endif
2019
2020  while ichoice <= a:0
2021
2022   " attempt to repeat with previous host-file-etc
2023   if exists("b:netrw_lastfile") && a:0 == 0
2024"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2025    let choice = b:netrw_lastfile
2026    let ichoice= ichoice + 1
2027
2028   else
2029    exe "let choice= a:" . ichoice
2030"    call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
2031
2032    if match(choice,"?") == 0
2033     " give help
2034     echomsg 'NetRead Usage:'
2035     echomsg ':Nread machine:path                         uses rcp'
2036     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
2037     echomsg ':Nread "machine id password path"           uses ftp'
2038     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
2039     echomsg ':Nread fetch://machine/path                 uses fetch'
2040     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2041     echomsg ':Nread http://[user@]machine/path           uses http  wget'
2042     echomsg ':Nread file:///path           		  uses elinks'
2043     echomsg ':Nread https://[user@]machine/path          uses http  wget'
2044     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
2045     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
2046     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
2047     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
2048     sleep 4
2049     break
2050
2051    elseif match(choice,'^"') != -1
2052     " Reconstruct Choice if choice starts with '"'
2053"     call Decho("reconstructing choice",'~'.expand("<slnum>"))
2054     if match(choice,'"$') != -1
2055      " case "..."
2056      let choice= strpart(choice,1,strlen(choice)-2)
2057     else
2058       "  case "... ... ..."
2059      let choice      = strpart(choice,1,strlen(choice)-1)
2060      let wholechoice = ""
2061
2062      while match(choice,'"$') == -1
2063       let wholechoice = wholechoice . " " . choice
2064       let ichoice     = ichoice + 1
2065       if ichoice > a:0
2066       	if !exists("g:netrw_quiet")
2067	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
2068	endif
2069"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
2070        return
2071       endif
2072       let choice= a:{ichoice}
2073      endwhile
2074      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2075     endif
2076    endif
2077   endif
2078
2079"   call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
2080   let ichoice= ichoice + 1
2081
2082   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
2083   call s:NetrwMethod(choice)
2084   if !exists("b:netrw_method") || b:netrw_method < 0
2085"    call Dret("netrw#NetRead : unsupported method")
2086    return
2087   endif
2088   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
2089
2090   " Check whether or not NetrwBrowse() should be handling this request
2091"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
2092   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
2093"    call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
2094    NetrwKeepj call s:NetrwBrowse(0,choice)
2095"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
2096    return
2097   endif
2098
2099   " ============
2100   " NetRead: Perform Protocol-Based Read {{{3
2101   " ===========================
2102   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2103    echo "(netrw) Processing your read request..."
2104   endif
2105
2106   ".........................................
2107   " NetRead: (rcp)  NetRead Method #1 {{{3
2108   if  b:netrw_method == 1 " read with rcp
2109"    call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
2110   " ER: nothing done with g:netrw_uid yet?
2111   " ER: on Win2K" rcp machine[.user]:file tmpfile
2112   " ER: when machine contains '.' adding .user is required (use $USERNAME)
2113   " ER: the tmpfile is full path: rcp sees C:\... as host C
2114   if s:netrw_has_nt_rcp == 1
2115    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2116     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2117    else
2118     " Any way needed it machine contains a '.'
2119     let uid_machine = g:netrw_machine .'.'. $USERNAME
2120    endif
2121   else
2122    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2123     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2124    else
2125     let uid_machine = g:netrw_machine
2126    endif
2127   endif
2128   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))
2129   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2130   let b:netrw_lastfile = choice
2131
2132   ".........................................
2133   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
2134   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
2135"     call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2136     let netrw_fname= b:netrw_fname
2137     NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2138     let filtbuf= bufnr("%")
2139     setl ff=unix
2140     NetrwKeepj put =g:netrw_ftpmode
2141"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2142     if exists("g:netrw_ftpextracmd")
2143      NetrwKeepj put =g:netrw_ftpextracmd
2144"      call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2145     endif
2146     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2147"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2148     if exists("g:netrw_port") && g:netrw_port != ""
2149      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2150     else
2151      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2152     endif
2153     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2154     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2155      let debugkeep = &debug
2156      setl debug=msg
2157      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2158      let &debug    = debugkeep
2159     endif
2160     call s:SaveBufVars()
2161     keepj bd!
2162     if bufname("%") == "" && getline("$") == "" && line('$') == 1
2163      " needed when one sources a file in a nolbl setting window via ftp
2164      q!
2165     endif
2166     call s:RestoreBufVars()
2167     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2168     let b:netrw_lastfile = choice
2169
2170   ".........................................
2171   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
2172   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
2173    " Construct execution string (four lines) which will be passed through filter
2174"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2175    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2176    NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2177    let filtbuf= bufnr("%")
2178    setl ff=unix
2179    if exists("g:netrw_port") && g:netrw_port != ""
2180     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2181"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2182    else
2183     NetrwKeepj put ='open '.g:netrw_machine
2184"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2185    endif
2186
2187    if exists("g:netrw_uid") && g:netrw_uid != ""
2188     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2189      NetrwKeepj put =g:netrw_uid
2190"       call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2191      if exists("s:netrw_passwd")
2192       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2193      endif
2194"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2195     elseif exists("s:netrw_passwd")
2196      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2197"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2198     endif
2199    endif
2200
2201    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2202     NetrwKeepj put =g:netrw_ftpmode
2203"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2204    endif
2205    if exists("g:netrw_ftpextracmd")
2206     NetrwKeepj put =g:netrw_ftpextracmd
2207"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2208    endif
2209    NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2210"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2211
2212    " perform ftp:
2213    " -i       : turns off interactive prompting from ftp
2214    " -n  unix : DON'T use <.netrc>, even though it exists
2215    " -n  win32: quit being obnoxious about password
2216    NetrwKeepj norm! 1G"_dd
2217    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2218    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2219    if getline(1) !~ "^$"
2220"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2221     if !exists("g:netrw_quiet")
2222      call netrw#ErrorMsg(s:ERROR,getline(1),5)
2223     endif
2224    endif
2225    call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2226    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2227    let b:netrw_lastfile = choice
2228
2229   ".........................................
2230   " NetRead: (scp) NetRead Method #4 {{{3
2231   elseif     b:netrw_method  == 4	" read with scp
2232"    call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2233    if exists("g:netrw_port") && g:netrw_port != ""
2234     let useport= " ".g:netrw_scpport." ".g:netrw_port
2235    else
2236     let useport= ""
2237    endif
2238    " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2239    " This is workaround to avoid mis-handle windows local-path:
2240    if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
2241      let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2242    else
2243      let tmpfile_get = tmpfile
2244    endif
2245    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))
2246    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2247    let b:netrw_lastfile = choice
2248
2249   ".........................................
2250   " NetRead: (http) NetRead Method #5 (wget) {{{3
2251   elseif     b:netrw_method  == 5
2252"    call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2253    if g:netrw_http_cmd == ""
2254     if !exists("g:netrw_quiet")
2255      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2256     endif
2257"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2258     return
2259    endif
2260
2261    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2262     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2263"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2264     if exists("g:netrw_http_xcmd")
2265      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))
2266     else
2267      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))
2268     endif
2269     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2270
2271    else
2272     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2273"     call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2274     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2275     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2276"     call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2277"     call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2278     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))
2279     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2280"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2281     exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2282    endif
2283    let b:netrw_lastfile = choice
2284"    call Decho("setl ro",'~'.expand("<slnum>"))
2285    setl ro nomod
2286
2287   ".........................................
2288   " NetRead: (dav) NetRead Method #6 {{{3
2289   elseif     b:netrw_method  == 6
2290"    call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2291
2292    if !executable(g:netrw_dav_cmd)
2293     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2294"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2295     return
2296    endif
2297    if g:netrw_dav_cmd =~ "curl"
2298     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2299    else
2300     " Construct execution string (four lines) which will be passed through filter
2301     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2302     new
2303     setl ff=unix
2304     if exists("g:netrw_port") && g:netrw_port != ""
2305      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2306     else
2307      NetrwKeepj put ='open '.g:netrw_machine
2308     endif
2309     if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2310      NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2311     endif
2312     NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2313     NetrwKeepj put ='quit'
2314
2315     " perform cadaver operation:
2316     NetrwKeepj norm! 1G"_dd
2317     call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2318     keepj bd!
2319    endif
2320    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2321    let b:netrw_lastfile = choice
2322
2323   ".........................................
2324   " NetRead: (rsync) NetRead Method #7 {{{3
2325   elseif     b:netrw_method  == 7
2326"    call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2327    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))
2328    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2329    let b:netrw_lastfile = choice
2330
2331   ".........................................
2332   " NetRead: (fetch) NetRead Method #8 {{{3
2333   "    fetch://[user@]host[:http]/path
2334   elseif     b:netrw_method  == 8
2335"    call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2336    if g:netrw_fetch_cmd == ""
2337     if !exists("g:netrw_quiet")
2338      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2339     endif
2340"     call Dret("NetRead")
2341     return
2342    endif
2343    if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2344     let netrw_option= "http"
2345    else
2346     let netrw_option= "ftp"
2347    endif
2348"    call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2349
2350    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2351     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))
2352    else
2353     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))
2354    endif
2355
2356    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2357    let b:netrw_lastfile = choice
2358"    call Decho("setl ro",'~'.expand("<slnum>"))
2359    setl ro nomod
2360
2361   ".........................................
2362   " NetRead: (sftp) NetRead Method #9 {{{3
2363   elseif     b:netrw_method  == 9
2364"    call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2365    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2366    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2367    let b:netrw_lastfile = choice
2368
2369   ".........................................
2370   " NetRead: (file) NetRead Method #10 {{{3
2371  elseif      b:netrw_method == 10 && exists("g:netrw_file_cmd")
2372"   "    call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2373   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2374   let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2375   let b:netrw_lastfile = choice
2376
2377   ".........................................
2378   " NetRead: Complain {{{3
2379   else
2380    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
2381   endif
2382  endwhile
2383
2384  " NetRead: cleanup {{{3
2385  if exists("b:netrw_method")
2386"   call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2387   unlet b:netrw_method
2388   unlet b:netrw_fname
2389  endif
2390  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
2391"   call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2392   NetrwKeepj call s:NetrwDelete(tmpfile)
2393  endif
2394  NetrwKeepj call s:NetrwOptionsRestore("w:")
2395
2396"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
2397endfun
2398
2399" ------------------------------------------------------------------------
2400" netrw#NetWrite: responsible for writing a file over the net {{{2
2401fun! netrw#NetWrite(...) range
2402"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
2403
2404  " NetWrite: option handling {{{3
2405  let mod= 0
2406  call s:NetrwOptionsSave("w:")
2407  call s:NetrwOptionsSafe(0)
2408
2409  " NetWrite: Get Temporary Filename {{{3
2410  let tmpfile= s:GetTempfile("")
2411  if tmpfile == ""
2412"   call Dret("netrw#NetWrite : unable to get a tempfile!")
2413   return
2414  endif
2415
2416  if a:0 == 0
2417   let ichoice = 0
2418  else
2419   let ichoice = 1
2420  endif
2421
2422  let curbufname= expand("%")
2423"  call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
2424  if &binary
2425   " For binary writes, always write entire file.
2426   " (line numbers don't really make sense for that).
2427   " Also supports the writing of tar and zip files.
2428"   call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2429   exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2430  elseif g:netrw_cygwin
2431   " write (selected portion of) file to temporary
2432   let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2433"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2434   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
2435  else
2436   " write (selected portion of) file to temporary
2437"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2438   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2439  endif
2440
2441  if curbufname == ""
2442   " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2443   " on the temporary file's name.  Deletion of the temporary file during
2444   " cleanup then causes an error message.
2445   0file!
2446  endif
2447
2448  " NetWrite: while choice loop: {{{3
2449  while ichoice <= a:0
2450
2451   " Process arguments: {{{4
2452   " attempt to repeat with previous host-file-etc
2453   if exists("b:netrw_lastfile") && a:0 == 0
2454"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2455    let choice = b:netrw_lastfile
2456    let ichoice= ichoice + 1
2457   else
2458    exe "let choice= a:" . ichoice
2459
2460    " Reconstruct Choice when choice starts with '"'
2461    if match(choice,"?") == 0
2462     echomsg 'NetWrite Usage:"'
2463     echomsg ':Nwrite machine:path                        uses rcp'
2464     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
2465     echomsg ':Nwrite "machine id password path"          uses ftp'
2466     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
2467     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
2468     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
2469     echomsg ':Nwrite rcp://machine/path                  uses rcp'
2470     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
2471     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2472     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
2473     sleep 4
2474     break
2475
2476    elseif match(choice,"^\"") != -1
2477     if match(choice,"\"$") != -1
2478       " case "..."
2479      let choice=strpart(choice,1,strlen(choice)-2)
2480     else
2481      "  case "... ... ..."
2482      let choice      = strpart(choice,1,strlen(choice)-1)
2483      let wholechoice = ""
2484
2485      while match(choice,"\"$") == -1
2486       let wholechoice= wholechoice . " " . choice
2487       let ichoice    = ichoice + 1
2488       if choice > a:0
2489       	if !exists("g:netrw_quiet")
2490	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2491	endif
2492"        call Dret("netrw#NetWrite")
2493        return
2494       endif
2495       let choice= a:{ichoice}
2496      endwhile
2497      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2498     endif
2499    endif
2500   endif
2501   let ichoice= ichoice + 1
2502"   call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
2503
2504   " Determine method of write (ftp, rcp, etc) {{{4
2505   NetrwKeepj call s:NetrwMethod(choice)
2506   if !exists("b:netrw_method") || b:netrw_method < 0
2507"    call Dfunc("netrw#NetWrite : unsupported method")
2508    return
2509   endif
2510
2511   " =============
2512   " NetWrite: Perform Protocol-Based Write {{{3
2513   " ============================
2514   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2515    echo "(netrw) Processing your write request..."
2516"    call Decho("Processing your write request...",'~'.expand("<slnum>"))
2517   endif
2518
2519   ".........................................
2520   " NetWrite: (rcp) NetWrite Method #1 {{{3
2521   if  b:netrw_method == 1
2522"    call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2523    if s:netrw_has_nt_rcp == 1
2524     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2525      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2526     else
2527      let uid_machine = g:netrw_machine .'.'. $USERNAME
2528     endif
2529    else
2530     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2531      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2532     else
2533      let uid_machine = g:netrw_machine
2534     endif
2535    endif
2536    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))
2537    let b:netrw_lastfile = choice
2538
2539   ".........................................
2540   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2541   elseif b:netrw_method == 2
2542"    call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2543    let netrw_fname = b:netrw_fname
2544
2545    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2546    let bhkeep      = &l:bh
2547    let curbuf      = bufnr("%")
2548    setl bh=hide
2549    keepj keepalt enew
2550
2551"    call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2552    setl ff=unix
2553    NetrwKeepj put =g:netrw_ftpmode
2554"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2555    if exists("g:netrw_ftpextracmd")
2556     NetrwKeepj put =g:netrw_ftpextracmd
2557"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2558    endif
2559    NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2560"    call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2561    if exists("g:netrw_port") && g:netrw_port != ""
2562     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2563    else
2564"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2565     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2566    endif
2567    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2568    if getline(1) !~ "^$"
2569     if !exists("g:netrw_quiet")
2570      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2571     endif
2572     let mod=1
2573    endif
2574
2575    " remove enew buffer (quietly)
2576    let filtbuf= bufnr("%")
2577    exe curbuf."b!"
2578    let &l:bh            = bhkeep
2579    exe filtbuf."bw!"
2580
2581    let b:netrw_lastfile = choice
2582
2583   ".........................................
2584   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2585   elseif b:netrw_method == 3
2586    " Construct execution string (three or more lines) which will be passed through filter
2587"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2588    let netrw_fname = b:netrw_fname
2589    let bhkeep      = &l:bh
2590
2591    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2592    let curbuf      = bufnr("%")
2593    setl bh=hide
2594    keepj keepalt enew
2595    setl ff=unix
2596
2597    if exists("g:netrw_port") && g:netrw_port != ""
2598     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2599"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2600    else
2601     NetrwKeepj put ='open '.g:netrw_machine
2602"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2603    endif
2604    if exists("g:netrw_uid") && g:netrw_uid != ""
2605     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2606      NetrwKeepj put =g:netrw_uid
2607"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2608      if exists("s:netrw_passwd") && s:netrw_passwd != ""
2609       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2610      endif
2611"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2612     elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2613      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2614"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2615     endif
2616    endif
2617    NetrwKeepj put =g:netrw_ftpmode
2618"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2619    if exists("g:netrw_ftpextracmd")
2620     NetrwKeepj put =g:netrw_ftpextracmd
2621"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2622    endif
2623    NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2624"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2625    " save choice/id/password for future use
2626    let b:netrw_lastfile = choice
2627
2628    " perform ftp:
2629    " -i       : turns off interactive prompting from ftp
2630    " -n  unix : DON'T use <.netrc>, even though it exists
2631    " -n  win32: quit being obnoxious about password
2632    NetrwKeepj norm! 1G"_dd
2633    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2634    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2635    if getline(1) !~ "^$"
2636     if  !exists("g:netrw_quiet")
2637      call netrw#ErrorMsg(s:ERROR,getline(1),15)
2638     endif
2639     let mod=1
2640    endif
2641
2642    " remove enew buffer (quietly)
2643    let filtbuf= bufnr("%")
2644    exe curbuf."b!"
2645    let &l:bh= bhkeep
2646    exe filtbuf."bw!"
2647
2648   ".........................................
2649   " NetWrite: (scp) NetWrite Method #4 {{{3
2650   elseif     b:netrw_method == 4
2651"    call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2652    if exists("g:netrw_port") && g:netrw_port != ""
2653     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2654    else
2655     let useport= ""
2656    endif
2657    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2658    let b:netrw_lastfile = choice
2659
2660   ".........................................
2661   " NetWrite: (http) NetWrite Method #5 {{{3
2662   elseif     b:netrw_method == 5
2663"    call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2664    let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2665    if executable(curl)
2666     let url= g:netrw_choice
2667     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2668    elseif !exists("g:netrw_quiet")
2669     call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd.">".",16)
2670    endif
2671
2672   ".........................................
2673   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2674   elseif     b:netrw_method == 6
2675"    call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2676
2677    " Construct execution string (four lines) which will be passed through filter
2678    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2679    let bhkeep      = &l:bh
2680
2681    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2682    let curbuf      = bufnr("%")
2683    setl bh=hide
2684    keepj keepalt enew
2685
2686    setl ff=unix
2687    if exists("g:netrw_port") && g:netrw_port != ""
2688     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2689    else
2690     NetrwKeepj put ='open '.g:netrw_machine
2691    endif
2692    if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2693     NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2694    endif
2695    NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2696
2697    " perform cadaver operation:
2698    NetrwKeepj norm! 1G"_dd
2699    call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2700
2701    " remove enew buffer (quietly)
2702    let filtbuf= bufnr("%")
2703    exe curbuf."b!"
2704    let &l:bh            = bhkeep
2705    exe filtbuf."bw!"
2706
2707    let b:netrw_lastfile = choice
2708
2709   ".........................................
2710   " NetWrite: (rsync) NetWrite Method #7 {{{3
2711   elseif     b:netrw_method == 7
2712"    call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2713    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))
2714    let b:netrw_lastfile = choice
2715
2716   ".........................................
2717   " NetWrite: (sftp) NetWrite Method #9 {{{3
2718   elseif     b:netrw_method == 9
2719"    call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2720    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2721    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2722     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2723    else
2724     let uid_machine = g:netrw_machine
2725    endif
2726
2727    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2728    let bhkeep = &l:bh
2729    let curbuf = bufnr("%")
2730    setl bh=hide
2731    keepj keepalt enew
2732
2733    setl ff=unix
2734    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2735"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2736    let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2737    call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2738    let filtbuf= bufnr("%")
2739    exe curbuf."b!"
2740    let &l:bh            = bhkeep
2741    exe filtbuf."bw!"
2742    let b:netrw_lastfile = choice
2743
2744   ".........................................
2745   " NetWrite: Complain {{{3
2746   else
2747    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2748    let leavemod= 1
2749   endif
2750  endwhile
2751
2752  " NetWrite: Cleanup: {{{3
2753"  call Decho("cleanup",'~'.expand("<slnum>"))
2754  if s:FileReadable(tmpfile)
2755"   call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2756   call s:NetrwDelete(tmpfile)
2757  endif
2758  call s:NetrwOptionsRestore("w:")
2759
2760  if a:firstline == 1 && a:lastline == line("$")
2761   " restore modifiability; usually equivalent to set nomod
2762   let &mod= mod
2763"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2764  elseif !exists("leavemod")
2765   " indicate that the buffer has not been modified since last written
2766"   call Decho("set nomod",'~'.expand("<slnum>"))
2767   setl nomod
2768"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2769  endif
2770
2771"  call Dret("netrw#NetWrite")
2772endfun
2773
2774" ---------------------------------------------------------------------
2775" netrw#NetSource: source a remotely hosted vim script {{{2
2776" uses NetRead to get a copy of the file into a temporarily file,
2777"              then sources that file,
2778"              then removes that file.
2779fun! netrw#NetSource(...)
2780"  call Dfunc("netrw#NetSource() a:0=".a:0)
2781  if a:0 > 0 && a:1 == '?'
2782   " give help
2783   echomsg 'NetSource Usage:'
2784   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
2785   echomsg ':Nsource fetch://machine/path                 uses fetch'
2786   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2787   echomsg ':Nsource http[s]://[user@]machine/path        uses http  wget'
2788   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
2789   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
2790   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
2791   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2792   sleep 4
2793  else
2794   let i= 1
2795   while i <= a:0
2796    call netrw#NetRead(3,a:{i})
2797"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2798    if s:FileReadable(s:netrw_tmpfile)
2799"     call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2800     exe "so ".fnameescape(s:netrw_tmpfile)
2801"     call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2802     if delete(s:netrw_tmpfile)
2803      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2804     endif
2805     unlet s:netrw_tmpfile
2806    else
2807     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2808    endif
2809    let i= i + 1
2810   endwhile
2811  endif
2812"  call Dret("netrw#NetSource")
2813endfun
2814
2815" ---------------------------------------------------------------------
2816" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2817"                   (implements the :Ntree command)
2818fun! netrw#SetTreetop(iscmd,...)
2819"  call Dfunc("netrw#SetTreetop(iscmd=".a:iscmd." ".((a:0 > 0)? a:1 : "").") a:0=".a:0)
2820"  call Decho("w:netrw_treetop<".w:netrw_treetop.">")
2821
2822  " iscmd==0: netrw#SetTreetop called using gn mapping
2823  " iscmd==1: netrw#SetTreetop called using :Ntree from the command line
2824"  call Decho("(iscmd=".a:iscmd.": called using :Ntree from command line",'~'.expand("<slnum>"))
2825  " clear out the current tree
2826  if exists("w:netrw_treetop")
2827"   call Decho("clearing out current tree",'~'.expand("<slnum>"))
2828   let inittreetop= w:netrw_treetop
2829   unlet w:netrw_treetop
2830  endif
2831  if exists("w:netrw_treedict")
2832"   call Decho("freeing w:netrw_treedict",'~'.expand("<slnum>"))
2833   unlet w:netrw_treedict
2834  endif
2835"  call Decho("inittreetop<".(exists("inittreetop")? inittreetop : "n/a").">")
2836
2837  if (a:iscmd == 0 || a:1 == "") && exists("inittreetop")
2838   let treedir         = s:NetrwTreePath(inittreetop)
2839"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2840  else
2841   if isdirectory(s:NetrwFile(a:1))
2842"    call Decho("a:1<".a:1."> is a directory",'~'.expand("<slnum>"))
2843    let treedir         = a:1
2844    let s:netrw_treetop = treedir
2845   elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2846    let treedir         = b:netrw_curdir."/".a:1
2847    let s:netrw_treetop = treedir
2848"    call Decho("a:1<".a:1."> is NOT a directory, using treedir<".treedir.">",'~'.expand("<slnum>"))
2849   else
2850    " normally the cursor is left in the message window.
2851    " However, here this results in the directory being listed in the message window, which is not wanted.
2852    let netrwbuf= bufnr("%")
2853    call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2854    exe bufwinnr(netrwbuf)."wincmd w"
2855    let treedir         = "."
2856    let s:netrw_treetop = getcwd()
2857   endif
2858  endif
2859"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2860
2861  " determine if treedir is remote or local
2862  let islocal= expand("%") !~ '^\a\{3,}://'
2863"  call Decho("islocal=".islocal,'~'.expand("<slnum>"))
2864
2865  " browse the resulting directory
2866  if islocal
2867   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir))
2868  else
2869   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir))
2870  endif
2871
2872"  call Dret("netrw#SetTreetop")
2873endfun
2874
2875" ===========================================
2876" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
2877"    readcmd == %r : replace buffer with newly read file
2878"            == 0r : read file at top of buffer
2879"            == r  : read file after current line
2880"            == t  : leave file in temporary form (ie. don't read into buffer)
2881fun! s:NetrwGetFile(readcmd, tfile, method)
2882"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
2883
2884  " readcmd=='t': simply do nothing
2885  if a:readcmd == 't'
2886"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2887"   call Dret("NetrwGetFile : skip read of tfile<".a:tfile.">")
2888   return
2889  endif
2890
2891  " get name of remote filename (ie. url and all)
2892  let rfile= bufname("%")
2893"  call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
2894
2895  if exists("*NetReadFixup")
2896   " for the use of NetReadFixup (not otherwise used internally)
2897   let line2= line("$")
2898  endif
2899
2900  if a:readcmd[0] == '%'
2901  " get file into buffer
2902"   call Decho("get file into buffer",'~'.expand("<slnum>"))
2903
2904   " rename the current buffer to the temp file (ie. tfile)
2905   if g:netrw_cygwin
2906    let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2907   else
2908    let tfile= a:tfile
2909   endif
2910   call s:NetrwBufRename(tfile)
2911
2912   " edit temporary file (ie. read the temporary file in)
2913   if     rfile =~ '\.zip$'
2914"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2915    call zip#Browse(tfile)
2916   elseif rfile =~ '\.tar$'
2917"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2918    call tar#Browse(tfile)
2919   elseif rfile =~ '\.tar\.gz$'
2920"    call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2921    call tar#Browse(tfile)
2922   elseif rfile =~ '\.tar\.bz2$'
2923"    call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2924    call tar#Browse(tfile)
2925   elseif rfile =~ '\.tar\.xz$'
2926"    call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2927    call tar#Browse(tfile)
2928   elseif rfile =~ '\.txz$'
2929"    call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2930    call tar#Browse(tfile)
2931   else
2932"    call Decho("edit temporary file",'~'.expand("<slnum>"))
2933    NetrwKeepj e!
2934   endif
2935
2936   " rename buffer back to remote filename
2937   call s:NetrwBufRename(rfile)
2938
2939   " Detect filetype of local version of remote file.
2940   " Note that isk must not include a "/" for scripts.vim
2941   " to process this detection correctly.
2942"   call Decho("detect filetype of local version of remote file",'~'.expand("<slnum>"))
2943   let iskkeep= &l:isk
2944   setl isk-=/
2945   let &l:isk= iskkeep
2946"   call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
2947   let line1 = 1
2948   let line2 = line("$")
2949
2950  elseif !&ma
2951   " attempting to read a file after the current line in the file, but the buffer is not modifiable
2952   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2953"   call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2954   return
2955
2956  elseif s:FileReadable(a:tfile)
2957   " read file after current line
2958"   call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2959   let curline = line(".")
2960   let lastline= line("$")
2961"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline,'~'.expand("<slnum>"))
2962   exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2963   let line1= curline + 1
2964   let line2= line("$") - lastline + 1
2965
2966  else
2967   " not readable
2968"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2969"   call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2970   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2971"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2972   return
2973  endif
2974
2975  " User-provided (ie. optional) fix-it-up command
2976  if exists("*NetReadFixup")
2977"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2978   NetrwKeepj call NetReadFixup(a:method, line1, line2)
2979"  else " Decho
2980"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2981  endif
2982
2983  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
2984   " update the Buffers menu
2985   NetrwKeepj call s:UpdateBuffersMenu()
2986  endif
2987
2988"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
2989
2990 " make sure file is being displayed
2991"  redraw!
2992
2993"  call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2994"  call Dret("NetrwGetFile")
2995endfun
2996
2997" ------------------------------------------------------------------------
2998" s:NetrwMethod:  determine method of transfer {{{2
2999" Input:
3000"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
3001" Output:
3002"  b:netrw_method= 1: rcp
3003"                  2: ftp + <.netrc>
3004"	           3: ftp + machine, id, password, and [path]filename
3005"	           4: scp
3006"	           5: http[s] (wget)
3007"	           6: dav
3008"	           7: rsync
3009"	           8: fetch
3010"	           9: sftp
3011"	          10: file
3012"  g:netrw_machine= hostname
3013"  b:netrw_fname  = filename
3014"  g:netrw_port   = optional port number (for ftp)
3015"  g:netrw_choice = copy of input url (choice)
3016fun! s:NetrwMethod(choice)
3017"   call Dfunc("s:NetrwMethod(a:choice<".a:choice.">)")
3018
3019   " sanity check: choice should have at least three slashes in it
3020   if strlen(substitute(a:choice,'[^/]','','g')) < 3
3021    call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
3022    let b:netrw_method = -1
3023"    call Dret("s:NetrwMethod : incorrect url format<".a:choice.">")
3024    return
3025   endif
3026
3027   " record current g:netrw_machine, if any
3028   " curmachine used if protocol == ftp and no .netrc
3029   if exists("g:netrw_machine")
3030    let curmachine= g:netrw_machine
3031"    call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
3032   else
3033    let curmachine= "N O T A HOST"
3034   endif
3035   if exists("g:netrw_port")
3036    let netrw_port= g:netrw_port
3037   endif
3038
3039   " insure that netrw_ftp_cmd starts off every method determination
3040   " with the current g:netrw_ftp_cmd
3041   let s:netrw_ftp_cmd= g:netrw_ftp_cmd
3042
3043  " initialization
3044  let b:netrw_method  = 0
3045  let g:netrw_machine = ""
3046  let b:netrw_fname   = ""
3047  let g:netrw_port    = ""
3048  let g:netrw_choice  = a:choice
3049
3050  " Patterns:
3051  " mipf     : a:machine a:id password filename	     Use ftp
3052  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
3053  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
3054  " rcpurm   : rcp://[user@]host/filename	     Use rcp
3055  " rcphf    : [user@]host:filename		     Use rcp
3056  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
3057  " httpurm  : http[s]://[user@]host/filename	     Use wget
3058  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
3059  " rsyncurm : rsync://host[:port]/path              Use rsync
3060  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
3061  " sftpurm  : sftp://[user@]host/filename  Use scp
3062  " fileurm  : file://[user@]host/filename	     Use elinks or links
3063  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
3064  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
3065  let ftpurm   = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
3066  let rcpurm   = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
3067  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
3068  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
3069  let httpurm  = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
3070  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
3071  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
3072  let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
3073  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
3074  let fileurm  = '^file\=://\(.*\)$'
3075
3076"  call Decho("determine method:",'~'.expand("<slnum>"))
3077  " Determine Method
3078  " Method#1: rcp://user@hostname/...path-to-file {{{3
3079  if match(a:choice,rcpurm) == 0
3080"   call Decho("rcp://...",'~'.expand("<slnum>"))
3081   let b:netrw_method  = 1
3082   let userid          = substitute(a:choice,rcpurm,'\1',"")
3083   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
3084   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
3085   if userid != ""
3086    let g:netrw_uid= userid
3087   endif
3088
3089  " Method#4: scp://user@hostname/...path-to-file {{{3
3090  elseif match(a:choice,scpurm) == 0
3091"   call Decho("scp://...",'~'.expand("<slnum>"))
3092   let b:netrw_method  = 4
3093   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
3094   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
3095   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
3096
3097  " Method#5: http[s]://user@hostname/...path-to-file {{{3
3098  elseif match(a:choice,httpurm) == 0
3099"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3100   let b:netrw_method = 5
3101   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
3102   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
3103   let b:netrw_http   = (a:choice =~ '^https:')? "https" : "http"
3104
3105  " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
3106  elseif match(a:choice,davurm) == 0
3107"   call Decho("dav://...",'~'.expand("<slnum>"))
3108   let b:netrw_method= 6
3109   if a:choice =~ 'davs:'
3110    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
3111   else
3112    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
3113   endif
3114   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
3115
3116   " Method#7: rsync://user@hostname/...path-to-file {{{3
3117  elseif match(a:choice,rsyncurm) == 0
3118"   call Decho("rsync://...",'~'.expand("<slnum>"))
3119   let b:netrw_method = 7
3120   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
3121   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
3122
3123   " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
3124  elseif match(a:choice,ftpurm) == 0
3125"   call Decho("ftp://...",'~'.expand("<slnum>"))
3126   let userid	      = substitute(a:choice,ftpurm,'\2',"")
3127   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
3128   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
3129   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
3130"   call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3131   if userid != ""
3132    let g:netrw_uid= userid
3133   endif
3134
3135   if curmachine != g:netrw_machine
3136    if exists("s:netrw_hup[".g:netrw_machine."]")
3137     call NetUserPass("ftp:".g:netrw_machine)
3138    elseif exists("s:netrw_passwd")
3139     " if there's a change in hostname, require password re-entry
3140     unlet s:netrw_passwd
3141    endif
3142    if exists("netrw_port")
3143     unlet netrw_port
3144    endif
3145   endif
3146
3147   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3148    let b:netrw_method = 3
3149   else
3150    let host= substitute(g:netrw_machine,'\..*$','','')
3151    if exists("s:netrw_hup[host]")
3152     call NetUserPass("ftp:".host)
3153
3154    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~# '-[sS]:'
3155"     call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3156"     call Decho("          g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3157     if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
3158      let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3159"      call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3160     endif
3161     let b:netrw_method= 2
3162    elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3163"     call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3164     let b:netrw_method= 2
3165    else
3166     if !exists("g:netrw_uid") || g:netrw_uid == ""
3167      call NetUserPass()
3168     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3169      call NetUserPass(g:netrw_uid)
3170    " else just use current g:netrw_uid and s:netrw_passwd
3171     endif
3172     let b:netrw_method= 3
3173    endif
3174   endif
3175
3176  " Method#8: fetch {{{3
3177  elseif match(a:choice,fetchurm) == 0
3178"   call Decho("fetch://...",'~'.expand("<slnum>"))
3179   let b:netrw_method = 8
3180   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3181   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3182   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3183   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
3184
3185   " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
3186  elseif match(a:choice,mipf) == 0
3187"   call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
3188   let b:netrw_method  = 3
3189   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3190   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
3191   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
3192   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
3193   call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
3194
3195  " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3196  elseif match(a:choice,mf) == 0
3197"   call Decho("(ftp) host file",'~'.expand("<slnum>"))
3198   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3199    let b:netrw_method  = 3
3200    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3201    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3202
3203   elseif s:FileReadable(expand("$HOME/.netrc"))
3204    let b:netrw_method  = 2
3205    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3206    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3207   endif
3208
3209  " Method#9: sftp://user@hostname/...path-to-file {{{3
3210  elseif match(a:choice,sftpurm) == 0
3211"   call Decho("sftp://...",'~'.expand("<slnum>"))
3212   let b:netrw_method = 9
3213   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3214   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
3215
3216  " Method#1: Issue an rcp: hostname:filename"  (this one should be last) {{{3
3217  elseif match(a:choice,rcphf) == 0
3218"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3219   let b:netrw_method  = 1
3220   let userid          = substitute(a:choice,rcphf,'\2',"")
3221   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3222   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
3223"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3224"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3225"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3226"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3227   if userid != ""
3228    let g:netrw_uid= userid
3229   endif
3230
3231   " Method#10: file://user@hostname/...path-to-file {{{3
3232  elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
3233"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3234   let b:netrw_method = 10
3235   let b:netrw_fname  = substitute(a:choice,fileurm,'\1',"")
3236"   call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
3237
3238  " Cannot Determine Method {{{3
3239  else
3240   if !exists("g:netrw_quiet")
3241    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3242   endif
3243   let b:netrw_method  = -1
3244  endif
3245  "}}}3
3246
3247  if g:netrw_port != ""
3248   " remove any leading [:#] from port number
3249   let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
3250  elseif exists("netrw_port")
3251   " retain port number as implicit for subsequent ftp operations
3252   let g:netrw_port= netrw_port
3253  endif
3254
3255"  call Decho("a:choice       <".a:choice.">",'~'.expand("<slnum>"))
3256"  call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3257"  call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3258"  call Decho("g:netrw_port   <".g:netrw_port.">",'~'.expand("<slnum>"))
3259"  if exists("g:netrw_uid")		"Decho
3260"   call Decho("g:netrw_uid    <".g:netrw_uid.">",'~'.expand("<slnum>"))
3261"  endif					"Decho
3262"  if exists("s:netrw_passwd")		"Decho
3263"   call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3264"  endif					"Decho
3265"  call Decho("b:netrw_fname  <".b:netrw_fname.">",'~'.expand("<slnum>"))
3266"  call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
3267endfun
3268
3269" ------------------------------------------------------------------------
3270" NetReadFixup: this sort of function is typically written by the user {{{2
3271"               to handle extra junk that their system's ftp dumps
3272"               into the transfer.  This function is provided as an
3273"               example and as a fix for a Windows 95 problem: in my
3274"               experience, win95's ftp always dumped four blank lines
3275"               at the end of the transfer.
3276if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
3277 fun! NetReadFixup(method, line1, line2)
3278"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
3279
3280   " sanity checks -- attempt to convert inputs to integers
3281   let method = a:method + 0
3282   let line1  = a:line1 + 0
3283   let line2  = a:line2 + 0
3284   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
3285"    call Dret("NetReadFixup")
3286    return
3287   endif
3288
3289   if method == 3   " ftp (no <.netrc>)
3290    let fourblanklines= line2 - 3
3291    if fourblanklines >= line1
3292     exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
3293     call histdel("/",-1)
3294    endif
3295   endif
3296
3297"   call Dret("NetReadFixup")
3298 endfun
3299endif
3300
3301" ---------------------------------------------------------------------
3302" NetUserPass: set username and password for subsequent ftp transfer {{{2
3303"   Usage:  :call NetUserPass()		               -- will prompt for userid and password
3304"	    :call NetUserPass("uid")	               -- will prompt for password
3305"	    :call NetUserPass("uid","password")        -- sets global userid and password
3306"	    :call NetUserPass("ftp:host")              -- looks up userid and password using hup dictionary
3307"	    :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
3308fun! NetUserPass(...)
3309
3310" call Dfunc("NetUserPass() a:0=".a:0)
3311
3312 if !exists('s:netrw_hup')
3313  let s:netrw_hup= {}
3314 endif
3315
3316 if a:0 == 0
3317  " case: no input arguments
3318
3319  " change host and username if not previously entered; get new password
3320  if !exists("g:netrw_machine")
3321   let g:netrw_machine= input('Enter hostname: ')
3322  endif
3323  if !exists("g:netrw_uid") || g:netrw_uid == ""
3324   " get username (user-id) via prompt
3325   let g:netrw_uid= input('Enter username: ')
3326  endif
3327  " get password via prompting
3328  let s:netrw_passwd= inputsecret("Enter Password: ")
3329
3330  " set up hup database
3331  let host = substitute(g:netrw_machine,'\..*$','','')
3332  if !exists('s:netrw_hup[host]')
3333   let s:netrw_hup[host]= {}
3334  endif
3335  let s:netrw_hup[host].uid    = g:netrw_uid
3336  let s:netrw_hup[host].passwd = s:netrw_passwd
3337
3338 elseif a:0 == 1
3339  " case: one input argument
3340
3341  if a:1 =~ '^ftp:'
3342   " get host from ftp:... url
3343   " access userid and password from hup (host-user-passwd) dictionary
3344"   call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3345   let host = substitute(a:1,'^ftp:','','')
3346   let host = substitute(host,'\..*','','')
3347   if exists("s:netrw_hup[host]")
3348    let g:netrw_uid    = s:netrw_hup[host].uid
3349    let s:netrw_passwd = s:netrw_hup[host].passwd
3350"    call Decho("get s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3351"    call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3352   else
3353    let g:netrw_uid    = input("Enter UserId: ")
3354    let s:netrw_passwd = inputsecret("Enter Password: ")
3355   endif
3356
3357  else
3358   " case: one input argument, not an url.  Using it as a new user-id.
3359"   call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3360   if exists("g:netrw_machine")
3361    if g:netrw_machine =~ '[0-9.]\+'
3362     let host= g:netrw_machine
3363    else
3364     let host= substitute(g:netrw_machine,'\..*$','','')
3365    endif
3366   else
3367    let g:netrw_machine= input('Enter hostname: ')
3368   endif
3369   let g:netrw_uid = a:1
3370"   call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3371   if exists("g:netrw_passwd")
3372    " ask for password if one not previously entered
3373    let s:netrw_passwd= g:netrw_passwd
3374   else
3375    let s:netrw_passwd = inputsecret("Enter Password: ")
3376   endif
3377  endif
3378
3379"  call Decho("host<".host.">",'~'.expand("<slnum>"))
3380  if exists("host")
3381   if !exists('s:netrw_hup[host]')
3382    let s:netrw_hup[host]= {}
3383   endif
3384   let s:netrw_hup[host].uid    = g:netrw_uid
3385   let s:netrw_hup[host].passwd = s:netrw_passwd
3386  endif
3387
3388 elseif a:0 == 2
3389  let g:netrw_uid    = a:1
3390  let s:netrw_passwd = a:2
3391
3392 elseif a:0 == 3
3393  " enter hostname, user-id, and password into the hup dictionary
3394  let host = substitute(a:1,'^\a\+:','','')
3395  let host = substitute(host,'\..*$','','')
3396  if !exists('s:netrw_hup[host]')
3397   let s:netrw_hup[host]= {}
3398  endif
3399  let s:netrw_hup[host].uid    = a:2
3400  let s:netrw_hup[host].passwd = a:3
3401  let g:netrw_uid              = s:netrw_hup[host].uid
3402  let s:netrw_passwd           = s:netrw_hup[host].passwd
3403"  call Decho("set s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3404"  call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3405 endif
3406
3407" call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
3408endfun
3409
3410" =================================
3411"  Shared Browsing Support:    {{{1
3412" =================================
3413
3414" ---------------------------------------------------------------------
3415" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3416fun! s:ExplorePatHls(pattern)
3417"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
3418  let repat= substitute(a:pattern,'^**/\{1,2}','','')
3419"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3420  let repat= escape(repat,'][.\')
3421"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3422  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
3423"  call Dret("s:ExplorePatHls repat<".repat.">")
3424  return repat
3425endfun
3426
3427" ---------------------------------------------------------------------
3428"  s:NetrwBookHistHandler: {{{2
3429"    0: (user: <mb>)   bookmark current directory
3430"    1: (user: <gb>)   change to the bookmarked directory
3431"    2: (user: <qb>)   list bookmarks
3432"    3: (browsing)     records current directory history
3433"    4: (user: <u>)    go up   (previous) directory, using history
3434"    5: (user: <U>)    go down (next)     directory, using history
3435"    6: (user: <mB>)   delete bookmark
3436fun! s:NetrwBookHistHandler(chg,curdir)
3437"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhistcnt." histmax=".g:netrw_dirhistmax)
3438  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3439"   "  call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3440   return
3441  endif
3442
3443  let ykeep    = @@
3444  let curbufnr = bufnr("%")
3445
3446  if a:chg == 0
3447   " bookmark the current directory
3448"   call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3449   if exists("s:netrwmarkfilelist_{curbufnr}")
3450    call s:NetrwBookmark(0)
3451    echo "bookmarked marked files"
3452   else
3453    call s:MakeBookmark(a:curdir)
3454    echo "bookmarked the current directory"
3455   endif
3456
3457  elseif a:chg == 1
3458   " change to the bookmarked directory
3459"   call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3460   if exists("g:netrw_bookmarklist[v:count-1]")
3461"    call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3462    exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3463   else
3464    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3465   endif
3466
3467  elseif a:chg == 2
3468"   redraw!
3469   let didwork= 0
3470   " list user's bookmarks
3471"   call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3472   if exists("g:netrw_bookmarklist")
3473"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3474    let cnt= 1
3475    for bmd in g:netrw_bookmarklist
3476"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3477     echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3478     let didwork = 1
3479     let cnt     = cnt + 1
3480    endfor
3481   endif
3482
3483   " list directory history
3484   " Note: history is saved only when PerformListing is done;
3485   "       ie. when netrw can re-use a netrw buffer, the current directory is not saved in the history.
3486   let cnt     = g:netrw_dirhistcnt
3487   let first   = 1
3488   let histcnt = 0
3489   if g:netrw_dirhistmax > 0
3490    while ( first || cnt != g:netrw_dirhistcnt )
3491"    call Decho("first=".first." cnt=".cnt." dirhistcnt=".g:netrw_dirhistcnt,'~'.expand("<slnum>"))
3492     if exists("g:netrw_dirhist_{cnt}")
3493"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3494      echo printf("Netrw  History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3495      let didwork= 1
3496     endif
3497     let histcnt = histcnt + 1
3498     let first   = 0
3499     let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3500     if cnt < 0
3501      let cnt= cnt + g:netrw_dirhistmax
3502     endif
3503    endwhile
3504   else
3505    let g:netrw_dirhistcnt= 0
3506   endif
3507   if didwork
3508    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3509   endif
3510
3511  elseif a:chg == 3
3512   " saves most recently visited directories (when they differ)
3513"   call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3514   if !exists("g:netrw_dirhistcnt") || !exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") || g:netrw_dirhist_{g:netrw_dirhistcnt} != a:curdir
3515    if g:netrw_dirhistmax > 0
3516     let g:netrw_dirhistcnt                   = ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3517     let g:netrw_dirhist_{g:netrw_dirhistcnt} = a:curdir
3518    endif
3519"    call Decho("save dirhist#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3520   endif
3521
3522  elseif a:chg == 4
3523   " u: change to the previous directory stored on the history list
3524"   call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
3525   if g:netrw_dirhistmax > 0
3526    let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - v:count1 ) % g:netrw_dirhistmax
3527    if g:netrw_dirhistcnt < 0
3528     let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3529    endif
3530   else
3531    let g:netrw_dirhistcnt= 0
3532   endif
3533   if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3534"    call Decho("changedir u#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3535    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3536     setl ma noro
3537"     call Decho("setl ma noro",'~'.expand("<slnum>"))
3538     sil! NetrwKeepj %d _
3539     setl nomod
3540"     call Decho("setl nomod",'~'.expand("<slnum>"))
3541"     call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3542    endif
3543"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3544    exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3545   else
3546    if g:netrw_dirhistmax > 0
3547     let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + v:count1 ) % g:netrw_dirhistmax
3548    else
3549     let g:netrw_dirhistcnt= 0
3550    endif
3551    echo "Sorry, no predecessor directory exists yet"
3552   endif
3553
3554  elseif a:chg == 5
3555   " U: change to the subsequent directory stored on the history list
3556"   call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3557   if g:netrw_dirhistmax > 0
3558    let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3559    if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3560"    call Decho("changedir U#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3561     if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3562"      call Decho("setl ma noro",'~'.expand("<slnum>"))
3563      setl ma noro
3564      sil! NetrwKeepj %d _
3565"      call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3566"      call Decho("setl nomod",'~'.expand("<slnum>"))
3567      setl nomod
3568"      call Decho("(set nomod)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3569     endif
3570"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3571     exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3572    else
3573     let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - 1 ) % g:netrw_dirhistmax
3574     if g:netrw_dirhistcnt < 0
3575      let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3576     endif
3577     echo "Sorry, no successor directory exists yet"
3578    endif
3579   else
3580    let g:netrw_dirhistcnt= 0
3581    echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
3582   endif
3583
3584  elseif a:chg == 6
3585"   call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3586   if exists("s:netrwmarkfilelist_{curbufnr}")
3587    call s:NetrwBookmark(1)
3588    echo "removed marked files from bookmarks"
3589   else
3590    " delete the v:count'th bookmark
3591    let iremove = v:count
3592    let dremove = g:netrw_bookmarklist[iremove - 1]
3593"    call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3594    call s:MergeBookmarks()
3595"    call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3596    NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3597    echo "removed ".dremove." from g:netrw_bookmarklist"
3598"    call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3599   endif
3600"   call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3601  endif
3602  call s:NetrwBookmarkMenu()
3603  call s:NetrwTgtMenu()
3604  let @@= ykeep
3605"  call Dret("s:NetrwBookHistHandler")
3606endfun
3607
3608" ---------------------------------------------------------------------
3609" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
3610"  Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
3611"                      Sister function: s:NetrwBookHistSave()
3612fun! s:NetrwBookHistRead()
3613"  call Dfunc("s:NetrwBookHistRead()")
3614  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3615"   call Dret("s:NetrwBookHistRead - nothing read (suppressed due to dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a").")")
3616   return
3617  endif
3618  let ykeep= @@
3619
3620  " read bookmarks
3621  if !exists("s:netrw_initbookhist")
3622   let home    = s:NetrwHome()
3623   let savefile= home."/.netrwbook"
3624   if filereadable(s:NetrwFile(savefile))
3625"    call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3626    exe "keepalt NetrwKeepj so ".savefile
3627   endif
3628
3629   " read history
3630   if g:netrw_dirhistmax > 0
3631    let savefile= home."/.netrwhist"
3632    if filereadable(s:NetrwFile(savefile))
3633"    call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3634     exe "keepalt NetrwKeepj so ".savefile
3635    endif
3636    let s:netrw_initbookhist= 1
3637    au VimLeave * call s:NetrwBookHistSave()
3638   endif
3639  endif
3640
3641  let @@= ykeep
3642"  call Decho("dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a"),'~'.expand("<slnum>"))
3643"  call Decho("dirhistcnt=".(exists("g:netrw_dirhistcnt")? g:netrw_dirhistcnt : "n/a"),'~'.expand("<slnum>"))
3644"  call Dret("s:NetrwBookHistRead")
3645endfun
3646
3647" ---------------------------------------------------------------------
3648" s:NetrwBookHistSave: this function saves bookmarks and history to files {{{2
3649"                      Sister function: s:NetrwBookHistRead()
3650"                      I used to do this via viminfo but that appears to
3651"                      be unreliable for long-term storage
3652"                      If g:netrw_dirhistmax is <= 0, no history or bookmarks
3653"                      will be saved.
3654"                      (s:NetrwBookHistHandler(3,...) used to record history)
3655fun! s:NetrwBookHistSave()
3656"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt)
3657  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3658"   call Dret("s:NetrwBookHistSave : nothing saved (dirhistmax=".g:netrw_dirhistmax.")")
3659   return
3660  endif
3661
3662  let savefile= s:NetrwHome()."/.netrwhist"
3663"  call Decho("savefile<".savefile.">",'~'.expand("<slnum>"))
3664  1split
3665
3666  " setting up a new buffer which will become .netrwhist
3667  call s:NetrwEnew()
3668"  call Decho("case g:netrw_use_noswf=".g:netrw_use_noswf.(exists("+acd")? " +acd" : " -acd"),'~'.expand("<slnum>"))
3669  if g:netrw_use_noswf
3670   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
3671  else
3672   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
3673  endif
3674  setl nocin noai noci magic nospell nohid wig= noaw
3675  setl ma noro write
3676  if exists("+acd") | setl noacd | endif
3677  sil! NetrwKeepj keepalt %d _
3678
3679  " rename enew'd file: .netrwhist -- no attempt to merge
3680  " record dirhistmax and current dirhistcnt
3681  " save history
3682"  call Decho("saving history: dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt." lastline=".line("$"),'~'.expand("<slnum>"))
3683  sil! keepalt file .netrwhist
3684  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
3685  call setline(2,"let g:netrw_dirhistcnt =".g:netrw_dirhistcnt)
3686  if g:netrw_dirhistmax > 0
3687   let lastline = line("$")
3688   let cnt      = g:netrw_dirhistcnt
3689   let first    = 1
3690   while ( first || cnt != g:netrw_dirhistcnt )
3691    let lastline= lastline + 1
3692    if exists("g:netrw_dirhist_{cnt}")
3693     call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3694"     call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("<slnum>"))
3695    endif
3696    let first   = 0
3697    let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3698    if cnt < 0
3699     let cnt= cnt + g:netrw_dirhistmax
3700    endif
3701   endwhile
3702   exe "sil! w! ".savefile
3703"   call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
3704  endif
3705
3706  " save bookmarks
3707  sil NetrwKeepj %d _
3708  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
3709"   call Decho("saving bookmarks",'~'.expand("<slnum>"))
3710   " merge and write .netrwbook
3711   let savefile= s:NetrwHome()."/.netrwbook"
3712
3713   if filereadable(s:NetrwFile(savefile))
3714    let booklist= deepcopy(g:netrw_bookmarklist)
3715    exe "sil NetrwKeepj keepalt so ".savefile
3716    for bdm in booklist
3717     if index(g:netrw_bookmarklist,bdm) == -1
3718      call add(g:netrw_bookmarklist,bdm)
3719     endif
3720    endfor
3721    call sort(g:netrw_bookmarklist)
3722   endif
3723
3724   " construct and save .netrwbook
3725   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3726   exe "sil! w! ".savefile
3727"   call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
3728  endif
3729
3730  " cleanup -- remove buffer used to construct history
3731  let bgone= bufnr("%")
3732  q!
3733  exe "keepalt ".bgone."bwipe!"
3734
3735"  call Dret("s:NetrwBookHistSave")
3736endfun
3737
3738" ---------------------------------------------------------------------
3739" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3740"  list of the contents of a local or remote directory.  It is assumed that the
3741"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3742"  with the requested remote hostname first.
3743"    Often called via:  Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
3744fun! s:NetrwBrowse(islocal,dirname)
3745  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
3746"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
3747"  call Decho("fyi: modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
3748"  call Decho("fyi: tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3749"  call Dredir("ls!","s:NetrwBrowse")
3750
3751  " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3752  " This is useful when one edits a local file, then :e ., then :Rex
3753  if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
3754   let w:netrw_rexfile= bufname("#")
3755"   call Decho("setting w:netrw_rexfile<".w:netrw_rexfile."> win#".winnr(),'~'.expand("<slnum>"))
3756  endif
3757
3758  " s:NetrwBrowse : initialize history {{{3
3759  if !exists("s:netrw_initbookhist")
3760   NetrwKeepj call s:NetrwBookHistRead()
3761  endif
3762
3763  " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
3764  if a:dirname !~ '^\a\{3,}://'
3765   let dirname= simplify(a:dirname)
3766"   call Decho("simplified dirname<".dirname.">")
3767  else
3768   let dirname= a:dirname
3769  endif
3770
3771  " repoint t:netrw_lexbufnr if appropriate
3772  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
3773"   call Decho("set repointlexbufnr to true!")
3774   let repointlexbufnr= 1
3775  endif
3776
3777  " s:NetrwBrowse : sanity checks: {{{3
3778  if exists("s:netrw_skipbrowse")
3779   unlet s:netrw_skipbrowse
3780"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("<slnum>"))
3781"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed")
3782   return
3783  endif
3784  if !exists("*shellescape")
3785   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3786"   call Dret("s:NetrwBrowse : missing shellescape()")
3787   return
3788  endif
3789  if !exists("*fnameescape")
3790   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3791"   call Dret("s:NetrwBrowse : missing fnameescape()")
3792   return
3793  endif
3794
3795  " s:NetrwBrowse : save options: {{{3
3796  call s:NetrwOptionsSave("w:")
3797
3798  " s:NetrwBrowse : re-instate any marked files {{{3
3799  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3800   if exists("s:netrwmarkfilelist_{bufnr('%')}")
3801"    call Decho("clearing marked files",'~'.expand("<slnum>"))
3802    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3803   endif
3804  endif
3805
3806  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
3807   " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3808"   call Decho("handle w:netrw_acdkeep:",'~'.expand("<slnum>"))
3809"   call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("<slnum>"))
3810   if s:NetrwLcd(dirname)
3811"    call Dret("s:NetrwBrowse : lcd failure")
3812    return
3813   endif
3814   "   call s:NetrwOptionsSafe() " tst952 failed with this enabled.
3815"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
3816
3817  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
3818   " s:NetrwBrowse :  remote regular file handler {{{3
3819"   call Decho("handle remote regular file: dirname<".dirname.">",'~'.expand("<slnum>"))
3820   if bufname(dirname) != ""
3821"    call Decho("edit buf#".bufname(dirname)." in win#".winnr(),'~'.expand("<slnum>"))
3822    exe "NetrwKeepj b ".bufname(dirname)
3823   else
3824    " attempt transfer of remote regular file
3825"    call Decho("attempt transfer as regular file<".dirname.">",'~'.expand("<slnum>"))
3826
3827    " remove any filetype indicator from end of dirname, except for the
3828    " "this is a directory" indicator (/).
3829    " There shouldn't be one of those here, anyway.
3830    let path= substitute(dirname,'[*=@|]\r\=$','','e')
3831"    call Decho("new path<".path.">",'~'.expand("<slnum>"))
3832    call s:RemotePathAnalysis(dirname)
3833
3834    " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3835    call s:NetrwEnew(dirname)
3836    call s:NetrwOptionsSafe(a:islocal)
3837    setl ma noro
3838"    call Decho("setl ma noro",'~'.expand("<slnum>"))
3839    let b:netrw_curdir = dirname
3840    let url            = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3841    call s:NetrwBufRename(url)
3842    exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3843    sil call netrw#NetRead(2,url)
3844    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3845"    call Decho("url<".url.">",'~'.expand("<slnum>"))
3846"    call Decho("s:path<".s:path.">",'~'.expand("<slnum>"))
3847"    call Decho("s:fname<".s:fname.">",'~'.expand("<slnum>"))
3848    if s:path =~ '.bz2'
3849     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3850    elseif s:path =~ '.gz'
3851     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3852    elseif s:path =~ '.gz'
3853     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3854    else
3855     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3856    endif
3857   endif
3858
3859   " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3860   call s:SetBufWinVars()
3861   call s:NetrwOptionsRestore("w:")
3862"   call Decho("setl ma nomod",'~'.expand("<slnum>"))
3863   setl ma nomod noro
3864"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3865
3866"   call Dret("s:NetrwBrowse : file<".s:fname.">")
3867   return
3868  endif
3869
3870  " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
3871  call s:UseBufWinVars()
3872
3873  " set up some variables {{{3
3874  let b:netrw_browser_active = 1
3875  let dirname                = dirname
3876  let s:last_sort_by         = g:netrw_sort_by
3877
3878  " set up menu {{{3
3879  NetrwKeepj call s:NetrwMenu(1)
3880
3881  " get/set-up buffer {{{3
3882"  call Decho("saving position across a buffer refresh",'~'.expand("<slnum>"))
3883  let svpos  = winsaveview()
3884"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3885  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
3886
3887  " maintain markfile highlighting
3888  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3889   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3890" "   call Decho("bufnr(%)=".bufnr('%'),'~'.expand("<slnum>"))
3891" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
3892    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3893   else
3894" "   call Decho("2match none",'~'.expand("<slnum>"))
3895    2match none
3896   endif
3897  endif
3898  if reusing && line("$") > 1
3899   call s:NetrwOptionsRestore("w:")
3900"   call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3901   setl noma nomod nowrap
3902"   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>"))
3903"   call Dret("s:NetrwBrowse : re-using not-cleared buffer")
3904   return
3905  endif
3906
3907  " set b:netrw_curdir to the new directory name {{{3
3908"  call Decho("set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")",'~'.expand("<slnum>"))
3909  let b:netrw_curdir= dirname
3910  if b:netrw_curdir =~ '[/\\]$'
3911   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
3912  endif
3913  if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
3914   let b:netrw_curdir= b:netrw_curdir."/"
3915  endif
3916  if b:netrw_curdir == ''
3917   if has("amiga")
3918    " On the Amiga, the empty string connotes the current directory
3919    let b:netrw_curdir= getcwd()
3920   else
3921    " under unix, when the root directory is encountered, the result
3922    " from the preceding substitute is an empty string.
3923    let b:netrw_curdir= '/'
3924   endif
3925  endif
3926  if !a:islocal && b:netrw_curdir !~ '/$'
3927   let b:netrw_curdir= b:netrw_curdir.'/'
3928  endif
3929"  call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
3930
3931  " ------------
3932  " (local only) {{{3
3933  " ------------
3934  if a:islocal
3935"   call Decho("local only:",'~'.expand("<slnum>"))
3936
3937   " Set up ShellCmdPost handling.  Append current buffer to browselist
3938   call s:LocalFastBrowser()
3939
3940  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3941   if !g:netrw_keepdir
3942"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
3943"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("<slnum>"))
3944    if !exists("&l:acd") || !&l:acd
3945     if s:NetrwLcd(b:netrw_curdir)
3946"      call Dret("s:NetrwBrowse : lcd failure")
3947      return
3948     endif
3949    endif
3950   endif
3951
3952  " --------------------------------
3953  " remote handling: {{{3
3954  " --------------------------------
3955  else
3956"   call Decho("remote only:",'~'.expand("<slnum>"))
3957
3958   " analyze dirname and g:netrw_list_cmd {{{3
3959"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>"))
3960   if dirname =~# "^NetrwTreeListing\>"
3961    let dirname= b:netrw_curdir
3962"    call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>"))
3963   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3964    let dirname= substitute(b:netrw_curdir,'\\','/','g')
3965    if dirname !~ '/$'
3966     let dirname= dirname.'/'
3967    endif
3968    let b:netrw_curdir = dirname
3969"    call Decho("(liststyle is TREELIST) dirname<".dirname.">",'~'.expand("<slnum>"))
3970   else
3971    let dirname = substitute(dirname,'\\','/','g')
3972"    call Decho("(normal) dirname<".dirname.">",'~'.expand("<slnum>"))
3973   endif
3974
3975   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3976   if dirname !~ dirpat
3977    if !exists("g:netrw_quiet")
3978     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3979    endif
3980    NetrwKeepj call s:NetrwOptionsRestore("w:")
3981"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3982    setl noma nomod nowrap
3983"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3984"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
3985    return
3986   endif
3987   let b:netrw_curdir= dirname
3988"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("<slnum>"))
3989  endif  " (additional remote handling)
3990
3991  " -------------------------------
3992  " Perform Directory Listing: {{{3
3993  " -------------------------------
3994  NetrwKeepj call s:NetrwMaps(a:islocal)
3995  NetrwKeepj call s:NetrwCommands(a:islocal)
3996  NetrwKeepj call s:PerformListing(a:islocal)
3997
3998  " restore option(s)
3999  call s:NetrwOptionsRestore("w:")
4000"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4001
4002  " If there is a rexposn: restore position with rexposn
4003  " Otherwise            : set rexposn
4004  if exists("s:rexposn_".bufnr("%"))
4005"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
4006   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
4007   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4008    NetrwKeepj exe w:netrw_bannercnt
4009   endif
4010  else
4011   NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
4012  endif
4013  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
4014   let &l:bexpr= "netrw#BalloonHelp()"
4015"   call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>"))
4016   setl beval
4017  endif
4018
4019  " repoint t:netrw_lexbufnr if appropriate
4020  if exists("repointlexbufnr")
4021   let t:netrw_lexbufnr= bufnr("%")
4022"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
4023  endif
4024
4025  " restore position
4026  if reusing
4027"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4028   call winrestview(svpos)
4029  endif
4030
4031  " The s:LocalBrowseRefresh() function is called by an autocmd
4032  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow or medium speed).
4033  " However, s:NetrwBrowse() causes the FocusGained event to fire the first time.
4034"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4035"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4036"  call Dret("s:NetrwBrowse : did PerformListing  ft<".&ft.">")
4037  return
4038endfun
4039
4040" ---------------------------------------------------------------------
4041" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
4042" may not apply correctly; ie. netrw's idea of the current directory may
4043" differ from vim's.  This function insures that netrw's idea of the current
4044" directory is used.
4045" Returns a path to the file specified by a:fname
4046fun! s:NetrwFile(fname)
4047"  "" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
4048"  "" call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
4049"  "" call Decho("g:netrw_cygwin   =".(exists("g:netrw_cygwin")?    g:netrw_cygwin    : 'n/a'),'~'.expand("<slnum>"))
4050"  "" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
4051"  "" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
4052
4053  " clean up any leading treedepthstring
4054  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4055   let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
4056"   "" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>"))
4057  else
4058   let fname= a:fname
4059  endif
4060
4061  if g:netrw_keepdir
4062   " vim's idea of the current directory possibly may differ from netrw's
4063   if !exists("b:netrw_curdir")
4064    let b:netrw_curdir= getcwd()
4065   endif
4066
4067   if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
4068    if fname =~ '^\' || fname =~ '^\a:\'
4069     " windows, but full path given
4070     let ret= fname
4071"     "" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4072    else
4073     " windows, relative path given
4074     let ret= s:ComposePath(b:netrw_curdir,fname)
4075"     "" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4076    endif
4077
4078   elseif fname =~ '^/'
4079    " not windows, full path given
4080    let ret= fname
4081"    "" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4082   else
4083    " not windows, relative path given
4084    let ret= s:ComposePath(b:netrw_curdir,fname)
4085"    "" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4086   endif
4087  else
4088   " vim and netrw agree on the current directory
4089   let ret= fname
4090"   "" call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
4091"   "" call Decho("vim   directory: ".getcwd(),'~'.expand("<slnum>"))
4092"   "" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>"))
4093  endif
4094
4095"  "" call Dret("s:NetrwFile ".ret)
4096  return ret
4097endfun
4098
4099" ---------------------------------------------------------------------
4100" s:NetrwFileInfo: supports qf (query for file information) {{{2
4101fun! s:NetrwFileInfo(islocal,fname)
4102"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
4103  let ykeep= @@
4104  if a:islocal
4105   let lsopt= "-lsad"
4106   if g:netrw_sizestyle =~# 'H'
4107    let lsopt= "-lsadh"
4108   elseif g:netrw_sizestyle =~# 'h'
4109    let lsopt= "-lsadh --si"
4110   endif
4111"   call Decho("(s:NetrwFileInfo) lsopt<".lsopt.">")
4112   if (has("unix") || has("macunix")) && executable("/bin/ls")
4113
4114    if getline(".") == "../"
4115     echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
4116"     call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
4117
4118    elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
4119     echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
4120"     call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
4121
4122    elseif exists("b:netrw_curdir")
4123      echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
4124"      call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
4125
4126    else
4127"     call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
4128     echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
4129"     call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
4130    endif
4131   else
4132    " use vim functions to return information about file below cursor
4133"    call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
4134    if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
4135     let fname= substitute(a:fname,".$","","")
4136    else
4137     let fname= a:fname
4138    endif
4139    let t  = getftime(s:NetrwFile(fname))
4140    let sz = getfsize(s:NetrwFile(fname))
4141    if g:netrw_sizestyle =~# "[hH]"
4142     let sz= s:NetrwHumanReadable(sz)
4143    endif
4144    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
4145"    call Decho("fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
4146   endif
4147  else
4148   echo "sorry, \"qf\" not supported yet for remote files"
4149  endif
4150  let @@= ykeep
4151"  call Dret("s:NetrwFileInfo")
4152endfun
4153
4154" ---------------------------------------------------------------------
4155" s:NetrwFullPath: returns the full path to a directory and/or file {{{2
4156fun! s:NetrwFullPath(filename)
4157"  " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)")
4158  let filename= a:filename
4159  if filename !~ '^/'
4160   let filename= resolve(getcwd().'/'.filename)
4161  endif
4162  if filename != "/" && filename =~ '/$'
4163   let filename= substitute(filename,'/$','','')
4164  endif
4165"  " call Dret("s:NetrwFullPath <".filename.">")
4166  return filename
4167endfun
4168
4169" ---------------------------------------------------------------------
4170" s:NetrwGetBuffer: [get a new|find an old netrw] buffer for a netrw listing {{{2
4171"   returns 0=cleared buffer
4172"           1=re-used buffer (buffer not cleared)
4173"  Nov 09, 2020: tst952 shows that when user does :set hidden that NetrwGetBuffer will come up with a [No Name] buffer (hid fix)
4174fun! s:NetrwGetBuffer(islocal,dirname)
4175"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
4176"  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." hid=".&hid,'~'.expand("<slnum>"))
4177"  call Decho("netrwbuf dictionary=".(exists("s:netrwbuf")? string(s:netrwbuf) : 'n/a'),'~'.expand("<slnum>"))
4178"  call Dredir("ls!","s:NetrwGetBuffer")
4179  let dirname= a:dirname
4180
4181  " re-use buffer if possible {{{3
4182"  call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
4183  if !exists("s:netrwbuf")
4184"   call Decho("  s:netrwbuf initialized to {}",'~'.expand("<slnum>"))
4185   let s:netrwbuf= {}
4186  endif
4187"  call Decho("  s:netrwbuf         =".string(s:netrwbuf),'~'.expand("<slnum>"))
4188"  call Decho("  w:netrw_liststyle  =".(exists("w:netrw_liststyle")? w:netrw_liststyle : "n/a"),'~'.expand("<slnum>"))
4189
4190  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4191   let bufnum = -1
4192
4193   if !empty(s:netrwbuf) && has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4194    if has_key(s:netrwbuf,"NetrwTreeListing")
4195     let bufnum= s:netrwbuf["NetrwTreeListing"]
4196    else
4197     let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4198    endif
4199"    call Decho("  NetrwTreeListing: bufnum#".bufnum,'~'.expand("<slnum>"))
4200    if !bufexists(bufnum)
4201     call remove(s:netrwbuf,"NetrwTreeListing"])
4202     let bufnum= -1
4203    endif
4204   elseif bufnr("NetrwTreeListing") != -1
4205    let bufnum= bufnr("NetrwTreeListing")
4206"    call Decho("  NetrwTreeListing".": bufnum#".bufnum,'~'.expand("<slnum>"))
4207   else
4208"    call Decho("  did not find a NetrwTreeListing buffer",'~'.expand("<slnum>"))
4209     let bufnum= -1
4210   endif
4211
4212  elseif has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4213   let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4214"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum,'~'.expand("<slnum>"))
4215   if !bufexists(bufnum)
4216    call remove(s:netrwbuf,s:NetrwFullPath(dirname))
4217    let bufnum= -1
4218   endif
4219
4220  else
4221"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key",'~'.expand("<slnum>"))
4222   let bufnum= -1
4223  endif
4224"  call Decho("  bufnum#".bufnum,'~'.expand("<slnum>"))
4225
4226  " hijack the current buffer
4227  "   IF the buffer already has the desired name
4228  "   AND it is empty
4229  let curbuf = bufname("%")
4230  if curbuf == '.'
4231   let curbuf = getcwd()
4232  endif
4233"  call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
4234"  call Decho("deciding if netrw may hijack the current buffer#".bufnr("%")."<".curbuf.">",'~'.expand("<slnum>"))
4235"  call Decho("..dirname<".dirname.">  IF dirname == bufname",'~'.expand("<slnum>"))
4236"  call Decho("..curbuf<".curbuf.">",'~'.expand("<slnum>"))
4237"  call Decho("..line($)=".line("$")." AND this is 1",'~'.expand("<slnum>"))
4238"  call Decho("..getline(%)<".getline("%").">  AND this line is empty",'~'.expand("<slnum>"))
4239  if dirname == curbuf && line("$") == 1 && getline("%") == ""
4240"   call Dret("s:NetrwGetBuffer 0<cleared buffer> : highjacking buffer#".bufnr("%"))
4241   return 0
4242  else  " DEBUG
4243"   call Decho("..did NOT hijack buffer",'~'.expand("<slnum>"))
4244  endif
4245  " Aug 14, 2021: was thinking about looking for a [No Name] buffer here and using it, but that might cause problems
4246
4247  " get enew buffer and name it -or- re-use buffer {{{3
4248  if bufnum < 0      " get enew buffer and name it
4249"   call Decho("--get enew buffer and name it  (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4250   call s:NetrwEnew(dirname)
4251"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4252   " name the buffer
4253   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4254    " Got enew buffer; transform into a NetrwTreeListing
4255"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4256    let w:netrw_treebufnr = bufnr("%")
4257    call s:NetrwBufRename("NetrwTreeListing")
4258    if g:netrw_use_noswf
4259     setl nobl bt=nofile noswf
4260    else
4261     setl nobl bt=nofile
4262    endif
4263    nnoremap <silent> <buffer> [[       :sil call <SID>TreeListMove('[[')<cr>
4264    nnoremap <silent> <buffer> ]]       :sil call <SID>TreeListMove(']]')<cr>
4265    nnoremap <silent> <buffer> []       :sil call <SID>TreeListMove('[]')<cr>
4266    nnoremap <silent> <buffer> ][       :sil call <SID>TreeListMove('][')<cr>
4267"    call Decho("  tree listing bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
4268   else
4269    call s:NetrwBufRename(dirname)
4270    " enter the new buffer into the s:netrwbuf dictionary
4271    let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%")
4272"    call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>"))
4273"    call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
4274   endif
4275"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4276
4277  else " Re-use the buffer
4278"   call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4279   let eikeep= &ei
4280   setl ei=all
4281   if getline(2) =~# '^" Netrw Directory Listing'
4282"    call Decho("  getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>"))
4283    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4284   else
4285"    call Decho("  getline(2)<".getline(2).'> does not match "Netrw Directory Listing" : using b '.bufnum,'~'.expand("<slnum>"))
4286    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4287   endif
4288"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
4289   if bufname("%") == '.'
4290    call s:NetrwBufRename(getcwd())
4291   endif
4292   let &ei= eikeep
4293
4294   if line("$") <= 1 && getline(1) == ""
4295    " empty buffer
4296    NetrwKeepj call s:NetrwListSettings(a:islocal)
4297"    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>"))
4298"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4299"    call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4300    return 0
4301
4302   elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4303"    call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4304    NetrwKeepj call s:NetrwListSettings(a:islocal)
4305    sil NetrwKeepj %d _
4306"    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>"))
4307"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4308"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4309    return 0
4310
4311   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4312"    call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4313"    call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4314    setl ma
4315    sil NetrwKeepj %d _
4316    NetrwKeepj call s:NetrwListSettings(a:islocal)
4317"    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>"))
4318"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4319"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4320    return 0
4321
4322   else
4323"    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>"))
4324"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4325"    call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4326    return 1
4327   endif
4328  endif
4329
4330  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4331  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
4332  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
4333  "  med    1         D      H
4334  "  fast   2         H      H
4335"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
4336  let fname= expand("%")
4337  NetrwKeepj call s:NetrwListSettings(a:islocal)
4338  call s:NetrwBufRename(fname)
4339
4340  " delete all lines from buffer {{{3
4341"  call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4342"  call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4343  sil! keepalt NetrwKeepj %d _
4344
4345"  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>"))
4346"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4347"  call Dret("s:NetrwGetBuffer 0<cleared buffer>")
4348  return 0
4349endfun
4350
4351" ---------------------------------------------------------------------
4352" s:NetrwGetcwd: get the current directory. {{{2
4353"   Change backslashes to forward slashes, if any.
4354"   If doesc is true, escape certain troublesome characters
4355fun! s:NetrwGetcwd(doesc)
4356"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
4357  let curdir= substitute(getcwd(),'\\','/','ge')
4358  if curdir !~ '[\/]$'
4359   let curdir= curdir.'/'
4360  endif
4361  if a:doesc
4362   let curdir= fnameescape(curdir)
4363  endif
4364"  call Dret("NetrwGetcwd <".curdir.">")
4365  return curdir
4366endfun
4367
4368" ---------------------------------------------------------------------
4369"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4370fun! s:NetrwGetWord()
4371"  call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4372"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4373  let keepsol= &l:sol
4374  setl nosol
4375
4376  call s:UseBufWinVars()
4377
4378  " insure that w:netrw_liststyle is set up
4379  if !exists("w:netrw_liststyle")
4380   if exists("g:netrw_liststyle")
4381    let w:netrw_liststyle= g:netrw_liststyle
4382   else
4383    let w:netrw_liststyle= s:THINLIST
4384   endif
4385"   call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
4386  endif
4387
4388  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4389   " Active Banner support
4390"   call Decho("active banner handling",'~'.expand("<slnum>"))
4391   NetrwKeepj norm! 0
4392   let dirname= "./"
4393   let curline= getline('.')
4394
4395   if curline =~# '"\s*Sorted by\s'
4396    NetrwKeepj norm! "_s
4397    let s:netrw_skipbrowse= 1
4398    echo 'Pressing "s" also works'
4399
4400   elseif curline =~# '"\s*Sort sequence:'
4401    let s:netrw_skipbrowse= 1
4402    echo 'Press "S" to edit sorting sequence'
4403
4404   elseif curline =~# '"\s*Quick Help:'
4405    NetrwKeepj norm! ?
4406    let s:netrw_skipbrowse= 1
4407
4408   elseif curline =~# '"\s*\%(Hiding\|Showing\):'
4409    NetrwKeepj norm! a
4410    let s:netrw_skipbrowse= 1
4411    echo 'Pressing "a" also works'
4412
4413   elseif line("$") > w:netrw_bannercnt
4414    exe 'sil NetrwKeepj '.w:netrw_bannercnt
4415   endif
4416
4417  elseif w:netrw_liststyle == s:THINLIST
4418"   call Decho("thin column handling",'~'.expand("<slnum>"))
4419   NetrwKeepj norm! 0
4420   let dirname= substitute(getline('.'),'\t -->.*$','','')
4421
4422  elseif w:netrw_liststyle == s:LONGLIST
4423"   call Decho("long column handling",'~'.expand("<slnum>"))
4424   NetrwKeepj norm! 0
4425   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
4426
4427  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4428"   call Decho("treelist handling",'~'.expand("<slnum>"))
4429   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4430   let dirname= substitute(dirname,'\t -->.*$','','')
4431
4432  else
4433"   call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4434   let dirname= getline('.')
4435
4436   if !exists("b:netrw_cpf")
4437    let b:netrw_cpf= 0
4438    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
4439    call histdel("/",-1)
4440"   "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4441   endif
4442
4443"   call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4444   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4445"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4446"   call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4447   if filestart == 0
4448    NetrwKeepj norm! 0ma
4449   else
4450    call cursor(line("."),filestart+1)
4451    NetrwKeepj norm! ma
4452   endif
4453   let rega= @a
4454   let eofname= filestart + b:netrw_cpf + 1
4455   if eofname <= col("$")
4456    call cursor(line("."),filestart+b:netrw_cpf+1)
4457    NetrwKeepj norm! "ay`a
4458   else
4459    NetrwKeepj norm! "ay$
4460   endif
4461   let dirname = @a
4462   let @a      = rega
4463"   call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4464   let dirname= substitute(dirname,'\s\+$','','e')
4465"   call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4466  endif
4467
4468  " symlinks are indicated by a trailing "@".  Remove it before further processing.
4469  let dirname= substitute(dirname,"@$","","")
4470
4471  " executables are indicated by a trailing "*".  Remove it before further processing.
4472  let dirname= substitute(dirname,"\*$","","")
4473
4474  let &l:sol= keepsol
4475
4476"  call Dret("s:NetrwGetWord <".dirname.">")
4477  return dirname
4478endfun
4479
4480" ---------------------------------------------------------------------
4481" s:NetrwListSettings: make standard settings for making a netrw listing {{{2
4482"                      g:netrw_bufsettings will be used after the listing is produced.
4483"                      Called by s:NetrwGetBuffer()
4484fun! s:NetrwListSettings(islocal)
4485"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4486"  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>"))
4487  let fname= bufname("%")
4488"  "  call Decho("setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
4489  "              nobl noma nomod nonu noma nowrap ro   nornu  (std g:netrw_bufsettings)
4490  setl bt=nofile nobl ma         nonu      nowrap noro nornu
4491  call s:NetrwBufRename(fname)
4492  if g:netrw_use_noswf
4493   setl noswf
4494  endif
4495"  call Dredir("ls!","s:NetrwListSettings")
4496"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
4497  exe "setl ts=".(g:netrw_maxfilenamelen+1)
4498  setl isk+=.,~,-
4499  if g:netrw_fastbrowse > a:islocal
4500   setl bh=hide
4501  else
4502   setl bh=delete
4503  endif
4504"  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>"))
4505"  call Dret("s:NetrwListSettings")
4506endfun
4507
4508" ---------------------------------------------------------------------
4509"  s:NetrwListStyle: change list style (thin - long - wide - tree) {{{2
4510"  islocal=0: remote browsing
4511"         =1: local browsing
4512fun! s:NetrwListStyle(islocal)
4513"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
4514
4515  let ykeep             = @@
4516  let fname             = s:NetrwGetWord()
4517  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
4518  let svpos            = winsaveview()
4519"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4520  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
4521"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
4522"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>"))
4523"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
4524
4525  " repoint t:netrw_lexbufnr if appropriate
4526  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
4527"   call Decho("set repointlexbufnr to true!")
4528   let repointlexbufnr= 1
4529  endif
4530
4531  if w:netrw_liststyle == s:THINLIST
4532   " use one column listing
4533"   call Decho("use one column list",'~'.expand("<slnum>"))
4534   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4535
4536  elseif w:netrw_liststyle == s:LONGLIST
4537   " use long list
4538"   call Decho("use long list",'~'.expand("<slnum>"))
4539   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
4540
4541  elseif w:netrw_liststyle == s:WIDELIST
4542   " give wide list
4543"   call Decho("use wide list",'~'.expand("<slnum>"))
4544   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4545
4546  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4547"   call Decho("use tree list",'~'.expand("<slnum>"))
4548   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4549
4550  else
4551   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4552   let g:netrw_liststyle = s:THINLIST
4553   let w:netrw_liststyle = g:netrw_liststyle
4554   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
4555  endif
4556  setl ma noro
4557"  call Decho("setl ma noro",'~'.expand("<slnum>"))
4558
4559  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
4560"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4561  sil! NetrwKeepj %d _
4562  " following prevents tree listing buffer from being marked "modified"
4563"  call Decho("setl nomod",'~'.expand("<slnum>"))
4564  setl nomod
4565"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4566
4567  " refresh the listing
4568"  call Decho("refresh the listing",'~'.expand("<slnum>"))
4569  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4570  NetrwKeepj call s:NetrwCursor(0)
4571
4572  " repoint t:netrw_lexbufnr if appropriate
4573  if exists("repointlexbufnr")
4574   let t:netrw_lexbufnr= bufnr("%")
4575"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
4576  endif
4577
4578  " restore position; keep cursor on the filename
4579"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4580  NetrwKeepj call winrestview(svpos)
4581  let @@= ykeep
4582
4583"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
4584endfun
4585
4586" ---------------------------------------------------------------------
4587" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4588fun! s:NetrwBannerCtrl(islocal)
4589"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
4590
4591  let ykeep= @@
4592  " toggle the banner (enable/suppress)
4593  let g:netrw_banner= !g:netrw_banner
4594
4595  " refresh the listing
4596  let svpos= winsaveview()
4597"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4598  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4599
4600  " keep cursor on the filename
4601  if g:netrw_banner && exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt
4602   let fname= s:NetrwGetWord()
4603   sil NetrwKeepj $
4604   let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4605" "  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4606   if result <= 0 && exists("w:netrw_bannercnt")
4607    exe "NetrwKeepj ".w:netrw_bannercnt
4608   endif
4609  endif
4610  let @@= ykeep
4611"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
4612endfun
4613
4614" ---------------------------------------------------------------------
4615" s:NetrwBookmark: supports :NetrwMB[!] [file]s                 {{{2
4616"
4617"  No bang: enters files/directories into Netrw's bookmark system
4618"   No argument and in netrw buffer:
4619"     if there are marked files: bookmark marked files
4620"     otherwise                : bookmark file/directory under cursor
4621"   No argument and not in netrw buffer: bookmarks current open file
4622"   Has arguments: globs them individually and bookmarks them
4623"
4624"  With bang: deletes files/directories from Netrw's bookmark system
4625fun! s:NetrwBookmark(del,...)
4626"  call Dfunc("s:NetrwBookmark(del=".a:del.",...) a:0=".a:0)
4627  if a:0 == 0
4628   if &ft == "netrw"
4629    let curbufnr = bufnr("%")
4630
4631    if exists("s:netrwmarkfilelist_{curbufnr}")
4632     " for every filename in the marked list
4633"     call Decho("bookmark every filename in marked list",'~'.expand("<slnum>"))
4634     let svpos  = winsaveview()
4635"     call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4636     let islocal= expand("%") !~ '^\a\{3,}://'
4637     for fname in s:netrwmarkfilelist_{curbufnr}
4638      if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4639     endfor
4640     let curdir  = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4641     call s:NetrwUnmarkList(curbufnr,curdir)
4642     NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./'))
4643"     call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4644     NetrwKeepj call winrestview(svpos)
4645    else
4646     let fname= s:NetrwGetWord()
4647     if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4648    endif
4649
4650   else
4651    " bookmark currently open file
4652"    call Decho("bookmark currently open file",'~'.expand("<slnum>"))
4653    let fname= expand("%")
4654    if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4655   endif
4656
4657  else
4658   " bookmark specified files
4659   "  attempts to infer if working remote or local
4660   "  by deciding if the current file begins with an url
4661   "  Globbing cannot be done remotely.
4662   let islocal= expand("%") !~ '^\a\{3,}://'
4663"   call Decho("bookmark specified file".((a:0>1)? "s" : ""),'~'.expand("<slnum>"))
4664   let i = 1
4665   while i <= a:0
4666    if islocal
4667     if v:version > 704 || (v:version == 704 && has("patch656"))
4668      let mbfiles= glob(fnameescape(a:{i}),0,1,1)
4669     else
4670      let mbfiles= glob(fnameescape(a:{i}),0,1)
4671     endif
4672    else
4673     let mbfiles= [a:{i}]
4674    endif
4675"    call Decho("mbfiles".string(mbfiles),'~'.expand("<slnum>"))
4676    for mbfile in mbfiles
4677"     call Decho("mbfile<".mbfile.">",'~'.expand("<slnum>"))
4678     if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4679    endfor
4680    let i= i + 1
4681   endwhile
4682  endif
4683
4684  " update the menu
4685  call s:NetrwBookmarkMenu()
4686
4687"  call Dret("s:NetrwBookmark")
4688endfun
4689
4690" ---------------------------------------------------------------------
4691" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4692"                      .2.[cnt] for bookmarks, and
4693"                      .3.[cnt] for history
4694"                      (see s:NetrwMenu())
4695fun! s:NetrwBookmarkMenu()
4696  if !exists("s:netrw_menucnt")
4697   return
4698  endif
4699"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhistcnt." menucnt=".s:netrw_menucnt)
4700
4701  " the following test assures that gvim is running, has menus available, and has menus enabled.
4702  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
4703   if exists("g:NetrwTopLvlMenu")
4704"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4705    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4706    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4707   endif
4708   if !exists("s:netrw_initbookhist")
4709    call s:NetrwBookHistRead()
4710   endif
4711
4712   " show bookmarked places
4713   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4714    let cnt= 1
4715    for bmd in g:netrw_bookmarklist
4716"     call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd,'~'.expand("<slnum>"))
4717     let bmd= escape(bmd,g:netrw_menu_escape)
4718
4719     " show bookmarks for goto menu
4720     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
4721
4722     " show bookmarks for deletion menu
4723     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
4724     let cnt= cnt + 1
4725    endfor
4726
4727   endif
4728
4729   " show directory browsing history
4730   if g:netrw_dirhistmax > 0
4731    let cnt     = g:netrw_dirhistcnt
4732    let first   = 1
4733    let histcnt = 0
4734    while ( first || cnt != g:netrw_dirhistcnt )
4735     let histcnt  = histcnt + 1
4736     let priority = g:netrw_dirhistcnt + histcnt
4737     if exists("g:netrw_dirhist_{cnt}")
4738      let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4739"     call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir,'~'.expand("<slnum>"))
4740      exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
4741     endif
4742     let first = 0
4743     let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
4744     if cnt < 0
4745      let cnt= cnt + g:netrw_dirhistmax
4746     endif
4747    endwhile
4748   endif
4749
4750  endif
4751"  call Dret("NetrwBookmarkMenu")
4752endfun
4753
4754" ---------------------------------------------------------------------
4755"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4756"                       directory and a new directory name.  Also, if the
4757"                       "new directory name" is actually a file,
4758"                       NetrwBrowseChgDir() edits the file.
4759fun! s:NetrwBrowseChgDir(islocal,newdir,...)
4760"  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 : "").">")
4761"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4762
4763  let ykeep= @@
4764  if !exists("b:netrw_curdir")
4765   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4766   " and the current window is the NetrwMessage window.
4767   let @@= ykeep
4768"   call Decho("b:netrw_curdir doesn't exist!",'~'.expand("<slnum>"))
4769"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
4770"   call Dredir("ls!","s:NetrwBrowseChgDir")
4771"   call Dret("s:NetrwBrowseChgDir")
4772   return
4773  endif
4774"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
4775
4776  " NetrwBrowseChgDir; save options and initialize {{{3
4777"  call Decho("saving options",'~'.expand("<slnum>"))
4778  call s:SavePosn(s:netrw_posn)
4779  NetrwKeepj call s:NetrwOptionsSave("s:")
4780  NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
4781  if (has("win32") || has("win95") || has("win64") || has("win16"))
4782   let dirname = substitute(b:netrw_curdir,'\\','/','ge')
4783  else
4784   let dirname = b:netrw_curdir
4785  endif
4786  let newdir    = a:newdir
4787  let dolockout = 0
4788  let dorestore = 1
4789"  call Decho("win#".winnr(),'~'.expand("<slnum>"))
4790"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
4791"  call Decho("newdir<".newdir.">",'~'.expand("<slnum>"))
4792
4793  " ignore <cr>s when done in the banner
4794"  call Decho('(s:NetrwBrowseChgDir) ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("<slnum>"))
4795  if g:netrw_banner
4796"   call Decho("win#".winnr()." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>"))
4797   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4798    if getline(".") =~# 'Quick Help'
4799"     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>"))
4800     let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4801"     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>"))
4802     setl ma noro nowrap
4803     NetrwKeepj call setline(line('.'),'"   Quick Help: <F1>:help  '.s:QuickHelp[g:netrw_quickhelp])
4804     setl noma nomod nowrap
4805     NetrwKeepj call s:NetrwOptionsRestore("s:")
4806"     call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4807    endif
4808   endif
4809"  else " Decho
4810"   call Decho("g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("<slnum>"))
4811  endif
4812
4813  " set up o/s-dependent directory recognition pattern
4814  if has("amiga")
4815   let dirpat= '[\/:]$'
4816  else
4817   let dirpat= '[\/]$'
4818  endif
4819"  call Decho("set up o/s-dependent directory recognition pattern: dirname<".dirname.">  dirpat<".dirpat.">",'~'.expand("<slnum>"))
4820
4821  if dirname !~ dirpat
4822   " apparently vim is "recognizing" that it is in a directory and
4823   " is removing the trailing "/".  Bad idea, so let's put it back.
4824   let dirname= dirname.'/'
4825"   call Decho("adjusting dirname<".dirname.'>  (put trailing "/" back)','~'.expand("<slnum>"))
4826  endif
4827
4828"  call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>"))
4829  if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
4830   " ------------------------------
4831   " NetrwBrowseChgDir: edit a file {{{3
4832   " ------------------------------
4833"   call Decho('edit-a-file: case "handling a file": win#'.winnr().' newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>"))
4834
4835   " save position for benefit of Rexplore
4836   let s:rexposn_{bufnr("%")}= winsaveview()
4837"   call Decho("edit-a-file: saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
4838"   call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
4839"   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>"))
4840
4841   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4842"    call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("<slnum>"))
4843"    call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("<slnum>"))
4844"    let newdir = s:NetrwTreePath(s:netrw_treetop)
4845"    call Decho("edit-a-file: COMBAK why doesn't this recognize file1's directory???")
4846    let dirname= s:NetrwTreeDir(a:islocal)
4847    "COMBAK : not working for a symlink -- but what about a regular file? a directory?
4848"    call Decho("COMBAK : not working for a symlink -- but what about a regular file? a directory?")
4849    " Feb 17, 2019: following if-else-endif restored -- wasn't editing a file in tree mode
4850    if dirname =~ '/$'
4851     let dirname= dirname.newdir
4852    else
4853     let dirname= dirname."/".newdir
4854    endif
4855"    call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>"))
4856"    call Decho("edit-a-file: tree listing",'~'.expand("<slnum>"))
4857   elseif newdir =~ '^\(/\|\a:\)'
4858"    call Decho("edit-a-file: handle an url or path starting with /: <".newdir.">",'~'.expand("<slnum>"))
4859    let dirname= newdir
4860   else
4861    let dirname= s:ComposePath(dirname,newdir)
4862   endif
4863"   call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>"))
4864   " this lets netrw#BrowseX avoid the edit
4865   if a:0 < 1
4866"    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>"))
4867    NetrwKeepj call s:NetrwOptionsRestore("s:")
4868    let curdir= b:netrw_curdir
4869    if !exists("s:didsplit")
4870"     "     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>"))
4871     if type(g:netrw_browse_split) == 3
4872      " open file in server
4873      " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4874"      call Decho("edit-a-file: open file in server",'~'.expand("<slnum>"))
4875      call s:NetrwServerEdit(a:islocal,dirname)
4876"      call Dret("s:NetrwBrowseChgDir")
4877      return
4878
4879     elseif g:netrw_browse_split == 1
4880      " horizontally splitting the window first
4881"      call Decho("edit-a-file: horizontally splitting window prior to edit",'~'.expand("<slnum>"))
4882      let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
4883      exe "keepalt ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
4884      if !&ea
4885       keepalt wincmd _
4886      endif
4887      call s:SetRexDir(a:islocal,curdir)
4888
4889     elseif g:netrw_browse_split == 2
4890      " vertically splitting the window first
4891"      call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>"))
4892      let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
4893      exe "keepalt ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
4894      if !&ea
4895       keepalt wincmd |
4896      endif
4897      call s:SetRexDir(a:islocal,curdir)
4898
4899     elseif g:netrw_browse_split == 3
4900      " open file in new tab
4901"      call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>"))
4902      keepalt tabnew
4903      if !exists("b:netrw_curdir")
4904       let b:netrw_curdir= getcwd()
4905      endif
4906      call s:SetRexDir(a:islocal,curdir)
4907
4908     elseif g:netrw_browse_split == 4
4909      " act like "P" (ie. open previous window)
4910"      call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>"))
4911      if s:NetrwPrevWinOpen(2) == 3
4912       let @@= ykeep
4913"       call Dret("s:NetrwBrowseChgDir")
4914       return
4915      endif
4916      call s:SetRexDir(a:islocal,curdir)
4917
4918     else
4919      " handling a file, didn't split, so remove menu
4920"      call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>"))
4921      call s:NetrwMenu(0)
4922      " optional change to window
4923      if g:netrw_chgwin >= 1
4924"       call Decho("edit-a-file: changing window to #".g:netrw_chgwin.": (due to g:netrw_chgwin)",'~'.expand("<slnum>"))
4925       if winnr("$")+1 == g:netrw_chgwin
4926	" if g:netrw_chgwin is set to one more than the last window, then
4927	" vertically split the last window to make that window available.
4928	let curwin= winnr()
4929	exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4930	vs
4931	exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4932       endif
4933       exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4934      endif
4935      call s:SetRexDir(a:islocal,curdir)
4936     endif
4937
4938    endif
4939
4940    " the point where netrw actually edits the (local) file
4941    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4942    " no keepalt to support  :e #  to return to a directory listing
4943    if !&mod
4944     " if e the new file would fail due to &mod, then don't change any of the flags
4945     let dolockout= 1
4946    endif
4947    if a:islocal
4948"     call Decho("edit-a-file: edit local file: exe e! ".fnameescape(dirname),'~'.expand("<slnum>"))
4949     " some like c-^ to return to the last edited file
4950     " others like c-^ to return to the netrw buffer
4951     " Apr 30, 2020: used to have e! here.  That can cause loss of a modified file,
4952     " so emit error E37 instead.
4953     if exists("g:netrw_altfile") && g:netrw_altfile
4954      exe "NetrwKeepj keepalt e ".fnameescape(dirname)
4955     else
4956      exe "NetrwKeepj e ".fnameescape(dirname)
4957     endif
4958"     call Decho("edit-a-file: after e! ".dirname.": hidden=".&hidden." bufhidden<".&bufhidden."> mod=".&mod,'~'.expand("<slnum>"))
4959     " COMBAK -- cuc cul related
4960     call s:NetrwCursor(1)
4961     if &hidden || &bufhidden == "hide"
4962      " file came from vim's hidden storage.  Don't "restore" options with it.
4963      let dorestore= 0
4964     endif
4965    else
4966"     call Decho("edit-a-file: remote file: NetrwBrowse will edit it",'~'.expand("<slnum>"))
4967    endif
4968
4969    " handle g:Netrw_funcref -- call external-to-netrw functions
4970    "   This code will handle g:Netrw_funcref as an individual function reference
4971    "   or as a list of function references.  It will ignore anything that's not
4972    "   a function reference.  See  :help Funcref  for information about function references.
4973    if exists("g:Netrw_funcref")
4974"     call Decho("edit-a-file: handle optional Funcrefs",'~'.expand("<slnum>"))
4975     if type(g:Netrw_funcref) == 2
4976"      call Decho("edit-a-file: handling a g:Netrw_funcref",'~'.expand("<slnum>"))
4977      NetrwKeepj call g:Netrw_funcref()
4978     elseif type(g:Netrw_funcref) == 3
4979"      call Decho("edit-a-file: handling a list of g:Netrw_funcrefs",'~'.expand("<slnum>"))
4980      for Fncref in g:Netrw_funcref
4981       if type(Fncref) == 2
4982        NetrwKeepj call Fncref()
4983       endif
4984      endfor
4985     endif
4986    endif
4987   endif
4988
4989  elseif newdir =~ '^/'
4990   " ----------------------------------------------------
4991   " NetrwBrowseChgDir: just go to the new directory spec {{{3
4992   " ----------------------------------------------------
4993"   call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("<slnum>"))
4994   let dirname = newdir
4995   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4996   NetrwKeepj call s:NetrwOptionsRestore("s:")
4997   norm! m`
4998
4999  elseif newdir == './'
5000   " ---------------------------------------------
5001   " NetrwBrowseChgDir: refresh the directory list {{{3
5002   " ---------------------------------------------
5003"   call Decho('(s:NetrwBrowseChgDir)refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("<slnum>"))
5004   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5005   norm! m`
5006
5007  elseif newdir == '../'
5008   " --------------------------------------
5009   " NetrwBrowseChgDir: go up one directory {{{3
5010   " --------------------------------------
5011"   call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../"','~'.expand("<slnum>"))
5012
5013   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5014    " force a refresh
5015"    call Decho("go-up: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
5016"    call Decho("go-up: setl noro ma",'~'.expand("<slnum>"))
5017    setl noro ma
5018    NetrwKeepj %d _
5019   endif
5020
5021   if has("amiga")
5022    " amiga
5023"    call Decho('go-up: case "go up one directory": newdir == "../" and amiga','~'.expand("<slnum>"))
5024    if a:islocal
5025     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
5026     let dirname= substitute(dirname,'/$','','')
5027    else
5028     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
5029    endif
5030"    call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5031
5032   elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
5033    " windows
5034    if a:islocal
5035     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
5036     if dirname == ""
5037      let dirname= '/'
5038     endif
5039    else
5040     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
5041    endif
5042    if dirname =~ '^\a:$'
5043     let dirname= dirname.'/'
5044    endif
5045"    call Decho("go-up: windows: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5046
5047   else
5048    " unix or cygwin
5049"    call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("<slnum>"))
5050    if a:islocal
5051     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
5052     if dirname == ""
5053      let dirname= '/'
5054     endif
5055    else
5056     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
5057    endif
5058"    call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5059   endif
5060   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5061   norm! m`
5062
5063  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5064   " --------------------------------------
5065   " NetrwBrowseChgDir: Handle Tree Listing {{{3
5066   " --------------------------------------
5067"   call Decho('(s:NetrwBrowseChgDir)tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("<slnum>"))
5068   " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
5069"   call Decho("tree-list: setl noro ma",'~'.expand("<slnum>"))
5070   setl noro ma
5071   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
5072"    call Decho("tree-list: clear buffer<".expand("%")."> with :%d  (force refresh)",'~'.expand("<slnum>"))
5073    NetrwKeepj %d _
5074   endif
5075   let treedir      = s:NetrwTreeDir(a:islocal)
5076"   call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>"))
5077   let s:treecurpos = winsaveview()
5078   let haskey       = 0
5079"   call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
5080
5081   " search treedict for tree dir as-is
5082"   call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("<slnum>"))
5083   if has_key(w:netrw_treedict,treedir)
5084"    call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>"))
5085    let haskey= 1
5086   else
5087"    call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
5088   endif
5089
5090   " search treedict for treedir with a [/@] appended
5091"   call Decho("tree-list: search treedict for treedir with a [/@] appended",'~'.expand("<slnum>"))
5092   if !haskey && treedir !~ '[/@]$'
5093    if has_key(w:netrw_treedict,treedir."/")
5094     let treedir= treedir."/"
5095"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
5096     let haskey = 1
5097    else
5098"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("<slnum>"))
5099    endif
5100   endif
5101
5102   " search treedict for treedir with any trailing / elided
5103"   call Decho("tree-list: search treedict for treedir with any trailing / elided",'~'.expand("<slnum>"))
5104   if !haskey && treedir =~ '/$'
5105    let treedir= substitute(treedir,'/$','','')
5106    if has_key(w:netrw_treedict,treedir)
5107"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
5108     let haskey = 1
5109    else
5110"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
5111    endif
5112   endif
5113
5114"   call Decho("haskey=".haskey,'~'.expand("<slnum>"))
5115   if haskey
5116    " close tree listing for selected subdirectory
5117"    call Decho("tree-list: closing selected subdirectory<".dirname.">",'~'.expand("<slnum>"))
5118    call remove(w:netrw_treedict,treedir)
5119"    call Decho("tree-list: removed     entry<".treedir."> from treedict",'~'.expand("<slnum>"))
5120"    call Decho("tree-list: yielding treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
5121    let dirname= w:netrw_treetop
5122   else
5123    " go down one directory
5124    let dirname= substitute(treedir,'/*$','/','')
5125"    call Decho("tree-list: go down one dir: treedir<".treedir.">",'~'.expand("<slnum>"))
5126"    call Decho("tree-list: ...            : dirname<".dirname.">",'~'.expand("<slnum>"))
5127   endif
5128   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5129"   call Decho("setting s:treeforceredraw to true",'~'.expand("<slnum>"))
5130   let s:treeforceredraw = 1
5131
5132  else
5133   " ----------------------------------------
5134   " NetrwBrowseChgDir: Go down one directory {{{3
5135   " ----------------------------------------
5136   let dirname    = s:ComposePath(dirname,newdir)
5137"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("<slnum>"))
5138   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5139   norm! m`
5140  endif
5141
5142 " --------------------------------------
5143 " NetrwBrowseChgDir: Restore and Cleanup {{{3
5144 " --------------------------------------
5145  if dorestore
5146   " dorestore is zero'd when a local file was hidden or bufhidden;
5147   " in such a case, we want to keep whatever settings it may have.
5148"   call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("<slnum>"))
5149   NetrwKeepj call s:NetrwOptionsRestore("s:")
5150"  else " Decho
5151"   call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>"))
5152  endif
5153  if dolockout && dorestore
5154"   call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>"))
5155   if filewritable(dirname)
5156"    call Decho("restore: doing modification lockout settings: ma nomod noro",'~'.expand("<slnum>"))
5157"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5158    setl ma noro nomod
5159"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5160   else
5161"    call Decho("restore: doing modification lockout settings: ma nomod ro",'~'.expand("<slnum>"))
5162"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5163    setl ma ro nomod
5164"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5165   endif
5166  endif
5167  call s:RestorePosn(s:netrw_posn)
5168  let @@= ykeep
5169
5170"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
5171  return dirname
5172endfun
5173
5174" ---------------------------------------------------------------------
5175" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
5176"    for thin, long, and wide: cursor placed just after banner
5177"    for tree, keeps cursor on current filename
5178fun! s:NetrwBrowseUpDir(islocal)
5179"  call Dfunc("s:NetrwBrowseUpDir(islocal=".a:islocal.")")
5180  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
5181   " this test needed because occasionally this function seems to be incorrectly called
5182   " when multiple leftmouse clicks are taken when atop the one line help in the banner.
5183   " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
5184   " directories.
5185"   call Dret("s:NetrwBrowseUpDir : cursor not in file area")
5186   return
5187  endif
5188
5189  norm! 0
5190  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5191"   call Decho("case: treestyle",'~'.expand("<slnum>"))
5192   let curline= getline(".")
5193   let swwline= winline() - 1
5194   if exists("w:netrw_treetop")
5195    let b:netrw_curdir= w:netrw_treetop
5196   elseif exists("b:netrw_curdir")
5197    let w:netrw_treetop= b:netrw_curdir
5198   else
5199    let w:netrw_treetop= getcwd()
5200    let b:netrw_curdir = w:netrw_treetop
5201   endif
5202   let curfile = getline(".")
5203   let curpath = s:NetrwTreePath(w:netrw_treetop)
5204   if a:islocal
5205    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5206   else
5207    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5208   endif
5209"   call Decho("looking for curfile<^".s:treedepthstring.curfile.">",'~'.expand("<slnum>"))
5210"   call Decho("having      curpath<".curpath.">",'~'.expand("<slnum>"))
5211   if w:netrw_treetop == '/'
5212     keepj call search('^\M'.curfile,"w")
5213   elseif curfile == '../'
5214     keepj call search('^\M'.curfile,"wb")
5215   else
5216"    call Decho("search(^\\M".s:treedepthstring.curfile.") backwards"))
5217    while 1
5218     keepj call search('^\M'.s:treedepthstring.curfile,"wb")
5219     let treepath= s:NetrwTreePath(w:netrw_treetop)
5220"     call Decho("..current treepath<".treepath.">",'~'.expand("<slnum>"))
5221     if treepath == curpath
5222      break
5223     endif
5224    endwhile
5225   endif
5226
5227  else
5228"   call Decho("case: not treestyle",'~'.expand("<slnum>"))
5229   call s:SavePosn(s:netrw_posn)
5230   if exists("b:netrw_curdir")
5231    let curdir= b:netrw_curdir
5232   else
5233    let curdir= expand(getcwd())
5234   endif
5235   if a:islocal
5236    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5237   else
5238    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5239   endif
5240   call s:RestorePosn(s:netrw_posn)
5241   let curdir= substitute(curdir,'^.*[\/]','','')
5242   call search('\<'.curdir.'/','wc')
5243  endif
5244"  call Dret("s:NetrwBrowseUpDir")
5245endfun
5246
5247" ---------------------------------------------------------------------
5248" netrw#BrowseX:  (implements "x" and "gx") executes a special "viewer" script or program for the {{{2
5249"              given filename; typically this means given their extension.
5250"              0=local, 1=remote
5251fun! netrw#BrowseX(fname,remote)
5252  let use_ctrlo= 1
5253"  call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")  implements x and gx maps")
5254
5255  if a:remote == 0 && isdirectory(a:fname)
5256   " if its really just a local directory, then do a "gf" instead
5257"   call Decho("remote≡0 and a:fname<".a:fname."> ".(isdirectory(a:fname)? "is a directory" : "is not a directory"),'~'.expand("<slnum>"))
5258"   call Decho("..appears to be a local directory; using e ".a:fname." instead",'~'.expand("<slnum>"))
5259   exe "e ".a:fname
5260"   call Dret("netrw#BrowseX")
5261   return
5262  elseif a:remote == 1 && a:fname !~ '^https\=:' && a:fname =~ '/$'
5263   " remote directory, not a webpage access, looks like an attempt to do a directory listing
5264"   call Decho("remote≡1 and a:fname<".a:fname.">",'~'.expand("<slnum>"))
5265"   call Decho("..and fname ".((a:fname =~ '^https\=:')? 'matches' : 'does not match').'^https\=:','~'.expand("<slnum>"))
5266"   call Decho("..and fname ".((a:fname =~ '/$')?        'matches' : 'does not match').' /$','~'.expand("<slnum>"))
5267"   call Decho("..appears to be a remote directory listing request; using gf instead",'~'.expand("<slnum>"))
5268   norm! gf
5269"   call Dret("netrw#BrowseX")
5270   return
5271  endif
5272"  call Decho("not a local file nor a webpage request",'~'.expand("<slnum>"))
5273
5274  if exists("g:netrw_browsex_viewer") && exists("g:netrw_browsex_support_remote") && !g:netrw_browsex_support_remote
5275    let remote = a:remote
5276  else
5277    let remote = 0
5278  endif
5279
5280  let ykeep      = @@
5281  let screenposn = winsaveview()
5282"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5283
5284  " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
5285  let awkeep     = &aw
5286  set noaw
5287
5288  " special core dump handler
5289  if a:fname =~ '/core\(\.\d\+\)\=$'
5290   if exists("g:Netrw_corehandler")
5291    if type(g:Netrw_corehandler) == 2
5292     " g:Netrw_corehandler is a function reference (see :help Funcref)
5293"     call Decho("g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
5294     call g:Netrw_corehandler(s:NetrwFile(a:fname))
5295    elseif type(g:Netrw_corehandler) == 3
5296     " g:Netrw_corehandler is a List of function references (see :help Funcref)
5297"     call Decho("g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
5298     for Fncref in g:Netrw_corehandler
5299      if type(FncRef) == 2
5300       call FncRef(a:fname)
5301      endif
5302     endfor
5303    endif
5304"    call Decho("restoring posn: screenposn<".string(screenposn).">,'~'.expand("<slnum>"))"
5305    call winrestview(screenposn)
5306    let @@= ykeep
5307    let &aw= awkeep
5308"    call Dret("netrw#BrowseX : coredump handler invoked")
5309    return
5310   endif
5311  endif
5312
5313  " set up the filename
5314  " (lower case the extension, make a local copy of a remote file)
5315  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5316  if has("win32") || has("win95") || has("win64") || has("win16")
5317   let exten= substitute(exten,'^.*$','\L&\E','')
5318  endif
5319  if exten =~ "[\\/]"
5320   let exten= ""
5321  endif
5322"  call Decho("exten<".exten.">",'~'.expand("<slnum>"))
5323
5324  if remote == 1
5325   " create a local copy
5326"   call Decho("remote: remote=".remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
5327   setl bh=delete
5328   call netrw#NetRead(3,a:fname)
5329   " attempt to rename tempfile
5330   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5331   let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5332"   call Decho("basename<".basename.">",'~'.expand("<slnum>"))
5333"   call Decho("newname <".newname.">",'~'.expand("<slnum>"))
5334   if s:netrw_tmpfile != newname && newname != ""
5335    if rename(s:netrw_tmpfile,newname) == 0
5336     " renaming succeeded
5337"     call Decho("renaming succeeded (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5338     let fname= newname
5339    else
5340     " renaming failed
5341"     call Decho("renaming failed (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5342     let fname= s:netrw_tmpfile
5343    endif
5344   else
5345    let fname= s:netrw_tmpfile
5346   endif
5347  else
5348"   call Decho("local: remote=".remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
5349   let fname= a:fname
5350   " special ~ handler for local
5351   if fname =~ '^\~' && expand("$HOME") != ""
5352"    call Decho('invoking special ~ handler','~'.expand("<slnum>"))
5353    let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5354   endif
5355  endif
5356"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
5357"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
5358
5359  " set up redirection (avoids browser messages)
5360  " by default, g:netrw_suppress_gx_mesg is true
5361  if g:netrw_suppress_gx_mesg
5362   if &srr =~ "%s"
5363    if (has("win32") || has("win95") || has("win64") || has("win16"))
5364     let redir= substitute(&srr,"%s","nul","")
5365    else
5366     let redir= substitute(&srr,"%s","/dev/null","")
5367    endif
5368   elseif (has("win32") || has("win95") || has("win64") || has("win16"))
5369    let redir= &srr . "nul"
5370   else
5371    let redir= &srr . "/dev/null"
5372   endif
5373  endif
5374"  call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
5375
5376  " extract any viewing options.  Assumes that they're set apart by spaces.
5377  if exists("g:netrw_browsex_viewer")
5378"   call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5379   if g:netrw_browsex_viewer =~ '\s'
5380    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5381    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5382    let oviewer = ''
5383    let cnt     = 1
5384    while !executable(viewer) && viewer != oviewer
5385     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5386     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5387     let cnt     = cnt + 1
5388     let oviewer = viewer
5389"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5390    endwhile
5391   else
5392    let viewer  = g:netrw_browsex_viewer
5393    let viewopt = ""
5394   endif
5395"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5396  endif
5397
5398  " execute the file handler
5399"  call Decho("execute the file handler (if any)",'~'.expand("<slnum>"))
5400  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
5401"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5402   let ret= netrwFileHandlers#Invoke(exten,fname)
5403
5404  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
5405"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5406   call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
5407   let ret= v:shell_error
5408
5409  elseif has("win32") || has("win64")
5410"   call Decho("(netrw#BrowseX) win".(has("win32")? "32" : "64"),'~'.expand("<slnum>"))
5411   if executable("start")
5412    call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5413   elseif executable("rundll32")
5414    call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5415   else
5416    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5417   endif
5418   let ret= v:shell_error
5419
5420  elseif has("win32unix")
5421   let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
5422"   call Decho("(netrw#BrowseX) cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
5423   if executable("start")
5424"    call Decho("(netrw#BrowseX) win32unix+start",'~'.expand("<slnum>"))
5425    call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5426   elseif executable("rundll32")
5427"    call Decho("(netrw#BrowseX) win32unix+rundll32",'~'.expand("<slnum>"))
5428    call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5429   elseif executable("cygstart")
5430"    call Decho("(netrw#BrowseX) win32unix+cygstart",'~'.expand("<slnum>"))
5431    call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
5432   else
5433    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5434   endif
5435   let ret= v:shell_error
5436
5437  elseif has("unix") && $DESKTOP_SESSION == "mate" && executable("atril")
5438"   call Decho("(netrw#BrowseX) unix and atril",'~'.expand("<slnum>"))
5439   if a:fname =~ '^https\=://'
5440    " atril does not appear to understand how to handle html -- so use gvim to edit the document
5441    let use_ctrlo= 0
5442"    call Decho("fname<".fname.">")
5443"    call Decho("a:fname<".a:fname.">")
5444    call s:NetrwExe("sil! !gvim ".fname.' -c "keepj keepalt file '.fnameescape(a:fname).'"')
5445
5446   else
5447    call s:NetrwExe("sil !atril ".s:ShellEscape(fname,1).redir)
5448   endif
5449   let ret= v:shell_error
5450
5451  elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
5452"   call Decho("(netrw#BrowseX) unix and kfmclient",'~'.expand("<slnum>"))
5453   call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
5454   let ret= v:shell_error
5455
5456  elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
5457"   call Decho("(netrw#BrowseX) unix, exo-open, xdg-open",'~'.expand("<slnum>"))
5458   call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir.'&')
5459   let ret= v:shell_error
5460
5461  elseif has("unix") && executable("xdg-open")
5462"   call Decho("(netrw#BrowseX) unix and xdg-open",'~'.expand("<slnum>"))
5463   call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir.'&')
5464   let ret= v:shell_error
5465
5466  elseif has("macunix") && executable("open")
5467"   call Decho("(netrw#BrowseX) macunix and open",'~'.expand("<slnum>"))
5468   call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
5469   let ret= v:shell_error
5470
5471  else
5472   " netrwFileHandlers#Invoke() always returns 0
5473"   call Decho("(netrw#BrowseX) use netrwFileHandlers",'~'.expand("<slnum>"))
5474   let ret= netrwFileHandlers#Invoke(exten,fname)
5475  endif
5476
5477  " if unsuccessful, attempt netrwFileHandlers#Invoke()
5478  if ret
5479"   call Decho("(netrw#BrowseX) ret=".ret," indicates unsuccessful thus far",'~'.expand("<slnum>"))
5480   let ret= netrwFileHandlers#Invoke(exten,fname)
5481  endif
5482
5483  " restoring redraw! after external file handlers
5484  redraw!
5485
5486  " cleanup: remove temporary file,
5487  "          delete current buffer if success with handler,
5488  "          return to prior buffer (directory listing)
5489  "          Feb 12, 2008: had to de-activiate removal of
5490  "          temporary file because it wasn't getting seen.
5491"  if remote == 1 && fname != a:fname
5492""   call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
5493"   call s:NetrwDelete(fname)
5494"  endif
5495
5496  if remote == 1
5497   setl bh=delete bt=nofile
5498   if g:netrw_use_noswf
5499    setl noswf
5500   endif
5501   if use_ctrlo
5502    exe "sil! NetrwKeepj norm! \<c-o>"
5503   endif
5504  endif
5505"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5506  call winrestview(screenposn)
5507  let @@ = ykeep
5508  let &aw= awkeep
5509
5510"  call Dret("netrw#BrowseX")
5511endfun
5512
5513" ---------------------------------------------------------------------
5514" netrw#GX: gets word under cursor for gx support {{{2
5515"           See also: netrw#BrowseXVis
5516"                     netrw#BrowseX
5517fun! netrw#GX()
5518"  call Dfunc("netrw#GX()")
5519  if &ft == "netrw"
5520   let fname= s:NetrwGetWord()
5521  else
5522   let fname= expand((exists("g:netrw_gx")? g:netrw_gx : '<cfile>'))
5523  endif
5524"  call Dret("netrw#GX <".fname.">")
5525  return fname
5526endfun
5527
5528" ---------------------------------------------------------------------
5529" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5530fun! netrw#BrowseXVis()
5531"  call Dfunc("netrw#BrowseXVis()")
5532  let akeep = @a
5533  norm! gv"ay
5534  let gxfile= @a
5535  let @a    = akeep
5536  call netrw#BrowseX(gxfile,netrw#CheckIfRemote(gxfile))
5537"  call Dret("netrw#BrowseXVis")
5538endfun
5539
5540" ---------------------------------------------------------------------
5541" s:NetrwBufRename: renames a buffer without the side effect of retaining an unlisted buffer having the old name {{{2
5542"                   Using the file command on a "[No Name]" buffer does not seem to cause the old "[No Name]" buffer
5543"                   to become an unlisted buffer, so in that case don't bwipe it.
5544fun! s:NetrwBufRename(newname)
5545"  call Dfunc("s:NetrwBufRename(newname<".a:newname.">) buf(%)#".bufnr("%")."<".bufname(bufnr("%")).">")
5546"  call Dredir("ls!","s:NetrwBufRename (before rename)")
5547  let oldbufname= bufname(bufnr("%"))
5548"  call Decho("buf#".bufnr("%").": oldbufname<".oldbufname.">",'~'.expand("<slnum>"))
5549
5550  if oldbufname != a:newname
5551"   call Decho("do buffer rename: oldbufname<".oldbufname."> ≠ a:newname<".a:newname.">",'~'.expand("<slnum>"))
5552   let b:junk= 1
5553"   call Decho("rename buffer: sil! keepj keepalt file ".fnameescape(a:newname),'~'.expand("<slnum>"))
5554   exe 'sil! keepj keepalt file '.fnameescape(a:newname)
5555"   call Dredir("ls!","s:NetrwBufRename (before bwipe)~".expand("<slnum>"))
5556   let oldbufnr= bufnr(oldbufname)
5557"   call Decho("oldbufname<".oldbufname."> oldbufnr#".oldbufnr,'~'.expand("<slnum>"))
5558"   call Decho("bufnr(%)=".bufnr("%"),'~'.expand("<slnum>"))
5559   if oldbufname != "" && oldbufnr != -1 && oldbufnr != bufnr("%")
5560"    call Decho("bwipe ".oldbufnr,'~'.expand("<slnum>"))
5561    exe "bwipe! ".oldbufnr
5562"   else " Decho
5563"    call Decho("did *not* bwipe buf#".oldbufnr,'~'.expand("<slnum>"))
5564"    call Decho("..reason: if oldbufname<".oldbufname."> is empty",'~'.expand("<slnum>"))"
5565"    call Decho("..reason: if oldbufnr#".oldbufnr." is -1",'~'.expand("<slnum>"))"
5566"    call Decho("..reason: if oldbufnr#".oldbufnr." != bufnr(%)#".bufnr("%"),'~'.expand("<slnum>"))"
5567   endif
5568"   call Dredir("ls!","s:NetrwBufRename (after rename)")
5569"  else " Decho
5570"   call Decho("oldbufname<".oldbufname."> == a:newname: did *not* rename",'~'.expand("<slnum>"))
5571  endif
5572
5573"  call Dret("s:NetrwBufRename : buf#".bufnr("%").": oldname<".oldbufname."> newname<".a:newname."> expand(%)<".expand("%").">")
5574endfun
5575
5576" ---------------------------------------------------------------------
5577" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5578fun! netrw#CheckIfRemote(...)
5579"  call Dfunc("netrw#CheckIfRemote() a:0=".a:0)
5580  if a:0 > 0
5581   let curfile= a:1
5582  else
5583   let curfile= expand("%")
5584  endif
5585
5586  " Ignore terminal buffers
5587  if &buftype ==# 'terminal'
5588    return 0
5589  endif
5590"  call Decho("curfile<".curfile.">")
5591  if curfile =~ '^\a\{3,}://'
5592"   call Dret("netrw#CheckIfRemote 1")
5593   return 1
5594  else
5595"   call Dret("netrw#CheckIfRemote 0")
5596   return 0
5597  endif
5598endfun
5599
5600" ---------------------------------------------------------------------
5601" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5602fun! s:NetrwChgPerm(islocal,curdir)
5603"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
5604  let ykeep  = @@
5605  call inputsave()
5606  let newperm= input("Enter new permission: ")
5607  call inputrestore()
5608  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5609  let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5610"  call Decho("chgperm<".chgperm.">",'~'.expand("<slnum>"))
5611  call system(chgperm)
5612  if v:shell_error != 0
5613   NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5614  endif
5615  if a:islocal
5616   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5617  endif
5618  let @@= ykeep
5619"  call Dret("s:NetrwChgPerm")
5620endfun
5621
5622" ---------------------------------------------------------------------
5623" s:CheckIfKde: checks if kdeinit is running {{{2
5624"    Returns 0: kdeinit not running
5625"            1: kdeinit is  running
5626fun! s:CheckIfKde()
5627"  call Dfunc("s:CheckIfKde()")
5628  " seems kde systems often have gnome-open due to dependencies, even though
5629  " gnome-open's subsidiary display tools are largely absent.  Kde systems
5630  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
5631  if !exists("s:haskdeinit")
5632   if has("unix") && executable("ps") && !has("win32unix")
5633    let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5634    if v:shell_error
5635     let s:haskdeinit = 0
5636    endif
5637   else
5638    let s:haskdeinit= 0
5639   endif
5640"   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5641  endif
5642
5643"  call Dret("s:CheckIfKde ".s:haskdeinit)
5644  return s:haskdeinit
5645endfun
5646
5647" ---------------------------------------------------------------------
5648" s:NetrwClearExplore: clear explore variables (if any) {{{2
5649fun! s:NetrwClearExplore()
5650"  call Dfunc("s:NetrwClearExplore()")
5651  2match none
5652  if exists("s:explore_match")        |unlet s:explore_match        |endif
5653  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
5654  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5655  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
5656  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
5657  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
5658  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5659  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
5660  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
5661"   redraw!
5662  echo " "
5663  echo " "
5664"  call Dret("s:NetrwClearExplore")
5665endfun
5666
5667" ---------------------------------------------------------------------
5668" s:NetrwExploreListUniq: {{{2
5669fun! s:NetrwExploreListUniq(explist)
5670"  call Dfunc("s:NetrwExploreListUniq(explist<".string(a:explist).">)")
5671
5672  " this assumes that the list is already sorted
5673  let newexplist= []
5674  for member in a:explist
5675   if !exists("uniqmember") || member != uniqmember
5676    let uniqmember = member
5677    let newexplist = newexplist + [ member ]
5678   endif
5679  endfor
5680
5681"  call Dret("s:NetrwExploreListUniq newexplist<".string(newexplist).">")
5682  return newexplist
5683endfun
5684
5685" ---------------------------------------------------------------------
5686" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5687fun! s:NetrwForceChgDir(islocal,newdir)
5688"  call Dfunc("s:NetrwForceChgDir(islocal=".a:islocal." newdir<".a:newdir.">)")
5689  let ykeep= @@
5690  if a:newdir !~ '/$'
5691   " ok, looks like force is needed to get directory-style treatment
5692   if a:newdir =~ '@$'
5693    let newdir= substitute(a:newdir,'@$','/','')
5694   elseif a:newdir =~ '[*=|\\]$'
5695    let newdir= substitute(a:newdir,'.$','/','')
5696   else
5697    let newdir= a:newdir.'/'
5698   endif
5699"   call Decho("adjusting newdir<".newdir."> due to gd",'~'.expand("<slnum>"))
5700  else
5701   " should already be getting treatment as a directory
5702   let newdir= a:newdir
5703  endif
5704  let newdir= s:NetrwBrowseChgDir(a:islocal,newdir)
5705  call s:NetrwBrowse(a:islocal,newdir)
5706  let @@= ykeep
5707"  call Dret("s:NetrwForceChgDir")
5708endfun
5709
5710" ---------------------------------------------------------------------
5711" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5712"     direntry: this is the name of the directory.  Will be fnameescape'd to prevent wildcard handling by glob()
5713"     expr    : this is the expression to follow the directory.  Will use s:ComposePath()
5714"     pare    =1: remove the current directory from the resulting glob() filelist
5715"             =0: leave  the current directory   in the resulting glob() filelist
5716fun! s:NetrwGlob(direntry,expr,pare)
5717"  call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")")
5718  if netrw#CheckIfRemote()
5719   keepalt 1sp
5720   keepalt enew
5721   let keep_liststyle    = w:netrw_liststyle
5722   let w:netrw_liststyle = s:THINLIST
5723   if s:NetrwRemoteListing() == 0
5724    keepj keepalt %s@/@@
5725    let filelist= getline(1,$)
5726    q!
5727   else
5728    " remote listing error -- leave treedict unchanged
5729    let filelist= w:netrw_treedict[a:direntry]
5730   endif
5731   let w:netrw_liststyle= keep_liststyle
5732  elseif v:version > 704 || (v:version == 704 && has("patch656"))
5733   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1)
5734   if a:pare
5735    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5736   endif
5737  else
5738   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1)
5739   if a:pare
5740    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5741   endif
5742  endif
5743"  call Dret("s:NetrwGlob ".string(filelist))
5744  return filelist
5745endfun
5746
5747" ---------------------------------------------------------------------
5748" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5749fun! s:NetrwForceFile(islocal,newfile)
5750"  call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)")
5751  if a:newfile =~ '[/@*=|\\]$'
5752   let newfile= substitute(a:newfile,'.$','','')
5753  else
5754   let newfile= a:newfile
5755  endif
5756  if a:islocal
5757   call s:NetrwBrowseChgDir(a:islocal,newfile)
5758  else
5759   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile))
5760  endif
5761"  call Dret("s:NetrwForceFile")
5762endfun
5763
5764" ---------------------------------------------------------------------
5765" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5766"          and switches the hiding mode.  The actual hiding is done by
5767"          s:NetrwListHide().
5768"             g:netrw_hide= 0: show all
5769"                           1: show not-hidden files
5770"                           2: show hidden files only
5771fun! s:NetrwHide(islocal)
5772"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
5773  let ykeep= @@
5774  let svpos= winsaveview()
5775"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5776
5777  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5778"   call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>"))
5779"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5780
5781   " hide the files in the markfile list
5782   for fname in s:netrwmarkfilelist_{bufnr("%")}
5783"    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>"))
5784    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5785     " remove fname from hiding list
5786     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5787     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5788     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5789"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5790    else
5791     " append fname to hiding list
5792     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5793      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5794     else
5795      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5796     endif
5797"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5798    endif
5799   endfor
5800   NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5801   let g:netrw_hide= 1
5802
5803  else
5804
5805   " switch between show-all/show-not-hidden/show-hidden
5806   let g:netrw_hide=(g:netrw_hide+1)%3
5807   exe "NetrwKeepj norm! 0"
5808   if g:netrw_hide && g:netrw_list_hide == ""
5809    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5810    let @@= ykeep
5811"    call Dret("NetrwHide")
5812    return
5813   endif
5814  endif
5815
5816  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5817"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5818  NetrwKeepj call winrestview(svpos)
5819  let @@= ykeep
5820"  call Dret("NetrwHide")
5821endfun
5822
5823" ---------------------------------------------------------------------
5824" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5825fun! s:NetrwHideEdit(islocal)
5826"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
5827
5828  let ykeep= @@
5829  " save current cursor position
5830  let svpos= winsaveview()
5831"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5832
5833  " get new hiding list from user
5834  call inputsave()
5835  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5836  call inputrestore()
5837  let g:netrw_list_hide= newhide
5838"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5839
5840  " refresh the listing
5841  sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
5842
5843  " restore cursor position
5844"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5845  call winrestview(svpos)
5846  let @@= ykeep
5847
5848"  call Dret("NetrwHideEdit")
5849endfun
5850
5851" ---------------------------------------------------------------------
5852" s:NetrwHidden: invoked by "gh" {{{2
5853fun! s:NetrwHidden(islocal)
5854"  call Dfunc("s:NetrwHidden()")
5855  let ykeep= @@
5856  "  save current position
5857  let svpos  = winsaveview()
5858"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5859
5860  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5861   " remove .file pattern from hiding list
5862"   call Decho("remove .file pattern from hiding list",'~'.expand("<slnum>"))
5863   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5864  elseif s:Strlen(g:netrw_list_hide) >= 1
5865"   call Decho("add .file pattern from hiding list",'~'.expand("<slnum>"))
5866   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5867  else
5868"   call Decho("set .file pattern as hiding list",'~'.expand("<slnum>"))
5869   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5870  endif
5871  if g:netrw_list_hide =~ '^,'
5872   let g:netrw_list_hide= strpart(g:netrw_list_hide,1)
5873  endif
5874
5875  " refresh screen and return to saved position
5876  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5877"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5878  NetrwKeepj call winrestview(svpos)
5879  let @@= ykeep
5880"  call Dret("s:NetrwHidden")
5881endfun
5882
5883" ---------------------------------------------------------------------
5884"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5885fun! s:NetrwHome()
5886  if exists("g:netrw_home")
5887   let home= expand(g:netrw_home)
5888  else
5889   let home = stdpath('data')
5890  endif
5891  " insure that the home directory exists
5892  if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5893"   call Decho("insure that the home<".home."> directory exists")
5894   if exists("g:netrw_mkdir")
5895"    call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")")
5896    call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5897   else
5898"    call Decho("mkdir(".home.")")
5899    call mkdir(home)
5900   endif
5901  endif
5902  let g:netrw_home= home
5903  return home
5904endfun
5905
5906" ---------------------------------------------------------------------
5907" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5908fun! s:NetrwLeftmouse(islocal)
5909  if exists("s:netrwdrag")
5910   return
5911  endif
5912  if &ft != "netrw"
5913   return
5914  endif
5915"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
5916
5917  let ykeep= @@
5918  " check if the status bar was clicked on instead of a file/directory name
5919  while getchar(0) != 0
5920   "clear the input stream
5921  endwhile
5922  call feedkeys("\<LeftMouse>")
5923  let c          = getchar()
5924  let mouse_lnum = v:mouse_lnum
5925  let wlastline  = line('w$')
5926  let lastline   = line('$')
5927"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr(),'~'.expand("<slnum>"))
5928"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0),'~'.expand("<slnum>"))
5929  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5930   " appears to be a status bar leftmouse click
5931   let @@= ykeep
5932"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
5933   return
5934  endif
5935   " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5936   " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5937   " without this test when its disabled.
5938   " May 26, 2014: edit file, :Lex, resize window -- causes refresh.  Reinstated a modified test.  See if problems develop.
5939"   call Decho("v:mouse_col=".v:mouse_col." col#".col('.')." virtcol#".virtcol('.')." col($)#".col("$")." virtcol($)#".virtcol("$"),'~'.expand("<slnum>"))
5940   if v:mouse_col > virtcol('.')
5941    let @@= ykeep
5942"    call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
5943    return
5944   endif
5945
5946  if a:islocal
5947   if exists("b:netrw_curdir")
5948    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
5949   endif
5950  else
5951   if exists("b:netrw_curdir")
5952    NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5953   endif
5954  endif
5955  let @@= ykeep
5956"  call Dret("s:NetrwLeftmouse")
5957endfun
5958
5959" ---------------------------------------------------------------------
5960" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5961fun! s:NetrwCLeftmouse(islocal)
5962  if &ft != "netrw"
5963   return
5964  endif
5965"  call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")")
5966  call s:NetrwMarkFileTgt(a:islocal)
5967"  call Dret("s:NetrwCLeftmouse")
5968endfun
5969
5970" ---------------------------------------------------------------------
5971" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER  (implements <c-r>){{{2
5972"   a:islocal=0 : <c-r> not used, remote
5973"   a:islocal=1 : <c-r> not used, local
5974"   a:islocal=2 : <c-r>     used, remote
5975"   a:islocal=3 : <c-r>     used, local
5976fun! s:NetrwServerEdit(islocal,fname)
5977"  call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5978  let islocal = a:islocal%2      " =0: remote           =1: local
5979  let ctrlr   = a:islocal >= 2   " =0: <c-r> not used   =1: <c-r> used
5980"  call Decho("islocal=".islocal." ctrlr=".ctrlr,'~'.expand("<slnum>"))
5981
5982  if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5983   " handle directories in the local window -- not in the remote vim server
5984   " user must have closed the NETRWSERVER window.  Treat as normal editing from netrw.
5985"   call Decho("handling directory in client window",'~'.expand("<slnum>"))
5986   let g:netrw_browse_split= 0
5987   if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
5988    let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5989    unlet s:netrw_browse_split_{winnr()}
5990   endif
5991   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5992"   call Dret("s:NetrwServerEdit")
5993   return
5994  endif
5995
5996"  call Decho("handling file in server window",'~'.expand("<slnum>"))
5997  if has("clientserver") && executable("gvim")
5998"   call Decho("has clientserver and gvim",'~'.expand("<slnum>"))
5999
6000    if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
6001"     call Decho("g:netrw_browse_split=".string(g:netrw_browse_split),'~'.expand("<slnum>"))
6002     let srvrname = g:netrw_browse_split[0]
6003     let tabnum   = g:netrw_browse_split[1]
6004     let winnum   = g:netrw_browse_split[2]
6005
6006     if serverlist() !~ '\<'.srvrname.'\>'
6007"      call Decho("server not available; ctrlr=".ctrlr,'~'.expand("<slnum>"))
6008
6009      if !ctrlr
6010       " user must have closed the server window and the user did not use <c-r>, but
6011       " used something like <cr>.
6012"       call Decho("user must have closed server AND did not use ctrl-r",'~'.expand("<slnum>"))
6013       if exists("g:netrw_browse_split")
6014	unlet g:netrw_browse_split
6015       endif
6016       let g:netrw_browse_split= 0
6017       if exists("s:netrw_browse_split_".winnr())
6018        let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
6019       endif
6020       call s:NetrwBrowseChgDir(islocal,a:fname)
6021"       call Dret("s:NetrwServerEdit")
6022       return
6023
6024      elseif has("win32") && executable("start")
6025       " start up remote netrw server under windows
6026"       call Decho("starting up gvim server<".srvrname."> for windows",'~'.expand("<slnum>"))
6027       call system("start gvim --servername ".srvrname)
6028
6029      else
6030       " start up remote netrw server under linux
6031"       call Decho("starting up gvim server<".srvrname.">",'~'.expand("<slnum>"))
6032       call system("gvim --servername ".srvrname)
6033      endif
6034     endif
6035
6036"     call Decho("srvrname<".srvrname."> tabnum=".tabnum." winnum=".winnum." server-editing<".a:fname.">",'~'.expand("<slnum>"))
6037     call remote_send(srvrname,":tabn ".tabnum."\<cr>")
6038     call remote_send(srvrname,":".winnum."wincmd w\<cr>")
6039     call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
6040
6041    else
6042
6043     if serverlist() !~ '\<'.g:netrw_servername.'\>'
6044
6045      if !ctrlr
6046"       call Decho("server<".g:netrw_servername."> not available and ctrl-r not used",'~'.expand("<slnum>"))
6047       if exists("g:netrw_browse_split")
6048	unlet g:netrw_browse_split
6049       endif
6050       let g:netrw_browse_split= 0
6051       call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
6052"       call Dret("s:NetrwServerEdit")
6053       return
6054
6055      else
6056"       call Decho("server<".g:netrw_servername."> not available but ctrl-r used",'~'.expand("<slnum>"))
6057       if has("win32") && executable("start")
6058        " start up remote netrw server under windows
6059"        call Decho("starting up gvim server<".g:netrw_servername."> for windows",'~'.expand("<slnum>"))
6060        call system("start gvim --servername ".g:netrw_servername)
6061       else
6062        " start up remote netrw server under linux
6063"        call Decho("starting up gvim server<".g:netrw_servername.">",'~'.expand("<slnum>"))
6064        call system("gvim --servername ".g:netrw_servername)
6065       endif
6066      endif
6067     endif
6068
6069     while 1
6070      try
6071"       call Decho("remote-send: e ".a:fname,'~'.expand("<slnum>"))
6072       call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
6073       break
6074      catch /^Vim\%((\a\+)\)\=:E241/
6075       sleep 200m
6076      endtry
6077     endwhile
6078
6079     if exists("g:netrw_browse_split")
6080      if type(g:netrw_browse_split) != 3
6081        let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
6082       endif
6083      unlet g:netrw_browse_split
6084     endif
6085     let g:netrw_browse_split= [g:netrw_servername,1,1]
6086    endif
6087
6088   else
6089    call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
6090   endif
6091
6092"  call Dret("s:NetrwServerEdit")
6093endfun
6094
6095" ---------------------------------------------------------------------
6096" s:NetrwSLeftmouse: marks the file under the cursor.  May be dragged to select additional files {{{2
6097fun! s:NetrwSLeftmouse(islocal)
6098  if &ft != "netrw"
6099   return
6100  endif
6101"  call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
6102
6103  let s:ngw= s:NetrwGetWord()
6104  call s:NetrwMarkFile(a:islocal,s:ngw)
6105
6106"  call Dret("s:NetrwSLeftmouse")
6107endfun
6108
6109" ---------------------------------------------------------------------
6110" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
6111"                   Used to mark multiple files.
6112fun! s:NetrwSLeftdrag(islocal)
6113"  call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
6114  if !exists("s:netrwdrag")
6115   let s:netrwdrag = winnr()
6116   if a:islocal
6117    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
6118   else
6119    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
6120   endif
6121  endif
6122  let ngw = s:NetrwGetWord()
6123  if !exists("s:ngw") || s:ngw != ngw
6124   call s:NetrwMarkFile(a:islocal,ngw)
6125  endif
6126  let s:ngw= ngw
6127"  call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
6128endfun
6129
6130" ---------------------------------------------------------------------
6131" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
6132fun! s:NetrwSLeftrelease(islocal)
6133"  call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
6134  if exists("s:netrwdrag")
6135   nunmap <s-leftrelease>
6136   let ngw = s:NetrwGetWord()
6137   if !exists("s:ngw") || s:ngw != ngw
6138    call s:NetrwMarkFile(a:islocal,ngw)
6139   endif
6140   if exists("s:ngw")
6141    unlet s:ngw
6142   endif
6143   unlet s:netrwdrag
6144  endif
6145"  call Dret("s:NetrwSLeftrelease")
6146endfun
6147
6148" ---------------------------------------------------------------------
6149" s:NetrwListHide: uses [range]g~...~d to delete files that match       {{{2
6150"                  comma-separated patterns given in g:netrw_list_hide
6151fun! s:NetrwListHide()
6152"  call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
6153"  call Decho("initial: ".string(getline(w:netrw_bannercnt,'$')))
6154  let ykeep= @@
6155
6156  " find a character not in the "hide" string to use as a separator for :g and :v commands
6157  " How-it-works: take the hiding command, convert it into a range.
6158  " Duplicate characters don't matter.
6159  " Remove all such characters from the '/~@#...890' string.
6160  " Use the first character left as a separator character.
6161"  call Decho("find a character not in the hide string to use as a separator",'~'.expand("<slnum>"))
6162  let listhide= g:netrw_list_hide
6163  let sep     = strpart(substitute('~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
6164"  call Decho("sep<".sep.">  (sep not in hide string)",'~'.expand("<slnum>"))
6165
6166  while listhide != ""
6167   if listhide =~ ','
6168    let hide     = substitute(listhide,',.*$','','e')
6169    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
6170   else
6171    let hide     = listhide
6172    let listhide = ""
6173   endif
6174"   call Decho("..extracted pattern from listhide: hide<".hide."> g:netrw_sort_by<".g:netrw_sort_by.'>','~'.expand("<slnum>"))
6175   if g:netrw_sort_by =~ '^[ts]'
6176    if hide =~ '^\^'
6177"     call Decho("..modify hide to handle a \"^...\" pattern",'~'.expand("<slnum>"))
6178     let hide= substitute(hide,'^\^','^\(\\d\\+/\)','')
6179    elseif hide =~ '^\\(\^'
6180     let hide= substitute(hide,'^\\(\^','\\(^\\(\\d\\+/\\)','')
6181    endif
6182"    call Decho("..hide<".hide."> listhide<".listhide.'>','~'.expand("<slnum>"))
6183   endif
6184
6185   " Prune the list by hiding any files which match
6186"   call Decho("..prune the list by hiding any files which ".((g:netrw_hide == 1)? "" : "don't")."match hide<".hide.">")
6187   if g:netrw_hide == 1
6188"    call Decho("..hiding<".hide.">",'~'.expand("<slnum>"))
6189    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
6190   elseif g:netrw_hide == 2
6191"    call Decho("..showing<".hide.">",'~'.expand("<slnum>"))
6192    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
6193   endif
6194"   call Decho("..result: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6195  endwhile
6196
6197  if g:netrw_hide == 2
6198   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
6199"   call Decho("..v KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6200   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
6201"   call Decho("..g KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6202  endif
6203
6204  " remove any blank lines that have somehow remained.
6205  " This seems to happen under Windows.
6206  exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
6207
6208  let @@= ykeep
6209"  call Dret("s:NetrwListHide")
6210endfun
6211
6212" ---------------------------------------------------------------------
6213" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
6214"                 implements the "d" mapping.
6215fun! s:NetrwMakeDir(usrhost)
6216"  call Dfunc("s:NetrwMakeDir(usrhost<".a:usrhost.">)")
6217
6218  let ykeep= @@
6219  " get name of new directory from user.  A bare <CR> will skip.
6220  " if its currently a directory, also request will be skipped, but with
6221  " a message.
6222  call inputsave()
6223  let newdirname= input("Please give directory name: ")
6224  call inputrestore()
6225"  call Decho("newdirname<".newdirname.">",'~'.expand("<slnum>"))
6226
6227  if newdirname == ""
6228   let @@= ykeep
6229"   call Dret("s:NetrwMakeDir : user aborted with bare <cr>")
6230   return
6231  endif
6232
6233  if a:usrhost == ""
6234"   call Decho("local mkdir",'~'.expand("<slnum>"))
6235
6236   " Local mkdir:
6237   " sanity checks
6238   let fullnewdir= b:netrw_curdir.'/'.newdirname
6239"   call Decho("fullnewdir<".fullnewdir.">",'~'.expand("<slnum>"))
6240   if isdirectory(s:NetrwFile(fullnewdir))
6241    if !exists("g:netrw_quiet")
6242     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
6243    endif
6244    let @@= ykeep
6245"    call Dret("s:NetrwMakeDir : directory<".newdirname."> exists previously")
6246    return
6247   endif
6248   if s:FileReadable(fullnewdir)
6249    if !exists("g:netrw_quiet")
6250     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
6251    endif
6252    let @@= ykeep
6253"    call Dret("s:NetrwMakeDir : file<".newdirname."> exists previously")
6254    return
6255   endif
6256
6257   " requested new local directory is neither a pre-existing file or
6258   " directory, so make it!
6259   if exists("*mkdir")
6260    if has("unix")
6261     call mkdir(fullnewdir,"p",xor(0777, system("umask")))
6262    else
6263     call mkdir(fullnewdir,"p")
6264    endif
6265   else
6266    let netrw_origdir= s:NetrwGetcwd(1)
6267    if s:NetrwLcd(b:netrw_curdir)
6268"    call Dret("s:NetrwMakeDir : lcd failure")
6269     return
6270    endif
6271"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("<slnum>"))
6272    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(newdirname,1))
6273    if v:shell_error != 0
6274     let @@= ykeep
6275     call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6276"     call Dret("s:NetrwMakeDir : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
6277     return
6278    endif
6279    if !g:netrw_keepdir
6280"     call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
6281     if s:NetrwLcd(netrw_origdir)
6282"     call Dret("s:NetrwBrowse : lcd failure")
6283      return
6284     endif
6285    endif
6286   endif
6287
6288   if v:shell_error == 0
6289    " refresh listing
6290"    call Decho("refresh listing",'~'.expand("<slnum>"))
6291    let svpos= winsaveview()
6292"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6293    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
6294"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6295    call winrestview(svpos)
6296   elseif !exists("g:netrw_quiet")
6297    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
6298   endif
6299"   redraw!
6300
6301  elseif !exists("b:netrw_method") || b:netrw_method == 4
6302   " Remote mkdir:  using ssh
6303"   call Decho("remote mkdir",'~'.expand("<slnum>"))
6304   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
6305   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
6306   call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
6307   if v:shell_error == 0
6308    " refresh listing
6309    let svpos= winsaveview()
6310"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6311    NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6312"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6313    NetrwKeepj call winrestview(svpos)
6314   elseif !exists("g:netrw_quiet")
6315    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
6316   endif
6317"   redraw!
6318
6319  elseif b:netrw_method == 2
6320   " Remote mkdir:  using ftp+.netrc
6321   let svpos= winsaveview()
6322"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6323"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6324   if exists("b:netrw_fname")
6325"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6326    let remotepath= b:netrw_fname
6327   else
6328    let remotepath= ""
6329   endif
6330   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6331   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6332"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6333   NetrwKeepj call winrestview(svpos)
6334
6335  elseif b:netrw_method == 3
6336   " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
6337   let svpos= winsaveview()
6338"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6339"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6340   if exists("b:netrw_fname")
6341"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6342    let remotepath= b:netrw_fname
6343   else
6344    let remotepath= ""
6345   endif
6346   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6347   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6348"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6349   NetrwKeepj call winrestview(svpos)
6350  endif
6351
6352  let @@= ykeep
6353"  call Dret("s:NetrwMakeDir")
6354endfun
6355
6356" ---------------------------------------------------------------------
6357" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
6358fun! s:TreeSqueezeDir(islocal)
6359"  call Dfunc("s:TreeSqueezeDir(islocal=".a:islocal.")")
6360  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6361   " its a tree-listing style
6362   let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
6363   let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
6364   let depth    = strchars(substitute(curdepth,' ','','g'))
6365   let srch     = -1
6366"   call Decho("curdepth<".curdepth.'>','~'.expand("<slnum>"))
6367"   call Decho("depth   =".depth,'~'.expand("<slnum>"))
6368"   call Decho("stopline#".stopline,'~'.expand("<slnum>"))
6369"   call Decho("curline#".line(".")."<".getline('.').'>','~'.expand("<slnum>"))
6370   if depth >= 2
6371    NetrwKeepj norm! 0
6372    let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
6373    let srch      = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
6374"    call Decho("curdepthm1<".curdepthm1.'>','~'.expand("<slnum>"))
6375"    call Decho("case depth>=2: srch<".srch.'>','~'.expand("<slnum>"))
6376   elseif depth == 1
6377    NetrwKeepj norm! 0
6378    let treedepthchr= substitute(s:treedepthstring,' ','','')
6379    let srch        = search('^[^'.treedepthchr.']','bW',stopline)
6380"    call Decho("case depth==1: srch<".srch.'>','~'.expand("<slnum>"))
6381   endif
6382   if srch > 0
6383"    call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
6384    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord()))
6385    exe srch
6386   endif
6387  endif
6388"  call Dret("s:TreeSqueezeDir")
6389endfun
6390
6391" ---------------------------------------------------------------------
6392" s:NetrwMaps: {{{2
6393fun! s:NetrwMaps(islocal)
6394"  call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6395
6396  " mouse <Plug> maps: {{{3
6397  if g:netrw_mousemaps && g:netrw_retmap
6398"   call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
6399   if !hasmapto("<Plug>NetrwReturn")
6400    if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
6401"     call Decho("making map for 2-leftmouse",'~'.expand("<slnum>"))
6402     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
6403    elseif maparg("<c-leftmouse>","n") == ""
6404"     call Decho("making map for c-leftmouse",'~'.expand("<slnum>"))
6405     nmap <unique> <silent> <c-leftmouse>	<Plug>NetrwReturn
6406    endif
6407   endif
6408   nno <silent> <Plug>NetrwReturn	:Rexplore<cr>
6409"   call Decho("made <Plug>NetrwReturn map",'~'.expand("<slnum>"))
6410  endif
6411
6412  " generate default <Plug> maps {{{3
6413  if !hasmapto('<Plug>NetrwHide')              |nmap <buffer> <silent> <nowait> a	<Plug>NetrwHide_a|endif
6414  if !hasmapto('<Plug>NetrwBrowseUpDir')       |nmap <buffer> <silent> <nowait> -	<Plug>NetrwBrowseUpDir|endif
6415  if !hasmapto('<Plug>NetrwOpenFile')          |nmap <buffer> <silent> <nowait> %	<Plug>NetrwOpenFile|endif
6416  if !hasmapto('<Plug>NetrwBadd_cb')           |nmap <buffer> <silent> <nowait> cb	<Plug>NetrwBadd_cb|endif
6417  if !hasmapto('<Plug>NetrwBadd_cB')           |nmap <buffer> <silent> <nowait> cB	<Plug>NetrwBadd_cB|endif
6418  if !hasmapto('<Plug>NetrwLcd')               |nmap <buffer> <silent> <nowait> cd	<Plug>NetrwLcd|endif
6419  if !hasmapto('<Plug>NetrwSetChgwin')         |nmap <buffer> <silent> <nowait> C	<Plug>NetrwSetChgwin|endif
6420  if !hasmapto('<Plug>NetrwRefresh')           |nmap <buffer> <silent> <nowait> <c-l>	<Plug>NetrwRefresh|endif
6421  if !hasmapto('<Plug>NetrwLocalBrowseCheck')  |nmap <buffer> <silent> <nowait> <cr>	<Plug>NetrwLocalBrowseCheck|endif
6422  if !hasmapto('<Plug>NetrwServerEdit')        |nmap <buffer> <silent> <nowait> <c-r>	<Plug>NetrwServerEdit|endif
6423  if !hasmapto('<Plug>NetrwMakeDir')           |nmap <buffer> <silent> <nowait> d	<Plug>NetrwMakeDir|endif
6424  if !hasmapto('<Plug>NetrwBookHistHandler_gb')|nmap <buffer> <silent> <nowait> gb	<Plug>NetrwBookHistHandler_gb|endif
6425" ---------------------------------------------------------------------
6426"  if !hasmapto('<Plug>NetrwForceChgDir')       |nmap <buffer> <silent> <nowait> gd	<Plug>NetrwForceChgDir|endif
6427"  if !hasmapto('<Plug>NetrwForceFile')         |nmap <buffer> <silent> <nowait> gf	<Plug>NetrwForceFile|endif
6428"  if !hasmapto('<Plug>NetrwHidden')            |nmap <buffer> <silent> <nowait> gh	<Plug>NetrwHidden|endif
6429"  if !hasmapto('<Plug>NetrwSetTreetop')        |nmap <buffer> <silent> <nowait> gn	<Plug>NetrwSetTreetop|endif
6430"  if !hasmapto('<Plug>NetrwChgPerm')           |nmap <buffer> <silent> <nowait> gp	<Plug>NetrwChgPerm|endif
6431"  if !hasmapto('<Plug>NetrwBannerCtrl')        |nmap <buffer> <silent> <nowait> I	<Plug>NetrwBannerCtrl|endif
6432"  if !hasmapto('<Plug>NetrwListStyle')         |nmap <buffer> <silent> <nowait> i	<Plug>NetrwListStyle|endif
6433"  if !hasmapto('<Plug>NetrwMarkMoveMF2Arglist')|nmap <buffer> <silent> <nowait> ma	<Plug>NetrwMarkMoveMF2Arglist|endif
6434"  if !hasmapto('<Plug>NetrwMarkMoveArglist2MF')|nmap <buffer> <silent> <nowait> mA	<Plug>NetrwMarkMoveArglist2MF|endif
6435"  if !hasmapto('<Plug>NetrwBookHistHandler_mA')|nmap <buffer> <silent> <nowait> mb	<Plug>NetrwBookHistHandler_mA|endif
6436"  if !hasmapto('<Plug>NetrwBookHistHandler_mB')|nmap <buffer> <silent> <nowait> mB	<Plug>NetrwBookHistHandler_mB|endif
6437"  if !hasmapto('<Plug>NetrwMarkFileCopy')      |nmap <buffer> <silent> <nowait> mc	<Plug>NetrwMarkFileCopy|endif
6438"  if !hasmapto('<Plug>NetrwMarkFileDiff')      |nmap <buffer> <silent> <nowait> md	<Plug>NetrwMarkFileDiff|endif
6439"  if !hasmapto('<Plug>NetrwMarkFileEdit')      |nmap <buffer> <silent> <nowait> me	<Plug>NetrwMarkFileEdit|endif
6440"  if !hasmapto('<Plug>NetrwMarkFile')          |nmap <buffer> <silent> <nowait> mf	<Plug>NetrwMarkFile|endif
6441"  if !hasmapto('<Plug>NetrwUnmarkList')        |nmap <buffer> <silent> <nowait> mF	<Plug>NetrwUnmarkList|endif
6442"  if !hasmapto('<Plug>NetrwMarkFileGrep')      |nmap <buffer> <silent> <nowait> mg	<Plug>NetrwMarkFileGrep|endif
6443"  if !hasmapto('<Plug>NetrwMarkHideSfx')       |nmap <buffer> <silent> <nowait> mh	<Plug>NetrwMarkHideSfx|endif
6444"  if !hasmapto('<Plug>NetrwMarkFileMove')      |nmap <buffer> <silent> <nowait> mm	<Plug>NetrwMarkFileMove|endif
6445"  if !hasmapto('<Plug>NetrwMarkFilePrint')     |nmap <buffer> <silent> <nowait> mp	<Plug>NetrwMarkFilePrint|endif
6446"  if !hasmapto('<Plug>NetrwMarkFileRegexp')    |nmap <buffer> <silent> <nowait> mr	<Plug>NetrwMarkFileRegexp|endif
6447"  if !hasmapto('<Plug>NetrwMarkFileSource')    |nmap <buffer> <silent> <nowait> ms	<Plug>NetrwMarkFileSource|endif
6448"  if !hasmapto('<Plug>NetrwMarkFileTag')       |nmap <buffer> <silent> <nowait> mT	<Plug>NetrwMarkFileTag|endif
6449"  if !hasmapto('<Plug>NetrwMarkFileTgt')       |nmap <buffer> <silent> <nowait> mt	<Plug>NetrwMarkFileTgt|endif
6450"  if !hasmapto('<Plug>NetrwUnMarkFile')        |nmap <buffer> <silent> <nowait> mu	<Plug>NetrwUnMarkFile|endif
6451"  if !hasmapto('<Plug>NetrwMarkFileVimCmd')    |nmap <buffer> <silent> <nowait> mv	<Plug>NetrwMarkFileVimCmd|endif
6452"  if !hasmapto('<Plug>NetrwMarkFileExe_mx')    |nmap <buffer> <silent> <nowait> mx	<Plug>NetrwMarkFileExe_mx|endif
6453"  if !hasmapto('<Plug>NetrwMarkFileExe_mX')    |nmap <buffer> <silent> <nowait> mX	<Plug>NetrwMarkFileExe_mX|endif
6454"  if !hasmapto('<Plug>NetrwMarkFileCompress')  |nmap <buffer> <silent> <nowait> mz	<Plug>NetrwMarkFileCompress|endif
6455"  if !hasmapto('<Plug>NetrwObtain')            |nmap <buffer> <silent> <nowait> O	<Plug>NetrwObtain|endif
6456"  if !hasmapto('<Plug>NetrwSplit_o')           |nmap <buffer> <silent> <nowait> o	<Plug>NetrwSplit_o|endif
6457"  if !hasmapto('<Plug>NetrwPreview')           |nmap <buffer> <silent> <nowait> p	<Plug>NetrwPreview|endif
6458"  if !hasmapto('<Plug>NetrwPrevWinOpen')       |nmap <buffer> <silent> <nowait> P	<Plug>NetrwPrevWinOpen|endif
6459"  if !hasmapto('<Plug>NetrwBookHistHandler_qb')|nmap <buffer> <silent> <nowait> qb	<Plug>NetrwBookHistHandler_qb|endif
6460"  if !hasmapto('<Plug>NetrwFileInfo')          |nmap <buffer> <silent> <nowait> qf	<Plug>NetrwFileInfo|endif
6461"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qF')   |nmap <buffer> <silent> <nowait> qF	<Plug>NetrwMarkFileQFEL_qF|endif
6462"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qL')   |nmap <buffer> <silent> <nowait> qL	<Plug>NetrwMarkFileQFEL_qL|endif
6463"  if !hasmapto('<Plug>NetrwSortStyle')         |nmap <buffer> <silent> <nowait> s	<Plug>NetrwSortStyle|endif
6464"  if !hasmapto('<Plug>NetSortSequence')        |nmap <buffer> <silent> <nowait> S	<Plug>NetSortSequence|endif
6465"  if !hasmapto('<Plug>NetrwSetTgt_Tb')         |nmap <buffer> <silent> <nowait> Tb	<Plug>NetrwSetTgt_Tb|endif
6466"  if !hasmapto('<Plug>NetrwSetTgt_Th')         |nmap <buffer> <silent> <nowait> Th	<Plug>NetrwSetTgt_Th|endif
6467"  if !hasmapto('<Plug>NetrwSplit_t')           |nmap <buffer> <silent> <nowait> t	<Plug>NetrwSplit_t|endif
6468"  if !hasmapto('<Plug>NetrwBookHistHandler_u') |nmap <buffer> <silent> <nowait> u	<Plug>NetrwBookHistHandler_u|endif
6469"  if !hasmapto('<Plug>NetrwBookHistHandler_U') |nmap <buffer> <silent> <nowait> U	<Plug>NetrwBookHistHandler_U|endif
6470"  if !hasmapto('<Plug>NetrwSplit_v')           |nmap <buffer> <silent> <nowait> v	<Plug>NetrwSplit_v|endif
6471"  if !hasmapto('<Plug>NetrwBrowseX')           |nmap <buffer> <silent> <nowait> x	<Plug>NetrwBrowseX|endif
6472"  if !hasmapto('<Plug>NetrwLocalExecute')      |nmap <buffer> <silent> <nowait> X	<Plug>NetrwLocalExecute|endif
6473
6474  if a:islocal
6475"   call Decho("make local maps",'~'.expand("<slnum>"))
6476   " local normal-mode maps {{{3
6477   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(1)<cr>
6478   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6479   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(1)<cr>
6480   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(1,0)<cr>
6481   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(1,1)<cr>
6482   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6483   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6484   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6485   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6486   nnoremap <buffer> <silent> <Plug>NetrwMakeDir		:<c-u>call <SID>NetrwMakeDir("")<cr>
6487   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6488" ---------------------------------------------------------------------
6489   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6490   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6491   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
6492   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(0,<SID>NetrwGetWord())<cr>
6493   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6494   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6495   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(1)<cr>
6496   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6497   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6498   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6499   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6500   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6501   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6502   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6503   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6504   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6505   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6506   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6507   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6508   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6509   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6510   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6511   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6512   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6513   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6514   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6515   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6516   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6517   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6518   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(1)<cr>
6519   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(3)<cr>
6520   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6521   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6522   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6523   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6524   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6525   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6526   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(1)<cr>
6527   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(1)<cr>
6528   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6529   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(4)<cr>
6530   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6531   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6532   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6533   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(5)<cr>
6534   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6535   nnoremap <buffer> <silent> <nowait> X	:<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6536
6537   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>
6538   if !hasmapto('<Plug>NetrwHideEdit')
6539    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6540   endif
6541   nnoremap <buffer> <silent> <Plug>NetrwHideEdit		:call <SID>NetrwHideEdit(1)<cr>
6542   if !hasmapto('<Plug>NetrwRefresh')
6543    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6544   endif
6545   nnoremap <buffer> <silent> <Plug>NetrwRefresh		<c-l>:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(exists("w:netrw_liststyle") && exists("w:netrw_treetop") && w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr>
6546   if s:didstarstar || !mapcheck("<s-down>","n")
6547    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6548   endif
6549   if s:didstarstar || !mapcheck("<s-up>","n")
6550    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6551   endif
6552   if !hasmapto('<Plug>NetrwTreeSqueeze')
6553    nmap <buffer> <silent> <nowait> <s-cr>			<Plug>NetrwTreeSqueeze
6554   endif
6555   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze		:call <SID>TreeSqueezeDir(1)<cr>
6556   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6557   if g:netrw_mousemaps == 1
6558    nmap <buffer>			<leftmouse>   		<Plug>NetrwLeftmouse
6559    nmap <buffer>			<c-leftmouse>		<Plug>NetrwCLeftmouse
6560    nmap <buffer>			<middlemouse>		<Plug>NetrwMiddlemouse
6561    nmap <buffer>			<s-leftmouse>		<Plug>NetrwSLeftmouse
6562    nmap <buffer>			<s-leftdrag>		<Plug>NetrwSLeftdrag
6563    nmap <buffer>			<2-leftmouse>		<Plug>Netrw2Leftmouse
6564    imap <buffer>			<leftmouse>		<Plug>ILeftmouse
6565    imap <buffer>			<middlemouse>		<Plug>IMiddlemouse
6566    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
6567    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(1)<cr>
6568    nno  <buffer> <silent>		<Plug>NetrwMiddlemouse	<leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
6569    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(1)<cr>
6570    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(1)<cr>
6571    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6572    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6573    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6574   endif
6575   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6576   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6577   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6578   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("")<cr>'
6579   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6580   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6581   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6582   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6583
6584   " support user-specified maps
6585   call netrw#UserMaps(1)
6586
6587  else
6588   " remote normal-mode maps {{{3
6589"   call Decho("make remote maps",'~'.expand("<slnum>"))
6590   call s:RemotePathAnalysis(b:netrw_curdir)
6591   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(0)<cr>
6592   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6593   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(0)<cr>
6594   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(0,0)<cr>
6595   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(0,1)<cr>
6596   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6597   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6598   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6599   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6600   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6601   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6602" ---------------------------------------------------------------------
6603   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6604   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6605   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
6606   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6607   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6608   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(0)<cr>
6609   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6610   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6611   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6612   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6613   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6614   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6615   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6616   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6617   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6618   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6619   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6620   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6621   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6622   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6623   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6624   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6625   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6626   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6627   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6628   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6629   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6630   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6631   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(0)<cr>
6632   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(0)<cr>
6633   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6634   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6635   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6636   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6637   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6638   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6639   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>
6640   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(0)<cr>
6641   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(0)<cr>
6642   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6643   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(1)<cr>
6644   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6645   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6646   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6647   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(2)<cr>
6648   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6649   if !hasmapto('<Plug>NetrwHideEdit')
6650    nmap <buffer> <c-h> <Plug>NetrwHideEdit
6651   endif
6652   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
6653   if !hasmapto('<Plug>NetrwRefresh')
6654    nmap <buffer> <c-l> <Plug>NetrwRefresh
6655   endif
6656   if !hasmapto('<Plug>NetrwTreeSqueeze')
6657    nmap <buffer> <silent> <nowait> <s-cr>	<Plug>NetrwTreeSqueeze
6658   endif
6659   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze	:call <SID>TreeSqueezeDir(0)<cr>
6660
6661   let mapsafepath     = escape(s:path, s:netrw_map_escape)
6662   let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6663
6664   nnoremap <buffer> <silent> <Plug>NetrwRefresh	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6665   if g:netrw_mousemaps == 1
6666    nmap <buffer> <leftmouse>		<Plug>NetrwLeftmouse
6667    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
6668    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6669    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(0)<cr>
6670    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6671    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(0)<cr>
6672    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6673    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(0)<cr>
6674    nmap <middlemouse>			<Plug>NetrwMiddlemouse
6675    nno  <buffer> <silent>		<middlemouse>		<Plug>NetrwMiddlemouse <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
6676    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6677    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6678    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6679    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6680    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6681    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6682    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6683   endif
6684   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6685   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6686   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6687   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6688   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6689   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6690   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6691   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6692
6693   " support user-specified maps
6694   call netrw#UserMaps(0)
6695  endif " }}}3
6696
6697"  call Dret("s:NetrwMaps")
6698endfun
6699
6700" ---------------------------------------------------------------------
6701" s:NetrwCommands: set up commands 				{{{2
6702"  If -buffer, the command is only available from within netrw buffers
6703"  Otherwise, the command is available from any window, so long as netrw
6704"  has been used at least once in the session.
6705fun! s:NetrwCommands(islocal)
6706"  call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6707
6708  com! -nargs=* -complete=file -bang	NetrwMB	call s:NetrwBookmark(<bang>0,<f-args>)
6709  com! -nargs=*			    	NetrwC	call s:NetrwSetChgwin(<q-args>)
6710  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
6711  if a:islocal
6712   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(1,<f-args>)
6713  else
6714   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(0,<f-args>)
6715  endif
6716  com! -buffer -nargs=? -complete=file	MT	call s:NetrwMarkTarget(<q-args>)
6717
6718"  call Dret("s:NetrwCommands")
6719endfun
6720
6721" ---------------------------------------------------------------------
6722" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6723"                   glob()ing only works with local files
6724fun! s:NetrwMarkFiles(islocal,...)
6725"  call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6726  let curdir = s:NetrwGetCurdir(a:islocal)
6727  let i      = 1
6728  while i <= a:0
6729   if a:islocal
6730    if v:version > 704 || (v:version == 704 && has("patch656"))
6731     let mffiles= glob(a:{i},0,1,1)
6732    else
6733     let mffiles= glob(a:{i},0,1)
6734    endif
6735   else
6736    let mffiles= [a:{i}]
6737   endif
6738"   call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6739   for mffile in mffiles
6740"    call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6741    call s:NetrwMarkFile(a:islocal,mffile)
6742   endfor
6743   let i= i + 1
6744  endwhile
6745"  call Dret("s:NetrwMarkFiles")
6746endfun
6747
6748" ---------------------------------------------------------------------
6749" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6750fun! s:NetrwMarkTarget(...)
6751"  call Dfunc("s:NetrwMarkTarget() a:0=".a:0)
6752  if a:0 == 0 || (a:0 == 1 && a:1 == "")
6753   let curdir = s:NetrwGetCurdir(1)
6754   let tgt    = b:netrw_curdir
6755  else
6756   let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6757   let tgt    = a:1
6758  endif
6759"  call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
6760  let s:netrwmftgt         = tgt
6761  let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6762  let curislocal           = b:netrw_curdir !~ '^\a\{3,}://'
6763  let svpos                = winsaveview()
6764"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6765  call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./'))
6766"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6767  call winrestview(svpos)
6768"  call Dret("s:NetrwMarkTarget")
6769endfun
6770
6771" ---------------------------------------------------------------------
6772" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6773"                  mark and unmark files.  If a markfile list exists,
6774"                  then the rename and delete functions will use it instead
6775"                  of whatever may happen to be under the cursor at that
6776"                  moment.  When the mouse and gui are available,
6777"                  shift-leftmouse may also be used to mark files.
6778"
6779"  Creates two lists
6780"    s:netrwmarkfilelist    -- holds complete paths to all marked files
6781"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
6782"
6783"  Creates a marked file match string
6784"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
6785"
6786"  Creates a buffer version of islocal
6787"    b:netrw_islocal
6788fun! s:NetrwMarkFile(islocal,fname)
6789"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6790"  call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6791
6792  " sanity check
6793  if empty(a:fname)
6794"   call Dret("s:NetrwMarkFile : empty fname")
6795   return
6796  endif
6797  let curdir = s:NetrwGetCurdir(a:islocal)
6798
6799  let ykeep   = @@
6800  let curbufnr= bufnr("%")
6801  if a:fname =~ '^\a'
6802   let leader= '\<'
6803  else
6804   let leader= ''
6805  endif
6806  if a:fname =~ '\a$'
6807   let trailer = '\>[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6808  else
6809   let trailer = '[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6810  endif
6811
6812  if exists("s:netrwmarkfilelist_".curbufnr)
6813   " markfile list pre-exists
6814"   call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6815"   call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6816"   call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6817   let b:netrw_islocal= a:islocal
6818
6819   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6820    " append filename to buffer's markfilelist
6821"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6822    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6823    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6824
6825   else
6826    " remove filename from buffer's markfilelist
6827"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6828    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6829    if s:netrwmarkfilelist_{curbufnr} == []
6830     " local markfilelist is empty; remove it entirely
6831"     call Decho("markfile list now empty",'~'.expand("<slnum>"))
6832     call s:NetrwUnmarkList(curbufnr,curdir)
6833    else
6834     " rebuild match list to display markings correctly
6835"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6836     let s:netrwmarkfilemtch_{curbufnr}= ""
6837     let first                         = 1
6838     for fname in s:netrwmarkfilelist_{curbufnr}
6839      if first
6840       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6841      else
6842       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6843      endif
6844      let first= 0
6845     endfor
6846"     call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6847    endif
6848   endif
6849
6850  else
6851   " initialize new markfilelist
6852"   call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6853
6854"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6855   let s:netrwmarkfilelist_{curbufnr}= []
6856   call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6857"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6858
6859   " build initial markfile matching pattern
6860   if a:fname =~ '/$'
6861    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6862   else
6863    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6864   endif
6865"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6866  endif
6867
6868  " handle global markfilelist
6869  if exists("s:netrwmarkfilelist")
6870   let dname= s:ComposePath(b:netrw_curdir,a:fname)
6871   if index(s:netrwmarkfilelist,dname) == -1
6872    " append new filename to global markfilelist
6873    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6874"    call Decho("append filename<".a:fname."> to global s:markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6875   else
6876    " remove new filename from global markfilelist
6877"    call Decho("remove new filename from global s:markfilelist",'~'.expand("<slnum>"))
6878"    call Decho("..filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6879    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6880"    call Decho("..ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6881    if s:netrwmarkfilelist == []
6882"     call Decho("s:netrwmarkfilelist is empty; unlet it",'~'.expand("<slnum>"))
6883     unlet s:netrwmarkfilelist
6884    endif
6885   endif
6886  else
6887   " initialize new global-directory markfilelist
6888   let s:netrwmarkfilelist= []
6889   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6890"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6891  endif
6892
6893  " set up 2match'ing to netrwmarkfilemtch_# list
6894  if has("syntax") && exists("g:syntax_on") && g:syntax_on
6895   if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6896" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6897    if exists("g:did_drchip_netrwlist_syntax")
6898     exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6899    endif
6900   else
6901" "   call Decho("2match none",'~'.expand("<slnum>"))
6902    2match none
6903   endif
6904  endif
6905  let @@= ykeep
6906"  call Decho("s:netrwmarkfilelist[".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : "")."] (avail in all buffers)",'~'.expand("<slnum>"))
6907"  call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">  (buf#".curbufnr."list)")
6908endfun
6909
6910" ---------------------------------------------------------------------
6911" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6912"                         mA: move the argument list to marked file list     (tomflist=1)
6913"                            Uses the global marked file list
6914fun! s:NetrwMarkFileArgList(islocal,tomflist)
6915"  call Dfunc("s:NetrwMarkFileArgList(islocal=".a:islocal.",tomflist=".a:tomflist.")")
6916
6917  let svpos    = winsaveview()
6918"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6919  let curdir   = s:NetrwGetCurdir(a:islocal)
6920  let curbufnr = bufnr("%")
6921
6922  if a:tomflist
6923   " mA: move argument list to marked file list
6924   while argc()
6925    let fname= argv(0)
6926"    call Decho("exe argdel ".fname,'~'.expand("<slnum>"))
6927    exe "argdel ".fnameescape(fname)
6928    call s:NetrwMarkFile(a:islocal,fname)
6929   endwhile
6930
6931  else
6932   " ma: move marked file list to argument list
6933   if exists("s:netrwmarkfilelist")
6934
6935    " for every filename in the marked list
6936    for fname in s:netrwmarkfilelist
6937"     call Decho("exe argadd ".fname,'~'.expand("<slnum>"))
6938     exe "argadd ".fnameescape(fname)
6939    endfor	" for every file in the marked list
6940
6941    " unmark list and refresh
6942    call s:NetrwUnmarkList(curbufnr,curdir)
6943    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6944"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6945    NetrwKeepj call winrestview(svpos)
6946   endif
6947  endif
6948
6949"  call Dret("s:NetrwMarkFileArgList")
6950endfun
6951
6952" ---------------------------------------------------------------------
6953" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6954"                          compress/decompress files using the programs
6955"                          in g:netrw_compress and g:netrw_uncompress,
6956"                          using g:netrw_compress_suffix to know which to
6957"                          do.  By default:
6958"                            g:netrw_compress        = "gzip"
6959"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6960fun! s:NetrwMarkFileCompress(islocal)
6961"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
6962  let svpos    = winsaveview()
6963"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6964  let curdir   = s:NetrwGetCurdir(a:islocal)
6965  let curbufnr = bufnr("%")
6966
6967  " sanity check
6968  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6969   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6970"   call Dret("s:NetrwMarkFileCompress")
6971   return
6972  endif
6973"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6974
6975  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6976
6977   " for every filename in the marked list
6978   for fname in s:netrwmarkfilelist_{curbufnr}
6979    let sfx= substitute(fname,'^.\{-}\(\.\a\+\)$','\1','')
6980"    call Decho("extracted sfx<".sfx.">",'~'.expand("<slnum>"))
6981    if exists("g:netrw_decompress['".sfx."']")
6982     " fname has a suffix indicating that its compressed; apply associated decompression routine
6983     let exe= g:netrw_decompress[sfx]
6984"     call Decho("fname<".fname."> is compressed so decompress with <".exe.">",'~'.expand("<slnum>"))
6985     let exe= netrw#WinPath(exe)
6986     if a:islocal
6987      if g:netrw_keepdir
6988       let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6989      endif
6990      call system(exe." ".fname)
6991      if v:shell_error
6992       NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6993      endif
6994     else
6995      let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6996      NetrwKeepj call s:RemoteSystem(exe." ".fname)
6997     endif
6998
6999    endif
7000    unlet sfx
7001
7002    if exists("exe")
7003     unlet exe
7004    elseif a:islocal
7005     " fname not a compressed file, so compress it
7006     call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
7007     if v:shell_error
7008      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_compress<".g:netrw_compress."> to something that works",104)
7009     endif
7010    else
7011     " fname not a compressed file, so compress it
7012     NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
7013    endif
7014   endfor	" for every file in the marked list
7015
7016   call s:NetrwUnmarkList(curbufnr,curdir)
7017   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7018"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7019   NetrwKeepj call winrestview(svpos)
7020  endif
7021"  call Dret("s:NetrwMarkFileCompress")
7022endfun
7023
7024" ---------------------------------------------------------------------
7025" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
7026"                      If no marked files, then set up directory as the
7027"                      target.  Currently does not support copying entire
7028"                      directories.  Uses the local-buffer marked file list.
7029"                      Returns 1=success  (used by NetrwMarkFileMove())
7030"                              0=failure
7031fun! s:NetrwMarkFileCopy(islocal,...)
7032"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
7033
7034  let curdir   = s:NetrwGetCurdir(a:islocal)
7035  let curbufnr = bufnr("%")
7036  if b:netrw_curdir !~ '/$'
7037   if !exists("b:netrw_curdir")
7038    let b:netrw_curdir= curdir
7039   endif
7040   let b:netrw_curdir= b:netrw_curdir."/"
7041  endif
7042
7043  " sanity check
7044  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7045   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7046"   call Dret("s:NetrwMarkFileCopy")
7047   return
7048  endif
7049"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7050
7051  if !exists("s:netrwmftgt")
7052   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
7053"   call Dret("s:NetrwMarkFileCopy 0")
7054   return 0
7055  endif
7056"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7057
7058  if a:islocal &&  s:netrwmftgt_islocal
7059   " Copy marked files, local directory to local directory
7060"   call Decho("copy from local to local",'~'.expand("<slnum>"))
7061   if !executable(g:netrw_localcopycmd)
7062    call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
7063"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
7064    return
7065   endif
7066
7067   " copy marked files while within the same directory (ie. allow renaming)
7068   if simplify(s:netrwmftgt) == simplify(b:netrw_curdir)
7069    if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
7070     " only one marked file
7071"     call Decho("case: only one marked file",'~'.expand("<slnum>"))
7072     let args    = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
7073     let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
7074    elseif a:0 == 1
7075"     call Decho("case: handling one input argument",'~'.expand("<slnum>"))
7076     " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
7077     let args    = s:ShellEscape(b:netrw_curdir.a:1)
7078     let oldname = a:1
7079    else
7080     " copy multiple marked files inside the same directory
7081"     call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
7082     let s:recursive= 1
7083     for oldname in s:netrwmarkfilelist_{bufnr("%")}
7084      let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
7085      if ret == 0
7086       break
7087      endif
7088     endfor
7089     unlet s:recursive
7090     call s:NetrwUnmarkList(curbufnr,curdir)
7091"     call Dret("s:NetrwMarkFileCopy ".ret)
7092     return ret
7093    endif
7094
7095    call inputsave()
7096    let newname= input("Copy ".oldname." to : ",oldname,"file")
7097    call inputrestore()
7098    if newname == ""
7099"     call Dret("s:NetrwMarkFileCopy 0")
7100     return 0
7101    endif
7102    let args= s:ShellEscape(oldname)
7103    let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
7104   else
7105    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
7106    let tgt = s:ShellEscape(s:netrwmftgt)
7107   endif
7108   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7109    let args= substitute(args,'/','\\','g')
7110    let tgt = substitute(tgt, '/','\\','g')
7111   endif
7112   if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
7113   if tgt  =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
7114   if args =~ '//'|let args= substitute(args,'//','/','g')|endif
7115   if tgt  =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
7116"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
7117"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
7118   if isdirectory(s:NetrwFile(args))
7119"    call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
7120    let copycmd= g:netrw_localcopydircmd
7121"    call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
7122    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7123     " window's xcopy doesn't copy a directory to a target properly.  Instead, it copies a directory's
7124     " contents to a target.  One must append the source directory name to the target to get xcopy to
7125     " do the right thing.
7126     let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
7127"     call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
7128    endif
7129   else
7130    let copycmd= g:netrw_localcopycmd
7131   endif
7132   if g:netrw_localcopycmd =~ '\s'
7133    let copycmd     = substitute(copycmd,'\s.*$','','')
7134    let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
7135    let copycmd     = netrw#WinPath(copycmd).copycmdargs
7136   else
7137    let copycmd = netrw#WinPath(copycmd)
7138   endif
7139"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
7140"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
7141"   call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
7142"   call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
7143   call system(copycmd.g:netrw_localcopycmdopt." '".args."' '".tgt."'")
7144   if v:shell_error != 0
7145    if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7146     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)
7147    else
7148     call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
7149    endif
7150"    call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
7151    return 0
7152   endif
7153
7154  elseif  a:islocal && !s:netrwmftgt_islocal
7155   " Copy marked files, local directory to remote directory
7156"   call Decho("copy from local to remote",'~'.expand("<slnum>"))
7157   NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
7158
7159  elseif !a:islocal &&  s:netrwmftgt_islocal
7160   " Copy marked files, remote directory to local directory
7161"   call Decho("copy from remote to local",'~'.expand("<slnum>"))
7162   NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
7163
7164  elseif !a:islocal && !s:netrwmftgt_islocal
7165   " Copy marked files, remote directory to remote directory
7166"   call Decho("copy from remote to remote",'~'.expand("<slnum>"))
7167   let curdir = getcwd()
7168   let tmpdir = s:GetTempfile("")
7169   if tmpdir !~ '/'
7170    let tmpdir= curdir."/".tmpdir
7171   endif
7172   if exists("*mkdir")
7173    call mkdir(tmpdir)
7174   else
7175    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(tmpdir,1))
7176    if v:shell_error != 0
7177     call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
7178"     call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
7179     return
7180    endif
7181   endif
7182   if isdirectory(s:NetrwFile(tmpdir))
7183    if s:NetrwLcd(tmpdir)
7184"     call Dret("s:NetrwMarkFileCopy : lcd failure")
7185     return
7186    endif
7187    NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
7188    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
7189    NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
7190    if getcwd() == tmpdir
7191     for fname in s:netrwmarkfilelist_{bufnr('%')}
7192      NetrwKeepj call s:NetrwDelete(fname)
7193     endfor
7194     if s:NetrwLcd(curdir)
7195"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7196      return
7197     endif
7198     if delete(tmpdir,"d")
7199      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
7200     endif
7201    else
7202     if s:NetrwLcd(curdir)
7203"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7204      return
7205     endif
7206    endif
7207   endif
7208  endif
7209
7210  " -------
7211  " cleanup
7212  " -------
7213"  call Decho("cleanup",'~'.expand("<slnum>"))
7214  " remove markings from local buffer
7215  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7216"  call Decho(" g:netrw_fastbrowse  =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
7217"  call Decho(" s:netrwmftgt        =".s:netrwmftgt,'~'.expand("<slnum>"))
7218"  call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
7219"  call Decho(" curdir              =".curdir,'~'.expand("<slnum>"))
7220"  call Decho(" a:islocal           =".a:islocal,'~'.expand("<slnum>"))
7221"  call Decho(" curbufnr            =".curbufnr,'~'.expand("<slnum>"))
7222  if exists("s:recursive")
7223"   call Decho(" s:recursive         =".s:recursive,'~'.expand("<slnum>"))
7224  else
7225"   call Decho(" s:recursive         =n/a",'~'.expand("<slnum>"))
7226  endif
7227  " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
7228  if g:netrw_fastbrowse <= 1
7229   NetrwKeepj call s:LocalBrowseRefresh()
7230  else
7231   " refresh local and targets for fast browsing
7232   if !exists("s:recursive")
7233    " remove markings from local buffer
7234"    call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
7235    NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
7236   endif
7237
7238   " refresh buffers
7239   if s:netrwmftgt_islocal
7240"    call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
7241    NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7242   endif
7243   if a:islocal && s:netrwmftgt != curdir
7244"    call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
7245    NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
7246   endif
7247  endif
7248
7249"  call Dret("s:NetrwMarkFileCopy 1")
7250  return 1
7251endfun
7252
7253" ---------------------------------------------------------------------
7254" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
7255"                      invoke vim's diff mode on the marked files.
7256"                      Either two or three files can be so handled.
7257"                      Uses the global marked file list.
7258fun! s:NetrwMarkFileDiff(islocal)
7259"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
7260  let curbufnr= bufnr("%")
7261
7262  " sanity check
7263  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7264   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7265"   call Dret("s:NetrwMarkFileDiff")
7266   return
7267  endif
7268  let curdir= s:NetrwGetCurdir(a:islocal)
7269"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7270
7271  if exists("s:netrwmarkfilelist_{".curbufnr."}")
7272   let cnt    = 0
7273   for fname in s:netrwmarkfilelist
7274    let cnt= cnt + 1
7275    if cnt == 1
7276"     call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
7277     exe "NetrwKeepj e ".fnameescape(fname)
7278     diffthis
7279    elseif cnt == 2 || cnt == 3
7280     vsplit
7281     wincmd l
7282"     call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
7283     exe "NetrwKeepj e ".fnameescape(fname)
7284     diffthis
7285    else
7286     break
7287    endif
7288   endfor
7289   call s:NetrwUnmarkList(curbufnr,curdir)
7290  endif
7291
7292"  call Dret("s:NetrwMarkFileDiff")
7293endfun
7294
7295" ---------------------------------------------------------------------
7296" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
7297"                       Uses global markfilelist
7298fun! s:NetrwMarkFileEdit(islocal)
7299"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
7300
7301  let curdir   = s:NetrwGetCurdir(a:islocal)
7302  let curbufnr = bufnr("%")
7303
7304  " sanity check
7305  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7306   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7307"   call Dret("s:NetrwMarkFileEdit")
7308   return
7309  endif
7310"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7311
7312  if exists("s:netrwmarkfilelist_{curbufnr}")
7313   call s:SetRexDir(a:islocal,curdir)
7314   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7315   " unmark markedfile list
7316"   call s:NetrwUnmarkList(curbufnr,curdir)
7317   call s:NetrwUnmarkAll()
7318"   call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
7319   exe "sil args ".flist
7320  endif
7321  echo "(use :bn, :bp to navigate files; :Rex to return)"
7322
7323"  call Dret("s:NetrwMarkFileEdit")
7324endfun
7325
7326" ---------------------------------------------------------------------
7327" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
7328fun! s:NetrwMarkFileQFEL(islocal,qfel)
7329"  call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
7330  call s:NetrwUnmarkAll()
7331  let curbufnr= bufnr("%")
7332
7333  if !empty(a:qfel)
7334   for entry in a:qfel
7335    let bufnmbr= entry["bufnr"]
7336"    call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
7337    if !exists("s:netrwmarkfilelist_{curbufnr}")
7338"     call Decho("case: no marked file list",'~'.expand("<slnum>"))
7339     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7340    elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
7341     " s:NetrwMarkFile will remove duplicate entries from the marked file list.
7342     " So, this test lets two or more hits on the same pattern to be ignored.
7343"     call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
7344     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7345    else
7346"     call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
7347    endif
7348   endfor
7349   echo "(use me to edit marked files)"
7350  else
7351   call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
7352  endif
7353
7354"  call Dret("s:NetrwMarkFileQFEL")
7355endfun
7356
7357" ---------------------------------------------------------------------
7358" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
7359"                     mx enbloc=0: Uses the local marked-file list, applies command to each file individually
7360"                     mX enbloc=1: Uses the global marked-file list, applies command to entire list
7361fun! s:NetrwMarkFileExe(islocal,enbloc)
7362"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")")
7363  let svpos    = winsaveview()
7364"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7365  let curdir   = s:NetrwGetCurdir(a:islocal)
7366  let curbufnr = bufnr("%")
7367
7368  if a:enbloc == 0
7369   " individually apply command to files, one at a time
7370    " sanity check
7371    if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7372     NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7373"     call Dret("s:NetrwMarkFileExe")
7374     return
7375    endif
7376"    call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7377
7378    if exists("s:netrwmarkfilelist_{curbufnr}")
7379     " get the command
7380     call inputsave()
7381     let cmd= input("Enter command: ","","file")
7382     call inputrestore()
7383"     call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7384     if cmd == ""
7385"      call Dret("s:NetrwMarkFileExe : early exit, empty command")
7386      return
7387     endif
7388
7389     " apply command to marked files, individually.  Substitute: filename -> %
7390     " If no %, then append a space and the filename to the command
7391     for fname in s:netrwmarkfilelist_{curbufnr}
7392      if a:islocal
7393       if g:netrw_keepdir
7394	let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
7395       endif
7396      else
7397       let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
7398      endif
7399      if cmd =~ '%'
7400       let xcmd= substitute(cmd,'%',fname,'g')
7401      else
7402       let xcmd= cmd.' '.fname
7403      endif
7404      if a:islocal
7405"       call Decho("local: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7406       let ret= system(xcmd)
7407      else
7408"       call Decho("remote: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7409       let ret= s:RemoteSystem(xcmd)
7410      endif
7411      if v:shell_error < 0
7412       NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7413       break
7414      else
7415       echo ret
7416      endif
7417     endfor
7418
7419   " unmark marked file list
7420   call s:NetrwUnmarkList(curbufnr,curdir)
7421
7422   " refresh the listing
7423   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7424"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7425   NetrwKeepj call winrestview(svpos)
7426  else
7427   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7428  endif
7429
7430 else " apply command to global list of files, en bloc
7431
7432  call inputsave()
7433  let cmd= input("Enter command: ","","file")
7434  call inputrestore()
7435"  call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7436  if cmd == ""
7437"   call Dret("s:NetrwMarkFileExe : early exit, empty command")
7438   return
7439  endif
7440  if cmd =~ '%'
7441   let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7442  else
7443   let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7444  endif
7445  if a:islocal
7446   call system(cmd)
7447   if v:shell_error < 0
7448    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7449   endif
7450  else
7451   let ret= s:RemoteSystem(cmd)
7452  endif
7453  call s:NetrwUnmarkAll()
7454
7455  " refresh the listing
7456  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7457"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7458  NetrwKeepj call winrestview(svpos)
7459
7460 endif
7461
7462"  call Dret("s:NetrwMarkFileExe")
7463endfun
7464
7465" ---------------------------------------------------------------------
7466" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7467"                  as the marked file(s) (toggles suffix presence)
7468"                  Uses the local marked file list.
7469fun! s:NetrwMarkHideSfx(islocal)
7470"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7471  let svpos    = winsaveview()
7472"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7473  let curbufnr = bufnr("%")
7474
7475  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7476  if exists("s:netrwmarkfilelist_{curbufnr}")
7477
7478   for fname in s:netrwmarkfilelist_{curbufnr}
7479"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7480     " construct suffix pattern
7481     if fname =~ '\.'
7482      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7483     else
7484      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7485     endif
7486     " determine if its in the hiding list or not
7487     let inhidelist= 0
7488     if g:netrw_list_hide != ""
7489      let itemnum = 0
7490      let hidelist= split(g:netrw_list_hide,',')
7491      for hidepat in hidelist
7492       if sfxpat == hidepat
7493        let inhidelist= 1
7494        break
7495       endif
7496       let itemnum= itemnum + 1
7497      endfor
7498     endif
7499"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7500     if inhidelist
7501      " remove sfxpat from list
7502      call remove(hidelist,itemnum)
7503      let g:netrw_list_hide= join(hidelist,",")
7504     elseif g:netrw_list_hide != ""
7505      " append sfxpat to non-empty list
7506      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7507     else
7508      " set hiding list to sfxpat
7509      let g:netrw_list_hide= sfxpat
7510     endif
7511    endfor
7512
7513   " refresh the listing
7514   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7515"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7516   NetrwKeepj call winrestview(svpos)
7517  else
7518   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7519  endif
7520
7521"  call Dret("s:NetrwMarkHideSfx")
7522endfun
7523
7524" ---------------------------------------------------------------------
7525" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7526"                     Uses the local marked-file list.
7527fun! s:NetrwMarkFileVimCmd(islocal)
7528"  call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")")
7529  let svpos    = winsaveview()
7530"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7531  let curdir   = s:NetrwGetCurdir(a:islocal)
7532  let curbufnr = bufnr("%")
7533
7534  " sanity check
7535  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7536   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7537"   call Dret("s:NetrwMarkFileVimCmd")
7538   return
7539  endif
7540"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7541
7542  if exists("s:netrwmarkfilelist_{curbufnr}")
7543   " get the command
7544   call inputsave()
7545   let cmd= input("Enter vim command: ","","file")
7546   call inputrestore()
7547"   call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7548   if cmd == ""
7549"    "   call Dret("s:NetrwMarkFileVimCmd : early exit, empty command")
7550    return
7551   endif
7552
7553   " apply command to marked files.  Substitute: filename -> %
7554   " If no %, then append a space and the filename to the command
7555   for fname in s:netrwmarkfilelist_{curbufnr}
7556"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7557    if a:islocal
7558     1split
7559     exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7560"     call Decho("local<".fname.">: exe ".cmd,'~'.expand("<slnum>"))
7561     exe cmd
7562     exe "sil! keepalt wq!"
7563    else
7564"     call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET",'~'.expand("<slnum>"))
7565     echo "sorry, \"mv\" not supported yet for remote files"
7566    endif
7567   endfor
7568
7569   " unmark marked file list
7570   call s:NetrwUnmarkList(curbufnr,curdir)
7571
7572   " refresh the listing
7573   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7574"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7575   NetrwKeepj call winrestview(svpos)
7576  else
7577   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7578  endif
7579
7580"  call Dret("s:NetrwMarkFileVimCmd")
7581endfun
7582
7583" ---------------------------------------------------------------------
7584" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7585"                  as the marked file(s) (toggles suffix presence)
7586"                  Uses the local marked file list.
7587fun! s:NetrwMarkHideSfx(islocal)
7588"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7589  let svpos    = winsaveview()
7590"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7591  let curbufnr = bufnr("%")
7592
7593  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7594  if exists("s:netrwmarkfilelist_{curbufnr}")
7595
7596   for fname in s:netrwmarkfilelist_{curbufnr}
7597"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7598     " construct suffix pattern
7599     if fname =~ '\.'
7600      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7601     else
7602      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7603     endif
7604     " determine if its in the hiding list or not
7605     let inhidelist= 0
7606     if g:netrw_list_hide != ""
7607      let itemnum = 0
7608      let hidelist= split(g:netrw_list_hide,',')
7609      for hidepat in hidelist
7610       if sfxpat == hidepat
7611        let inhidelist= 1
7612        break
7613       endif
7614       let itemnum= itemnum + 1
7615      endfor
7616     endif
7617"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7618     if inhidelist
7619      " remove sfxpat from list
7620      call remove(hidelist,itemnum)
7621      let g:netrw_list_hide= join(hidelist,",")
7622     elseif g:netrw_list_hide != ""
7623      " append sfxpat to non-empty list
7624      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7625     else
7626      " set hiding list to sfxpat
7627      let g:netrw_list_hide= sfxpat
7628     endif
7629    endfor
7630
7631   " refresh the listing
7632   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7633"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7634   NetrwKeepj call winrestview(svpos)
7635  else
7636   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7637  endif
7638
7639"  call Dret("s:NetrwMarkHideSfx")
7640endfun
7641
7642" ---------------------------------------------------------------------
7643" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7644"                     Uses the global markfilelist
7645fun! s:NetrwMarkFileGrep(islocal)
7646"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7647  let svpos    = winsaveview()
7648"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7649  let curbufnr = bufnr("%")
7650  let curdir   = s:NetrwGetCurdir(a:islocal)
7651
7652  if exists("s:netrwmarkfilelist")
7653"   call Decho("using s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7654   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7655"   call Decho("keeping copy of s:netrwmarkfilelist in function-local variable,'~'.expand("<slnum>"))"
7656   call s:NetrwUnmarkAll()
7657  else
7658"   call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7659   let netrwmarkfilelist= "*"
7660  endif
7661
7662  " ask user for pattern
7663"  call Decho("ask user for search pattern",'~'.expand("<slnum>"))
7664  call inputsave()
7665  let pat= input("Enter pattern: ","")
7666  call inputrestore()
7667  let patbang = ""
7668  if pat =~ '^!'
7669   let patbang = "!"
7670   let pat     = strpart(pat,2)
7671  endif
7672  if pat =~ '^\i'
7673   let pat    = escape(pat,'/')
7674   let pat    = '/'.pat.'/'
7675  else
7676   let nonisi = pat[0]
7677  endif
7678
7679  " use vimgrep for both local and remote
7680"  call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7681  try
7682   exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7683  catch /^Vim\%((\a\+)\)\=:E480/
7684   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7685"   call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7686   return
7687  endtry
7688  echo "(use :cn, :cp to navigate, :Rex to return)"
7689
7690  2match none
7691"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7692  NetrwKeepj call winrestview(svpos)
7693
7694  if exists("nonisi")
7695   " original, user-supplied pattern did not begin with a character from isident
7696"   call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7697   if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7698    call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7699   endif
7700  endif
7701
7702"  call Dret("s:NetrwMarkFileGrep")
7703endfun
7704
7705" ---------------------------------------------------------------------
7706" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7707"                      uses the global marked file list
7708"                      s:netrwmfloc= 0: target directory is remote
7709"                                  = 1: target directory is local
7710fun! s:NetrwMarkFileMove(islocal)
7711"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7712  let curdir   = s:NetrwGetCurdir(a:islocal)
7713  let curbufnr = bufnr("%")
7714
7715  " sanity check
7716  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7717   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7718"   call Dret("s:NetrwMarkFileMove")
7719   return
7720  endif
7721"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7722
7723  if !exists("s:netrwmftgt")
7724   NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7725"   call Dret("s:NetrwMarkFileCopy 0")
7726   return 0
7727  endif
7728"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7729
7730  if      a:islocal &&  s:netrwmftgt_islocal
7731   " move: local -> local
7732"   call Decho("move from local to local",'~'.expand("<slnum>"))
7733"   call Decho("local to local move",'~'.expand("<slnum>"))
7734   if !executable(g:netrw_localmovecmd)
7735    call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7736"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7737    return
7738   endif
7739   let tgt = s:ShellEscape(s:netrwmftgt)
7740"   call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7741   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7742    let tgt= substitute(tgt, '/','\\','g')
7743"    call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7744    if g:netrw_localmovecmd =~ '\s'
7745     let movecmd     = substitute(g:netrw_localmovecmd,'\s.*$','','')
7746     let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7747     let movecmd     = netrw#WinPath(movecmd).movecmdargs
7748"     call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7749    else
7750     let movecmd = netrw#WinPath(movecmd)
7751"     call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7752    endif
7753   else
7754    let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7755"    call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7756   endif
7757   for fname in s:netrwmarkfilelist_{bufnr("%")}
7758    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7759     let fname= substitute(fname,'/','\\','g')
7760    endif
7761"    call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7762    let ret= system(movecmd.g:netrw_localmovecmdopt." ".s:ShellEscape(fname)." ".tgt)
7763    if v:shell_error != 0
7764     if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7765      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)
7766     else
7767      call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7768     endif
7769     break
7770    endif
7771   endfor
7772
7773  elseif  a:islocal && !s:netrwmftgt_islocal
7774   " move: local -> remote
7775"   call Decho("move from local to remote",'~'.expand("<slnum>"))
7776"   call Decho("copy",'~'.expand("<slnum>"))
7777   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7778   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7779"   call Decho("remove",'~'.expand("<slnum>"))
7780   for fname in mflist
7781    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7782    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7783   endfor
7784   unlet mflist
7785
7786  elseif !a:islocal &&  s:netrwmftgt_islocal
7787   " move: remote -> local
7788"   call Decho("move from remote to local",'~'.expand("<slnum>"))
7789"   call Decho("copy",'~'.expand("<slnum>"))
7790   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7791   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7792"   call Decho("remove",'~'.expand("<slnum>"))
7793   for fname in mflist
7794    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7795    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7796   endfor
7797   unlet mflist
7798
7799  elseif !a:islocal && !s:netrwmftgt_islocal
7800   " move: remote -> remote
7801"   call Decho("move from remote to remote",'~'.expand("<slnum>"))
7802"   call Decho("copy",'~'.expand("<slnum>"))
7803   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7804   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7805"   call Decho("remove",'~'.expand("<slnum>"))
7806   for fname in mflist
7807    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7808    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7809   endfor
7810   unlet mflist
7811  endif
7812
7813  " -------
7814  " cleanup
7815  " -------
7816"  call Decho("cleanup",'~'.expand("<slnum>"))
7817
7818  " remove markings from local buffer
7819  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7820
7821  " refresh buffers
7822  if !s:netrwmftgt_islocal
7823"   call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7824   NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7825  endif
7826  if a:islocal
7827"   call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7828   NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7829  endif
7830  if g:netrw_fastbrowse <= 1
7831"   call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7832   NetrwKeepj call s:LocalBrowseRefresh()
7833  endif
7834
7835"  call Dret("s:NetrwMarkFileMove")
7836endfun
7837
7838" ---------------------------------------------------------------------
7839" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7840"                       using the hardcopy command.  Local marked-file list only.
7841fun! s:NetrwMarkFilePrint(islocal)
7842"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7843  let curbufnr= bufnr("%")
7844
7845  " sanity check
7846  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7847   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7848"   call Dret("s:NetrwMarkFilePrint")
7849   return
7850  endif
7851"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7852  let curdir= s:NetrwGetCurdir(a:islocal)
7853
7854  if exists("s:netrwmarkfilelist_{curbufnr}")
7855   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7856   call s:NetrwUnmarkList(curbufnr,curdir)
7857   for fname in netrwmarkfilelist
7858    if a:islocal
7859     if g:netrw_keepdir
7860      let fname= s:ComposePath(curdir,fname)
7861     endif
7862    else
7863     let fname= curdir.fname
7864    endif
7865    1split
7866    " the autocmds will handle both local and remote files
7867"    call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7868    exe "sil NetrwKeepj e ".fnameescape(fname)
7869"    call Decho("hardcopy",'~'.expand("<slnum>"))
7870    hardcopy
7871    q
7872   endfor
7873   2match none
7874  endif
7875"  call Dret("s:NetrwMarkFilePrint")
7876endfun
7877
7878" ---------------------------------------------------------------------
7879" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7880"                        files when given a regexp (for which a prompt is
7881"                        issued) (matches to name of files).
7882fun! s:NetrwMarkFileRegexp(islocal)
7883"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7884
7885  " get the regular expression
7886  call inputsave()
7887  let regexp= input("Enter regexp: ","","file")
7888  call inputrestore()
7889
7890  if a:islocal
7891   let curdir= s:NetrwGetCurdir(a:islocal)
7892"   call Decho("curdir<".fnameescape(curdir).">")
7893   " get the matching list of files using local glob()
7894"   call Decho("handle local regexp",'~'.expand("<slnum>"))
7895   let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7896   if v:version > 704 || (v:version == 704 && has("patch656"))
7897    let filelist= glob(s:ComposePath(dirname,regexp),0,1,1)
7898   else
7899    let files   = glob(s:ComposePath(dirname,regexp),0,0)
7900    let filelist= split(files,"\n")
7901   endif
7902"   call Decho("files<".string(filelist).">",'~'.expand("<slnum>"))
7903
7904  " mark the list of files
7905  for fname in filelist
7906   if fname =~ '^'.fnameescape(curdir)
7907"    call Decho("fname<".substitute(fname,'^'.fnameescape(curdir).'/','','').">",'~'.expand("<slnum>"))
7908    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^'.fnameescape(curdir).'/','',''))
7909   else
7910"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7911    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7912   endif
7913  endfor
7914
7915  else
7916"   call Decho("handle remote regexp",'~'.expand("<slnum>"))
7917
7918   " convert displayed listing into a filelist
7919   let eikeep = &ei
7920   let areg   = @a
7921   sil NetrwKeepj %y a
7922   setl ei=all ma
7923"   call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7924   1split
7925   NetrwKeepj call s:NetrwEnew()
7926   NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
7927   sil NetrwKeepj norm! "ap
7928   NetrwKeepj 2
7929   let bannercnt= search('^" =====','W')
7930   exe "sil NetrwKeepj 1,".bannercnt."d"
7931   setl bt=nofile
7932   if     g:netrw_liststyle == s:LONGLIST
7933    sil NetrwKeepj %s/\s\{2,}\S.*$//e
7934    call histdel("/",-1)
7935   elseif g:netrw_liststyle == s:WIDELIST
7936    sil NetrwKeepj %s/\s\{2,}/\r/ge
7937    call histdel("/",-1)
7938   elseif g:netrw_liststyle == s:TREELIST
7939    exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7940    sil! NetrwKeepj g/^ .*$/d
7941    call histdel("/",-1)
7942    call histdel("/",-1)
7943   endif
7944   " convert regexp into the more usual glob-style format
7945   let regexp= substitute(regexp,'\*','.*','g')
7946"   call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7947   exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7948   call histdel("/",-1)
7949   let filelist= getline(1,line("$"))
7950   q!
7951   for filename in filelist
7952    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7953   endfor
7954   unlet filelist
7955   let @a  = areg
7956   let &ei = eikeep
7957  endif
7958  echo "  (use me to edit marked files)"
7959
7960"  call Dret("s:NetrwMarkFileRegexp")
7961endfun
7962
7963" ---------------------------------------------------------------------
7964" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7965"                        Uses the local marked file list.
7966fun! s:NetrwMarkFileSource(islocal)
7967"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7968  let curbufnr= bufnr("%")
7969
7970  " sanity check
7971  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7972   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7973"   call Dret("s:NetrwMarkFileSource")
7974   return
7975  endif
7976"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7977  let curdir= s:NetrwGetCurdir(a:islocal)
7978
7979  if exists("s:netrwmarkfilelist_{curbufnr}")
7980   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7981   call s:NetrwUnmarkList(curbufnr,curdir)
7982   for fname in netrwmarkfilelist
7983    if a:islocal
7984     if g:netrw_keepdir
7985      let fname= s:ComposePath(curdir,fname)
7986     endif
7987    else
7988     let fname= curdir.fname
7989    endif
7990    " the autocmds will handle sourcing both local and remote files
7991"    call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7992    exe "so ".fnameescape(fname)
7993   endfor
7994   2match none
7995  endif
7996"  call Dret("s:NetrwMarkFileSource")
7997endfun
7998
7999" ---------------------------------------------------------------------
8000" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
8001"                     Uses the global markfilelist
8002fun! s:NetrwMarkFileTag(islocal)
8003"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
8004  let svpos    = winsaveview()
8005"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8006  let curdir   = s:NetrwGetCurdir(a:islocal)
8007  let curbufnr = bufnr("%")
8008
8009  " sanity check
8010  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
8011   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
8012"   call Dret("s:NetrwMarkFileTag")
8013   return
8014  endif
8015"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
8016
8017  if exists("s:netrwmarkfilelist")
8018"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
8019   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
8020   call s:NetrwUnmarkAll()
8021
8022   if a:islocal
8023
8024"    call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("<slnum>"))
8025    call system(g:netrw_ctags." ".netrwmarkfilelist)
8026    if v:shell_error
8027     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
8028    endif
8029
8030   else
8031    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
8032    call netrw#Obtain(a:islocal,"tags")
8033    let curdir= b:netrw_curdir
8034    1split
8035    NetrwKeepj e tags
8036    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
8037"    call Decho("curdir<".curdir."> path<".path.">",'~'.expand("<slnum>"))
8038    exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
8039    call histdel("/",-1)
8040    wq!
8041   endif
8042   2match none
8043   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8044"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8045   call winrestview(svpos)
8046  endif
8047
8048"  call Dret("s:NetrwMarkFileTag")
8049endfun
8050
8051" ---------------------------------------------------------------------
8052" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
8053"   Sets up two variables,
8054"     s:netrwmftgt         : holds the target directory
8055"     s:netrwmftgt_islocal : 0=target directory is remote
8056"                            1=target directory is local
8057fun! s:NetrwMarkFileTgt(islocal)
8058" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
8059  let svpos  = winsaveview()
8060"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8061  let curdir = s:NetrwGetCurdir(a:islocal)
8062  let hadtgt = exists("s:netrwmftgt")
8063  if !exists("w:netrw_bannercnt")
8064   let w:netrw_bannercnt= b:netrw_bannercnt
8065  endif
8066
8067  " set up target
8068  if line(".") < w:netrw_bannercnt
8069"   call Decho("set up target: line(.) < w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
8070   " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
8071   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
8072"    call Decho("cursor in banner region, and target already is <".b:netrw_curdir.">: removing target",'~'.expand("<slnum>"))
8073    unlet s:netrwmftgt s:netrwmftgt_islocal
8074    if g:netrw_fastbrowse <= 1
8075     call s:LocalBrowseRefresh()
8076    endif
8077    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8078"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8079    call winrestview(svpos)
8080"    call Dret("s:NetrwMarkFileTgt : removed target")
8081    return
8082   else
8083    let s:netrwmftgt= b:netrw_curdir
8084"    call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8085   endif
8086
8087  else
8088   " get word under cursor.
8089   "  * If directory, use it for the target.
8090   "  * If file, use b:netrw_curdir for the target
8091"   call Decho("get word under cursor",'~'.expand("<slnum>"))
8092   let curword= s:NetrwGetWord()
8093   let tgtdir = s:ComposePath(curdir,curword)
8094   if a:islocal && isdirectory(s:NetrwFile(tgtdir))
8095    let s:netrwmftgt = tgtdir
8096"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8097   elseif !a:islocal && tgtdir =~ '/$'
8098    let s:netrwmftgt = tgtdir
8099"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8100   else
8101    let s:netrwmftgt = curdir
8102"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8103   endif
8104  endif
8105  if a:islocal
8106   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
8107   let s:netrwmftgt= simplify(s:netrwmftgt)
8108"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8109  endif
8110  if g:netrw_cygwin
8111   let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
8112   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
8113  endif
8114  let s:netrwmftgt_islocal= a:islocal
8115
8116  " need to do refresh so that the banner will be updated
8117  "  s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
8118  if g:netrw_fastbrowse <= 1
8119"   call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers",'~'.expand("<slnum>"))
8120   call s:LocalBrowseRefresh()
8121  endif
8122"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8123  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8124   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop))
8125  else
8126   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8127  endif
8128"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8129  call winrestview(svpos)
8130  if !hadtgt
8131   sil! NetrwKeepj norm! j
8132  endif
8133
8134"  call Decho("getmatches=".string(getmatches()),'~'.expand("<slnum>"))
8135"  call Decho("s:netrwmarkfilelist=".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : 'n/a'),'~'.expand("<slnum>"))
8136"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
8137endfun
8138
8139" ---------------------------------------------------------------------
8140" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
8141fun! s:NetrwGetCurdir(islocal)
8142"  call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
8143
8144  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8145   let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
8146"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
8147  elseif !exists("b:netrw_curdir")
8148   let b:netrw_curdir= getcwd()
8149"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
8150  endif
8151
8152"  call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>"))
8153  if b:netrw_curdir !~ '\<\a\{3,}://'
8154   let curdir= b:netrw_curdir
8155"   call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
8156   if g:netrw_keepdir == 0
8157    call s:NetrwLcd(curdir)
8158   endif
8159  endif
8160
8161"  call Dret("s:NetrwGetCurdir <".curdir.">")
8162  return b:netrw_curdir
8163endfun
8164
8165" ---------------------------------------------------------------------
8166" s:NetrwOpenFile: query user for a filename and open it {{{2
8167fun! s:NetrwOpenFile(islocal)
8168"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
8169  let ykeep= @@
8170  call inputsave()
8171  let fname= input("Enter filename: ")
8172  call inputrestore()
8173"  call Decho("(s:NetrwOpenFile) fname<".fname.">",'~'.expand("<slnum>"))
8174
8175  " determine if Lexplore is in use
8176  if exists("t:netrw_lexbufnr")
8177   " check if t:netrw_lexbufnr refers to a netrw window
8178"   call Decho("(s:netrwOpenFile) ..t:netrw_lexbufnr=".t:netrw_lexbufnr,'~'.expand("<slnum>"))
8179   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
8180   if lexwinnr != -1 && exists("g:netrw_chgwin") && g:netrw_chgwin != -1
8181"    call Decho("(s:netrwOpenFile) ..Lexplore in use",'~'.expand("<slnum>"))
8182    exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
8183    exe "NetrwKeepj e ".fnameescape(fname)
8184    let @@= ykeep
8185"    call Dret("s:NetrwOpenFile : creating a file with Lexplore mode")
8186   endif
8187  endif
8188
8189  " Does the filename contain a path?
8190  if fname !~ '[/\\]'
8191   if exists("b:netrw_curdir")
8192    if exists("g:netrw_quiet")
8193     let netrw_quiet_keep = g:netrw_quiet
8194    endif
8195    let g:netrw_quiet = 1
8196    " save position for benefit of Rexplore
8197    let s:rexposn_{bufnr("%")}= winsaveview()
8198"    call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
8199    if b:netrw_curdir =~ '/$'
8200     exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
8201    else
8202     exe "e ".fnameescape(b:netrw_curdir."/".fname)
8203    endif
8204    if exists("netrw_quiet_keep")
8205     let g:netrw_quiet= netrw_quiet_keep
8206    else
8207     unlet g:netrw_quiet
8208    endif
8209   endif
8210  else
8211   exe "NetrwKeepj e ".fnameescape(fname)
8212  endif
8213  let @@= ykeep
8214"  call Dret("s:NetrwOpenFile")
8215endfun
8216
8217" ---------------------------------------------------------------------
8218" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
8219"               For the mapping to this function be made via
8220"               netrwPlugin, you'll need to have had
8221"               g:netrw_usetab set to non-zero.
8222fun! netrw#Shrink()
8223"  call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
8224  let curwin  = winnr()
8225  let wiwkeep = &wiw
8226  set wiw=1
8227
8228  if &ft == "netrw"
8229   if winwidth(0) > g:netrw_wiw
8230    let t:netrw_winwidth= winwidth(0)
8231    exe "vert resize ".g:netrw_wiw
8232    wincmd l
8233    if winnr() == curwin
8234     wincmd h
8235    endif
8236"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8237   else
8238    exe "vert resize ".t:netrw_winwidth
8239"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8240   endif
8241
8242  elseif exists("t:netrw_lexbufnr")
8243   exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
8244   if     winwidth(bufwinnr(t:netrw_lexbufnr)) >  g:netrw_wiw
8245    let t:netrw_winwidth= winwidth(0)
8246    exe "vert resize ".g:netrw_wiw
8247    wincmd l
8248    if winnr() == curwin
8249     wincmd h
8250    endif
8251"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8252   elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
8253    exe "vert resize ".t:netrw_winwidth
8254"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8255   else
8256    call netrw#Lexplore(0,0)
8257   endif
8258
8259  else
8260   call netrw#Lexplore(0,0)
8261  endif
8262  let wiw= wiwkeep
8263
8264"  call Dret("netrw#Shrink")
8265endfun
8266
8267" ---------------------------------------------------------------------
8268" s:NetSortSequence: allows user to edit the sorting sequence {{{2
8269fun! s:NetSortSequence(islocal)
8270"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
8271
8272  let ykeep= @@
8273  let svpos= winsaveview()
8274"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8275  call inputsave()
8276  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
8277  call inputrestore()
8278
8279  " refresh the listing
8280  let g:netrw_sort_sequence= newsortseq
8281  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8282"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8283  NetrwKeepj call winrestview(svpos)
8284  let @@= ykeep
8285
8286"  call Dret("NetSortSequence")
8287endfun
8288
8289" ---------------------------------------------------------------------
8290" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
8291"   User access provided by the <mF> mapping. (see :help netrw-mF)
8292"   Used by many MarkFile functions.
8293fun! s:NetrwUnmarkList(curbufnr,curdir)
8294"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
8295
8296  "  remove all files in local marked-file list from global list
8297  if exists("s:netrwmarkfilelist")
8298   for mfile in s:netrwmarkfilelist_{a:curbufnr}
8299    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
8300    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
8301    call remove(s:netrwmarkfilelist,idx)            " remove from global list
8302   endfor
8303   if s:netrwmarkfilelist == []
8304    unlet s:netrwmarkfilelist
8305   endif
8306
8307   " getting rid of the local marked-file lists is easy
8308   unlet s:netrwmarkfilelist_{a:curbufnr}
8309  endif
8310  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
8311   unlet s:netrwmarkfilemtch_{a:curbufnr}
8312  endif
8313  2match none
8314"  call Dret("s:NetrwUnmarkList")
8315endfun
8316
8317" ---------------------------------------------------------------------
8318" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
8319fun! s:NetrwUnmarkAll()
8320"  call Dfunc("s:NetrwUnmarkAll()")
8321  if exists("s:netrwmarkfilelist")
8322   unlet s:netrwmarkfilelist
8323  endif
8324  sil call s:NetrwUnmarkAll2()
8325  2match none
8326"  call Dret("s:NetrwUnmarkAll")
8327endfun
8328
8329" ---------------------------------------------------------------------
8330" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
8331fun! s:NetrwUnmarkAll2()
8332"  call Dfunc("s:NetrwUnmarkAll2()")
8333  redir => netrwmarkfilelist_let
8334  let
8335  redir END
8336  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
8337  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
8338  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
8339  for flist in netrwmarkfilelist_list
8340   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
8341   unlet s:netrwmarkfilelist_{curbufnr}
8342   unlet s:netrwmarkfilemtch_{curbufnr}
8343  endfor
8344"  call Dret("s:NetrwUnmarkAll2")
8345endfun
8346
8347" ---------------------------------------------------------------------
8348" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
8349"
8350" Marked files are in two types of lists:
8351"    s:netrwmarkfilelist    -- holds complete paths to all marked files
8352"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
8353"
8354" Marked files suitable for use with 2match are in:
8355"    s:netrwmarkfilemtch_#   -- used with 2match to display marked files
8356fun! s:NetrwUnMarkFile(islocal)
8357"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
8358  let svpos    = winsaveview()
8359"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8360  let curbufnr = bufnr("%")
8361
8362  " unmark marked file list
8363  " (although I expect s:NetrwUpload() to do it, I'm just making sure)
8364  if exists("s:netrwmarkfilelist")
8365"   "   call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
8366   unlet s:netrwmarkfilelist
8367  endif
8368
8369  let ibuf= 1
8370  while ibuf < bufnr("$")
8371   if exists("s:netrwmarkfilelist_".ibuf)
8372    unlet s:netrwmarkfilelist_{ibuf}
8373    unlet s:netrwmarkfilemtch_{ibuf}
8374   endif
8375   let ibuf = ibuf + 1
8376  endwhile
8377  2match none
8378
8379"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8380"call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8381call winrestview(svpos)
8382"  call Dret("s:NetrwUnMarkFile")
8383endfun
8384
8385" ---------------------------------------------------------------------
8386" s:NetrwMenu: generates the menu for gvim and netrw {{{2
8387fun! s:NetrwMenu(domenu)
8388
8389  if !exists("g:NetrwMenuPriority")
8390   let g:NetrwMenuPriority= 80
8391  endif
8392
8393  if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8394"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
8395
8396   if !exists("s:netrw_menu_enabled") && a:domenu
8397"    call Decho("initialize menu",'~'.expand("<slnum>"))
8398    let s:netrw_menu_enabled= 1
8399    exe 'sil! menu '.g:NetrwMenuPriority.'.1      '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
8400    exe 'sil! menu '.g:NetrwMenuPriority.'.5      '.g:NetrwTopLvlMenu.'-Sep1-	:'
8401    exe 'sil! menu '.g:NetrwMenuPriority.'.6      '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
8402    exe 'sil! menu '.g:NetrwMenuPriority.'.7      '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
8403    if g:netrw_dirhistmax > 0
8404     exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
8405     exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
8406     exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
8407     exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
8408    else
8409     exe 'sil! menu '.g:NetrwMenuPriority.'.8     '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History	:echo "(disabled)"'."\<cr>"
8410    endif
8411    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1    '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o	o'
8412    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2    '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v	v'
8413    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3    '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t	t'
8414    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4    '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p	p'
8415    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
8416    exe 'sil! menu '.g:NetrwMenuPriority.'.9.6    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
8417    exe 'sil! menu '.g:NetrwMenuPriority.'.9.7    '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
8418    exe 'sil! menu '.g:NetrwMenuPriority.'.9.8    '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
8419    exe 'sil! menu '.g:NetrwMenuPriority.'.9.9    '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
8420    exe 'sil! menu '.g:NetrwMenuPriority.'.10     '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
8421    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
8422    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
8423    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
8424    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
8425    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
8426    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t	t'
8427    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
8428    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1   '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
8429    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
8430    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
8431    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
8432    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
8433    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
8434    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
8435    exe 'sil! menu '.g:NetrwMenuPriority.'.13     '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
8436    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
8437    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
8438    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3   '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
8439    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4   '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
8440    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5   '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
8441    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6   '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
8442    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7   '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
8443    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8   '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
8444    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9   '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
8445    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10  '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
8446    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11  '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
8447    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12  '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
8448    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13  '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
8449    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14  '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
8450    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15  '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
8451    exe 'sil! menu '.g:NetrwMenuPriority.'.15     '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
8452    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i	:let w:netrw_liststyle=0<cr><c-L>'
8453    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i	:let w:netrw_liststyle=1<cr><c-L>'
8454    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i	:let w:netrw_liststyle=2<cr><c-L>'
8455    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i	:let w:netrw_liststyle=3<cr><c-L>'
8456    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>'
8457    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>'
8458    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>'
8459    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3   '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
8460    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>'
8461    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>'
8462    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>'
8463    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>'
8464    exe 'sil! menu '.g:NetrwMenuPriority.'.17     '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
8465    exe 'sil! menu '.g:NetrwMenuPriority.'.18     '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
8466    let s:netrw_menucnt= 28
8467    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
8468    call s:NetrwTgtMenu()      " let bookmarks and history be easy targets
8469
8470   elseif !a:domenu
8471    let s:netrwcnt = 0
8472    let curwin     = winnr()
8473    windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8474    exe curwin."wincmd w"
8475
8476    if s:netrwcnt <= 1
8477"     call Decho("clear menus",'~'.expand("<slnum>"))
8478     exe 'sil! unmenu '.g:NetrwTopLvlMenu
8479"     call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8480     sil! unlet s:netrw_menu_enabled
8481    endif
8482   endif
8483"   call Dret("NetrwMenu")
8484   return
8485  endif
8486
8487endfun
8488
8489" ---------------------------------------------------------------------
8490" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8491"                Used by the O maps (as <SID>NetrwObtain())
8492fun! s:NetrwObtain(islocal)
8493"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8494
8495  let ykeep= @@
8496  if exists("s:netrwmarkfilelist_{bufnr('%')}")
8497   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8498   call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8499   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
8500  else
8501   call netrw#Obtain(a:islocal,s:NetrwGetWord())
8502  endif
8503  let @@= ykeep
8504
8505"  call Dret("NetrwObtain")
8506endfun
8507
8508" ---------------------------------------------------------------------
8509" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
8510"   If there's only one window, then the window will first be split.
8511"   Returns:
8512"     choice = 0 : didn't have to choose
8513"     choice = 1 : saved modified file in window first
8514"     choice = 2 : didn't save modified file, opened window
8515"     choice = 3 : cancel open
8516fun! s:NetrwPrevWinOpen(islocal)
8517"  call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")")
8518
8519  let ykeep= @@
8520  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8521  let curdir = b:netrw_curdir
8522
8523  " get last window number and the word currently under the cursor
8524  let origwin   = winnr()
8525  let lastwinnr = winnr("$")
8526  let curword   = s:NetrwGetWord()
8527  let choice    = 0
8528  let s:prevwinopen= 1	" lets s:NetrwTreeDir() know that NetrwPrevWinOpen called it
8529  let s:treedir = s:NetrwTreeDir(a:islocal)
8530  let curdir    = s:treedir
8531"  call Decho("winnr($)#".lastwinnr." curword<".curword.">",'~'.expand("<slnum>"))
8532
8533  let didsplit = 0
8534  if lastwinnr == 1
8535   " if only one window, open a new one first
8536"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("<slnum>"))
8537   " g:netrw_preview=0: preview window shown in a horizontally split window
8538   " g:netrw_preview=1: preview window shown in a vertically   split window
8539   if g:netrw_preview
8540    " vertically split preview window
8541    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8542"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("<slnum>"))
8543    exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8544   else
8545    " horizontally split preview window
8546    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8547"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8548    exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8549   endif
8550   let didsplit = 1
8551"   call Decho("did split",'~'.expand("<slnum>"))
8552
8553  else
8554   NetrwKeepj call s:SaveBufVars()
8555   let eikeep= &ei
8556   setl ei=all
8557   wincmd p
8558"   call Decho("wincmd p  (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
8559
8560   " prevwinnr: the window number of the "prev" window
8561   " prevbufnr: the buffer number of the buffer in the "prev" window
8562   " bnrcnt   : the qty of windows open on the "prev" buffer
8563   let prevwinnr   = winnr()
8564   let prevbufnr   = bufnr("%")
8565   let prevbufname = bufname("%")
8566   let prevmod     = &mod
8567   let bnrcnt      = 0
8568   NetrwKeepj call s:RestoreBufVars()
8569"   call Decho("after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr,'~'.expand("<slnum>"))
8570
8571   " if the previous window's buffer has been changed (ie. its modified flag is set),
8572   " and it doesn't appear in any other extant window, then ask the
8573   " user if s/he wants to abandon modifications therein.
8574   if prevmod
8575"    call Decho("detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr(),'~'.expand("<slnum>"))
8576    windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8577"    call Decho("prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr,'~'.expand("<slnum>"))
8578    exe prevwinnr."wincmd w"
8579
8580    if bnrcnt == 1 && &hidden == 0
8581     " only one copy of the modified buffer in a window, and
8582     " hidden not set, so overwriting will lose the modified file.  Ask first...
8583     let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8584"     call Decho("prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("<slnum>"))
8585     let &ei= eikeep
8586
8587     if choice == 1
8588      " Yes -- write file & then browse
8589      let v:errmsg= ""
8590      sil w
8591      if v:errmsg != ""
8592       call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8593       exe origwin."wincmd w"
8594       let &ei = eikeep
8595       let @@  = ykeep
8596"       call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">")
8597       return choice
8598      endif
8599
8600     elseif choice == 2
8601      " No -- don't worry about changed file, just browse anyway
8602"      call Decho("don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")",'~'.expand("<slnum>"))
8603      echomsg "**note** changes to ".prevbufname." abandoned"
8604
8605     else
8606      " Cancel -- don't do this
8607"      call Decho("cancel, don't browse, switch to win#".origwin,'~'.expand("<slnum>"))
8608      exe origwin."wincmd w"
8609      let &ei= eikeep
8610      let @@ = ykeep
8611"      call Dret("s:NetrwPrevWinOpen ".choice." : cancelled")
8612      return choice
8613     endif
8614    endif
8615   endif
8616   let &ei= eikeep
8617  endif
8618
8619  " restore b:netrw_curdir (window split/enew may have lost it)
8620  let b:netrw_curdir= curdir
8621  if a:islocal < 2
8622   if a:islocal
8623    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
8624   else
8625    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
8626   endif
8627  endif
8628  let @@= ykeep
8629"  call Dret("s:NetrwPrevWinOpen ".choice)
8630  return choice
8631endfun
8632
8633" ---------------------------------------------------------------------
8634" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8635"                Always assumed to be local -> remote
8636"                call s:NetrwUpload(filename, target)
8637"                call s:NetrwUpload(filename, target, fromdirectory)
8638fun! s:NetrwUpload(fname,tgt,...)
8639"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
8640
8641  if a:tgt =~ '^\a\{3,}://'
8642   let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
8643  else
8644   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
8645  endif
8646"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
8647
8648  if a:0 > 0
8649   let fromdir= a:1
8650  else
8651   let fromdir= getcwd()
8652  endif
8653"  call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
8654
8655  if type(a:fname) == 1
8656   " handle uploading a single file using NetWrite
8657"   call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8658   1split
8659"   call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8660   exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8661"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8662   if a:tgt =~ '/$'
8663    let wfname= substitute(a:fname,'^.*/','','')
8664"    call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8665    exe "w! ".fnameescape(a:tgt.wfname)
8666   else
8667"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8668    exe "w ".fnameescape(a:tgt)
8669"    call Decho("done writing local->remote",'~'.expand("<slnum>"))
8670   endif
8671   q!
8672
8673  elseif type(a:fname) == 3
8674   " handle uploading a list of files via scp
8675"   call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8676   let curdir= getcwd()
8677   if a:tgt =~ '^scp:'
8678    if s:NetrwLcd(fromdir)
8679"     call Dret("s:NetrwUpload : lcd failure")
8680     return
8681    endif
8682    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8683    let args    = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8684    if exists("g:netrw_port") && g:netrw_port != ""
8685     let useport= " ".g:netrw_scpport." ".g:netrw_port
8686    else
8687     let useport= ""
8688    endif
8689    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8690    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8691    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8692    if s:NetrwLcd(curdir)
8693"     call Dret("s:NetrwUpload : lcd failure")
8694     return
8695    endif
8696
8697   elseif a:tgt =~ '^ftp:'
8698    call s:NetrwMethod(a:tgt)
8699
8700    if b:netrw_method == 2
8701     " handle uploading a list of files via ftp+.netrc
8702     let netrw_fname = b:netrw_fname
8703     sil NetrwKeepj new
8704"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8705
8706     NetrwKeepj put =g:netrw_ftpmode
8707"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8708
8709     if exists("g:netrw_ftpextracmd")
8710      NetrwKeepj put =g:netrw_ftpextracmd
8711"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8712     endif
8713
8714     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8715"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8716
8717     if tgtdir == ""
8718      let tgtdir= '/'
8719     endif
8720     NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8721"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8722
8723     for fname in a:fname
8724      NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8725"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8726     endfor
8727
8728     if exists("g:netrw_port") && g:netrw_port != ""
8729      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8730     else
8731"      call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8732      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8733     endif
8734     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8735     sil NetrwKeepj g/Local directory now/d
8736     call histdel("/",-1)
8737     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8738      call netrw#ErrorMsg(s:ERROR,getline(1),14)
8739     else
8740      bw!|q
8741     endif
8742
8743    elseif b:netrw_method == 3
8744     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8745     let netrw_fname= b:netrw_fname
8746     NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8747     let tmpbufnr= bufnr("%")
8748     setl ff=unix
8749
8750     if exists("g:netrw_port") && g:netrw_port != ""
8751      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8752"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8753     else
8754      NetrwKeepj put ='open '.g:netrw_machine
8755"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8756     endif
8757
8758     if exists("g:netrw_uid") && g:netrw_uid != ""
8759      if exists("g:netrw_ftp") && g:netrw_ftp == 1
8760       NetrwKeepj put =g:netrw_uid
8761"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8762       if exists("s:netrw_passwd")
8763        NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8764       endif
8765"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8766      elseif exists("s:netrw_passwd")
8767       NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8768"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8769      endif
8770     endif
8771
8772     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8773"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8774
8775     if exists("b:netrw_fname") && b:netrw_fname != ""
8776      NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8777"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8778     endif
8779
8780     if exists("g:netrw_ftpextracmd")
8781      NetrwKeepj put =g:netrw_ftpextracmd
8782"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8783     endif
8784
8785     for fname in a:fname
8786      NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8787"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8788     endfor
8789
8790     " perform ftp:
8791     " -i       : turns off interactive prompting from ftp
8792     " -n  unix : DON'T use <.netrc>, even though it exists
8793     " -n  win32: quit being obnoxious about password
8794     NetrwKeepj norm! 1G"_dd
8795     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8796     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8797     sil NetrwKeepj g/Local directory now/d
8798     call histdel("/",-1)
8799     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8800      let debugkeep= &debug
8801      setl debug=msg
8802      call netrw#ErrorMsg(s:ERROR,getline(1),15)
8803      let &debug = debugkeep
8804      let mod    = 1
8805     else
8806      bw!|q
8807     endif
8808    elseif !exists("b:netrw_method") || b:netrw_method < 0
8809"     call Dret("s:#NetrwUpload : unsupported method")
8810     return
8811    endif
8812   else
8813    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
8814   endif
8815  endif
8816
8817"  call Dret("s:NetrwUpload")
8818endfun
8819
8820" ---------------------------------------------------------------------
8821" s:NetrwPreview: supports netrw's "p" map {{{2
8822fun! s:NetrwPreview(path) range
8823"  call Dfunc("NetrwPreview(path<".a:path.">)")
8824"  call Decho("g:netrw_alto   =".(exists("g:netrw_alto")?    g:netrw_alto    : 'n/a'),'~'.expand("<slnum>"))
8825"  call Decho("g:netrw_preview=".(exists("g:netrw_preview")? g:netrw_preview : 'n/a'),'~'.expand("<slnum>"))
8826  let ykeep= @@
8827  NetrwKeepj call s:NetrwOptionsSave("s:")
8828  if a:path !~ '^\*\{1,2}/' && a:path !~ '^\a\{3,}://'
8829   NetrwKeepj call s:NetrwOptionsSafe(1)
8830  else
8831   NetrwKeepj call s:NetrwOptionsSafe(0)
8832  endif
8833  if has("quickfix")
8834"   call Decho("has quickfix",'~'.expand("<slnum>"))
8835   if !isdirectory(s:NetrwFile(a:path))
8836"    call Decho("good; not previewing a directory",'~'.expand("<slnum>"))
8837    if g:netrw_preview
8838     " vertical split
8839     let pvhkeep = &pvh
8840     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8841     let &pvh    = winwidth(0) - winsz
8842"     call Decho("g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily)  g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8843    else
8844     " horizontal split
8845     let pvhkeep = &pvh
8846     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8847     let &pvh    = winheight(0) - winsz
8848"     call Decho("!g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily)  g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8849    endif
8850    " g:netrw_preview   g:netrw_alto
8851    "    1 : vert        1: top       -- preview window is vertically   split off and on the left
8852    "    1 : vert        0: bot       -- preview window is vertically   split off and on the right
8853    "    0 :             1: top       -- preview window is horizontally split off and on the top
8854    "    0 :             0: bot       -- preview window is horizontally split off and on the bottom
8855    "
8856    " Note that the file being previewed is already known to not be a directory, hence we can avoid doing a LocalBrowseCheck() check via
8857    " the BufEnter event set up in netrwPlugin.vim
8858"    call Decho("exe ".(g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path),'~'.expand("<slnum>"))
8859    let eikeep = &ei
8860    set ei=BufEnter
8861    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8862    let &ei= eikeep
8863"    call Decho("winnr($)=".winnr("$"),'~'.expand("<slnum>"))
8864    if exists("pvhkeep")
8865     let &pvh= pvhkeep
8866    endif
8867   elseif !exists("g:netrw_quiet")
8868    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
8869   endif
8870  elseif !exists("g:netrw_quiet")
8871   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
8872  endif
8873  NetrwKeepj call s:NetrwOptionsRestore("s:")
8874  let @@= ykeep
8875"  call Dret("NetrwPreview")
8876endfun
8877
8878" ---------------------------------------------------------------------
8879" s:NetrwRefresh: {{{2
8880fun! s:NetrwRefresh(islocal,dirname)
8881"  call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") g:netrw_hide=".g:netrw_hide." g:netrw_sort_direction=".g:netrw_sort_direction)
8882  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
8883  setl ma noro
8884"  call Decho("setl ma noro",'~'.expand("<slnum>"))
8885"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8886  let ykeep      = @@
8887  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8888   if !exists("w:netrw_treetop")
8889    if exists("b:netrw_curdir")
8890     let w:netrw_treetop= b:netrw_curdir
8891    else
8892     let w:netrw_treetop= getcwd()
8893    endif
8894   endif
8895   NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
8896  endif
8897
8898  " save the cursor position before refresh.
8899  let screenposn = winsaveview()
8900"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8901
8902"  call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8903"  call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
8904  sil! NetrwKeepj %d _
8905  if a:islocal
8906   NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
8907  else
8908   NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
8909  endif
8910
8911  " restore position
8912"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8913  NetrwKeepj call winrestview(screenposn)
8914
8915  " restore file marks
8916  if has("syntax") && exists("g:syntax_on") && g:syntax_on
8917   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8918" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8919    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8920   else
8921" "   call Decho("2match none  (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8922    2match none
8923   endif
8924 endif
8925
8926"  restore
8927  let @@= ykeep
8928"  call Dret("s:NetrwRefresh")
8929endfun
8930
8931" ---------------------------------------------------------------------
8932" s:NetrwRefreshDir: refreshes a directory by name {{{2
8933"                    Called by NetrwMarkFileCopy()
8934"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
8935fun! s:NetrwRefreshDir(islocal,dirname)
8936"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) g:netrw_fastbrowse=".g:netrw_fastbrowse)
8937  if g:netrw_fastbrowse == 0
8938   " slowest mode (keep buffers refreshed, local or remote)
8939"   call Decho("slowest mode: keep buffers refreshed, local or remote",'~'.expand("<slnum>"))
8940   let tgtwin= bufwinnr(a:dirname)
8941"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin,'~'.expand("<slnum>"))
8942
8943   if tgtwin > 0
8944    " tgtwin is being displayed, so refresh it
8945    let curwin= winnr()
8946"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")",'~'.expand("<slnum>"))
8947    exe tgtwin."wincmd w"
8948    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8949    exe curwin."wincmd w"
8950
8951   elseif bufnr(a:dirname) > 0
8952    let bn= bufnr(a:dirname)
8953"    call Decho("bd bufnr(".a:dirname.")=".bn,'~'.expand("<slnum>"))
8954    exe "sil keepj bd ".bn
8955   endif
8956
8957  elseif g:netrw_fastbrowse <= 1
8958"   call Decho("medium-speed mode: refresh local buffers only",'~'.expand("<slnum>"))
8959   NetrwKeepj call s:LocalBrowseRefresh()
8960  endif
8961"  call Dret("s:NetrwRefreshDir")
8962endfun
8963
8964" ---------------------------------------------------------------------
8965" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8966" window number to do its editing in.
8967" Supports   [count]C  where the count, if present, is used to specify
8968" a window to use for editing via the <cr> mapping.
8969fun! s:NetrwSetChgwin(...)
8970"  call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
8971  if a:0 > 0
8972"   call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8973   if a:1 == ""    " :NetrwC win#
8974    let g:netrw_chgwin= winnr()
8975   else              " :NetrwC
8976    let g:netrw_chgwin= a:1
8977   endif
8978  elseif v:count > 0 " [count]C
8979   let g:netrw_chgwin= v:count
8980  else               " C
8981   let g:netrw_chgwin= winnr()
8982  endif
8983  echo "editing window now set to window#".g:netrw_chgwin
8984"  call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
8985endfun
8986
8987" ---------------------------------------------------------------------
8988" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8989"          What this function does is to compute a priority for the patterns
8990"          in the g:netrw_sort_sequence.  It applies a substitute to any
8991"          "files" that satisfy each pattern, putting the priority / in
8992"          front.  An "*" pattern handles the default priority.
8993fun! s:NetrwSetSort()
8994"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
8995  let ykeep= @@
8996  if w:netrw_liststyle == s:LONGLIST
8997   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
8998  else
8999   let seqlist  = g:netrw_sort_sequence
9000  endif
9001  " sanity check -- insure that * appears somewhere
9002  if seqlist == ""
9003   let seqlist= '*'
9004  elseif seqlist !~ '\*'
9005   let seqlist= seqlist.',*'
9006  endif
9007  let priority = 1
9008  while seqlist != ""
9009   if seqlist =~ ','
9010    let seq     = substitute(seqlist,',.*$','','e')
9011    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
9012   else
9013    let seq     = seqlist
9014    let seqlist = ""
9015   endif
9016   if priority < 10
9017    let spriority= "00".priority.g:netrw_sepchr
9018   elseif priority < 100
9019    let spriority= "0".priority.g:netrw_sepchr
9020   else
9021    let spriority= priority.g:netrw_sepchr
9022   endif
9023"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
9024
9025   " sanity check
9026   if w:netrw_bannercnt > line("$")
9027    " apparently no files were left after a Hiding pattern was used
9028"    call Dret("SetSort : no files left after hiding")
9029    return
9030   endif
9031   if seq == '*'
9032    let starpriority= spriority
9033   else
9034    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
9035    call histdel("/",-1)
9036    " sometimes multiple sorting patterns will match the same file or directory.
9037    " The following substitute is intended to remove the excess matches.
9038    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
9039    NetrwKeepj call histdel("/",-1)
9040   endif
9041   let priority = priority + 1
9042  endwhile
9043  if exists("starpriority")
9044   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
9045   NetrwKeepj call histdel("/",-1)
9046  endif
9047
9048  " Following line associated with priority -- items that satisfy a priority
9049  " pattern get prefixed by ###/ which permits easy sorting by priority.
9050  " Sometimes files can satisfy multiple priority patterns -- only the latest
9051  " priority pattern needs to be retained.  So, at this point, these excess
9052  " priority prefixes need to be removed, but not directories that happen to
9053  " be just digits themselves.
9054  exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
9055  NetrwKeepj call histdel("/",-1)
9056  let @@= ykeep
9057
9058"  call Dret("SetSort")
9059endfun
9060
9061" ---------------------------------------------------------------------
9062" s:NetrwSetTgt: sets the target to the specified choice index {{{2
9063"    Implements [count]Tb  (bookhist<b>)
9064"               [count]Th  (bookhist<h>)
9065"               See :help netrw-qb for how to make the choice.
9066fun! s:NetrwSetTgt(islocal,bookhist,choice)
9067"  call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
9068
9069  if     a:bookhist == 'b'
9070   " supports choosing a bookmark as a target using a qb-generated list
9071   let choice= a:choice - 1
9072   if exists("g:netrw_bookmarklist[".choice."]")
9073    call netrw#MakeTgt(g:netrw_bookmarklist[choice])
9074   else
9075    echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
9076   endif
9077
9078  elseif a:bookhist == 'h'
9079   " supports choosing a history stack entry as a target using a qb-generated list
9080   let choice= (a:choice % g:netrw_dirhistmax) + 1
9081   if exists("g:netrw_dirhist_".choice)
9082    let histentry = g:netrw_dirhist_{choice}
9083    call netrw#MakeTgt(histentry)
9084   else
9085    echomsg "Sorry, history#".a:choice." not available!"
9086   endif
9087  endif
9088
9089  " refresh the display
9090  if !exists("b:netrw_curdir")
9091   let b:netrw_curdir= getcwd()
9092  endif
9093  call s:NetrwRefresh(a:islocal,b:netrw_curdir)
9094
9095"  call Dret("s:NetrwSetTgt")
9096endfun
9097
9098" =====================================================================
9099" s:NetrwSortStyle: change sorting style (name - time - size - exten) and refresh display {{{2
9100fun! s:NetrwSortStyle(islocal)
9101"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
9102  NetrwKeepj call s:NetrwSaveWordPosn()
9103  let svpos= winsaveview()
9104"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9105
9106  let g:netrw_sort_by= (g:netrw_sort_by =~# '^n')? 'time' : (g:netrw_sort_by =~# '^t')? 'size' : (g:netrw_sort_by =~# '^siz')? 'exten' : 'name'
9107  NetrwKeepj norm! 0
9108  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
9109"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9110  NetrwKeepj call winrestview(svpos)
9111
9112"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
9113endfun
9114
9115" ---------------------------------------------------------------------
9116" s:NetrwSplit: mode {{{2
9117"           =0 : net   and o
9118"           =1 : net   and t
9119"           =2 : net   and v
9120"           =3 : local and o
9121"           =4 : local and t
9122"           =5 : local and v
9123fun! s:NetrwSplit(mode)
9124"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
9125
9126  let ykeep= @@
9127  call s:SaveWinVars()
9128
9129  if a:mode == 0
9130   " remote and o
9131   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
9132   if winsz == 0|let winsz= ""|endif
9133"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
9134   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
9135   let s:didsplit= 1
9136   NetrwKeepj call s:RestoreWinVars()
9137   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
9138   unlet s:didsplit
9139
9140  elseif a:mode == 1
9141   " remote and t
9142   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
9143"   call Decho("tabnew",'~'.expand("<slnum>"))
9144   tabnew
9145   let s:didsplit= 1
9146   NetrwKeepj call s:RestoreWinVars()
9147   NetrwKeepj call s:NetrwBrowse(0,newdir)
9148   unlet s:didsplit
9149
9150  elseif a:mode == 2
9151   " remote and v
9152   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
9153   if winsz == 0|let winsz= ""|endif
9154"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
9155   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
9156   let s:didsplit= 1
9157   NetrwKeepj call s:RestoreWinVars()
9158   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
9159   unlet s:didsplit
9160
9161  elseif a:mode == 3
9162   " local and o
9163   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
9164   if winsz == 0|let winsz= ""|endif
9165"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
9166   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
9167   let s:didsplit= 1
9168   NetrwKeepj call s:RestoreWinVars()
9169   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
9170   unlet s:didsplit
9171
9172  elseif a:mode == 4
9173   " local and t
9174   let cursorword  = s:NetrwGetWord()
9175   let eikeep      = &ei
9176   let netrw_winnr = winnr()
9177   let netrw_line  = line(".")
9178   let netrw_col   = virtcol(".")
9179   NetrwKeepj norm! H0
9180   let netrw_hline = line(".")
9181   setl ei=all
9182   exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
9183   exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
9184   let &ei          = eikeep
9185   let netrw_curdir = s:NetrwTreeDir(0)
9186"   call Decho("tabnew",'~'.expand("<slnum>"))
9187   tabnew
9188   let b:netrw_curdir = netrw_curdir
9189   let s:didsplit     = 1
9190   NetrwKeepj call s:RestoreWinVars()
9191   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
9192   if &ft == "netrw"
9193    setl ei=all
9194    exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
9195    exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
9196    let &ei= eikeep
9197   endif
9198   unlet s:didsplit
9199
9200  elseif a:mode == 5
9201   " local and v
9202   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
9203   if winsz == 0|let winsz= ""|endif
9204"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
9205   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
9206   let s:didsplit= 1
9207   NetrwKeepj call s:RestoreWinVars()
9208   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
9209   unlet s:didsplit
9210
9211  else
9212   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
9213  endif
9214
9215  let @@= ykeep
9216"  call Dret("s:NetrwSplit")
9217endfun
9218
9219" ---------------------------------------------------------------------
9220" s:NetrwTgtMenu: {{{2
9221fun! s:NetrwTgtMenu()
9222  if !exists("s:netrw_menucnt")
9223   return
9224  endif
9225"  call Dfunc("s:NetrwTgtMenu()")
9226
9227  " the following test assures that gvim is running, has menus available, and has menus enabled.
9228  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
9229   if exists("g:NetrwTopLvlMenu")
9230"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
9231    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
9232   endif
9233   if !exists("s:netrw_initbookhist")
9234    call s:NetrwBookHistRead()
9235   endif
9236
9237   " try to cull duplicate entries
9238   let tgtdict={}
9239
9240   " target bookmarked places
9241   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
9242"    call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
9243    let cnt= 1
9244    for bmd in g:netrw_bookmarklist
9245     if has_key(tgtdict,bmd)
9246      let cnt= cnt + 1
9247      continue
9248     endif
9249     let tgtdict[bmd]= cnt
9250     let ebmd= escape(bmd,g:netrw_menu_escape)
9251     " show bookmarks for goto menu
9252"     call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
9253     exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd."	:call netrw#MakeTgt('".bmd."')\<cr>"
9254     let cnt= cnt + 1
9255    endfor
9256   endif
9257
9258   " target directory browsing history
9259   if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
9260"    call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
9261    let histcnt = 1
9262    while histcnt <= g:netrw_dirhistmax
9263     let priority = g:netrw_dirhistcnt + histcnt
9264     if exists("g:netrw_dirhist_{histcnt}")
9265      let histentry  = g:netrw_dirhist_{histcnt}
9266      if has_key(tgtdict,histentry)
9267       let histcnt = histcnt + 1
9268       continue
9269      endif
9270      let tgtdict[histentry] = histcnt
9271      let ehistentry         = escape(histentry,g:netrw_menu_escape)
9272"      call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
9273      exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry."	:call netrw#MakeTgt('".histentry."')\<cr>"
9274     endif
9275     let histcnt = histcnt + 1
9276    endwhile
9277   endif
9278  endif
9279"  call Dret("s:NetrwTgtMenu")
9280endfun
9281
9282" ---------------------------------------------------------------------
9283" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
9284" (full path directory with trailing slash returned)
9285fun! s:NetrwTreeDir(islocal)
9286"  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)
9287"  call Decho("Determine tree directory given current cursor position")
9288"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
9289"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9290"  call Decho("w:netrw_treetop  =".(exists("w:netrw_treetop")?   w:netrw_treetop   : 'n/a'),'~'.expand("<slnum>"))
9291"  call Decho("current line<".getline(".").">")
9292
9293  if exists("s:treedir") && exists("s:prevwinopen")
9294   " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
9295"   call Decho('s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early')
9296   let treedir= s:treedir
9297   unlet s:treedir
9298   unlet s:prevwinopen
9299"   call Dret("s:NetrwTreeDir ".treedir.": early return since s:treedir existed previously")
9300   return treedir
9301  endif
9302  if exists("s:prevwinopen")
9303   unlet s:prevwinopen
9304  endif
9305
9306  if !exists("b:netrw_curdir") || b:netrw_curdir == ""
9307   let b:netrw_curdir= getcwd()
9308  endif
9309  let treedir = b:netrw_curdir
9310"  call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>"))
9311
9312  let s:treecurpos= winsaveview()
9313"  call Decho("saving posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9314
9315  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9316"   call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>"))
9317"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9318
9319   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
9320   let curline= substitute(getline('.'),"\t -->.*$",'','')
9321   if curline =~ '/$'
9322"    call Decho("extract tree subdirectory from current line",'~'.expand("<slnum>"))
9323    let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9324"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9325   elseif curline =~ '@$'
9326"    call Decho("handle symbolic link from current line",'~'.expand("<slnum>"))
9327    let treedir= resolve(substitute(substitute(getline('.'),'@.*$','','e'),'^|*\s*','','e'))
9328"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9329   else
9330"    call Decho("do not extract tree subdirectory from current line and set treedir to empty",'~'.expand("<slnum>"))
9331    let treedir= ""
9332   endif
9333
9334   " detect user attempting to close treeroot
9335"   call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>"))
9336"   call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9337"   call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~# '^'.s:treedepthstring)? '=~#' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>"))
9338   if curline !~ '^'.s:treedepthstring && getline('.') != '..'
9339"    call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>"))
9340    " now force a refresh
9341"    call Decho(".force refresh: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9342    sil! NetrwKeepj %d _
9343"    call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9344    return b:netrw_curdir
9345"   else " Decho
9346"    call Decho(".user not attempting to close treeroot",'~'.expand("<slnum>"))
9347   endif
9348
9349"   call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>"))
9350   let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
9351"   call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(potentialdir),'~'.expand("<slnum>"))
9352
9353   " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
9354"   if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
9355"    let newdir          = w:netrw_treetop.'/'.potentialdir
9356" "   call Decho("apply NetrwTreePath to newdir<".newdir.">",'~'.expand("<slnum>"))
9357"    let treedir         = s:NetrwTreePath(newdir)
9358"    let w:netrw_treetop = newdir
9359" "   call Decho("newdir <".newdir.">",'~'.expand("<slnum>"))
9360"   else
9361"    call Decho("apply NetrwTreePath to treetop<".w:netrw_treetop.">",'~'.expand("<slnum>"))
9362    let treedir = s:NetrwTreePath(w:netrw_treetop)
9363"   endif
9364  endif
9365
9366  " sanity maintenance: keep those //s away...
9367  let treedir= substitute(treedir,'//$','/','')
9368"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9369
9370"  call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9371  return treedir
9372endfun
9373
9374" ---------------------------------------------------------------------
9375" s:NetrwTreeDisplay: recursive tree display {{{2
9376fun! s:NetrwTreeDisplay(dir,depth)
9377"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
9378
9379  " insure that there are no folds
9380  setl nofen
9381
9382  " install ../ and shortdir
9383  if a:depth == ""
9384   call setline(line("$")+1,'../')
9385"   call Decho("setline#".line("$")." ../ (depth is zero)",'~'.expand("<slnum>"))
9386  endif
9387  if a:dir =~ '^\a\{3,}://'
9388   if a:dir == w:netrw_treetop
9389    let shortdir= a:dir
9390   else
9391    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
9392   endif
9393   call setline(line("$")+1,a:depth.shortdir)
9394  else
9395   let shortdir= substitute(a:dir,'^.*/','','e')
9396   call setline(line("$")+1,a:depth.shortdir.'/')
9397  endif
9398"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">",'~'.expand("<slnum>"))
9399  " append a / to dir if its missing one
9400  let dir= a:dir
9401
9402  " display subtrees (if any)
9403  let depth= s:treedepthstring.a:depth
9404"  call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>"))
9405
9406  " implement g:netrw_hide for tree listings (uses g:netrw_list_hide)
9407  if     g:netrw_hide == 1
9408   " hide given patterns
9409   let listhide= split(g:netrw_list_hide,',')
9410"   call Decho("listhide=".string(listhide))
9411   for pat in listhide
9412    call filter(w:netrw_treedict[dir],'v:val !~ "'.escape(pat,'\\').'"')
9413   endfor
9414
9415  elseif g:netrw_hide == 2
9416   " show given patterns (only)
9417   let listhide= split(g:netrw_list_hide,',')
9418"   call Decho("listhide=".string(listhide))
9419   let entries=[]
9420   for entry in w:netrw_treedict[dir]
9421    for pat in listhide
9422     if entry =~ pat
9423      call add(entries,entry)
9424      break
9425     endif
9426    endfor
9427   endfor
9428   let w:netrw_treedict[dir]= entries
9429  endif
9430  if depth != ""
9431   " always remove "." and ".." entries when there's depth
9432   call filter(w:netrw_treedict[dir],'v:val !~ "\\.\\.$"')
9433   call filter(w:netrw_treedict[dir],'v:val !~ "\\.$"')
9434  endif
9435
9436"  call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>"))
9437  for entry in w:netrw_treedict[dir]
9438   if dir =~ '/$'
9439    let direntry= substitute(dir.entry,'[@/]$','','e')
9440   else
9441    let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
9442   endif
9443"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9444   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9445"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9446    NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
9447   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9448"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9449    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9450   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9451"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9452    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9453   else
9454"    call Decho("<".entry."> is not a key in treedict (no subtree)",'~'.expand("<slnum>"))
9455    sil! NetrwKeepj call setline(line("$")+1,depth.entry)
9456   endif
9457  endfor
9458"  call Decho("displaying: ".string(getline(w:netrw_bannercnt,'$')))
9459
9460"  call Dret("NetrwTreeDisplay")
9461endfun
9462
9463" ---------------------------------------------------------------------
9464" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
9465fun! s:NetrwRefreshTreeDict(dir)
9466"  call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)")
9467  if !exists("w:netrw_treedict")
9468"   call Dret("s:NetrwRefreshTreeDict : w:netrw_treedict doesn't exist")
9469   return
9470  endif
9471
9472  for entry in w:netrw_treedict[a:dir]
9473   let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
9474"   call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9475
9476   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9477"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9478    NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
9479    let liststar                   = s:NetrwGlob(direntry,'*',1)
9480    let listdotstar                = s:NetrwGlob(direntry,'.*',1)
9481    let w:netrw_treedict[direntry] = liststar + listdotstar
9482"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9483
9484   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9485"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9486    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9487    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9488    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9489    let w:netrw_treedict[direntry]= liststar + listdotstar
9490"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9491
9492   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9493"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9494    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9495    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9496    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9497"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9498
9499   else
9500"    call Decho('not updating w:netrw_treedict['.string(direntry).'] with entry<'.string(entry).'> (no subtree)','~'.expand("<slnum>"))
9501   endif
9502  endfor
9503"  call Dret("s:NetrwRefreshTreeDict")
9504endfun
9505
9506" ---------------------------------------------------------------------
9507" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
9508"                     Called by s:PerformListing()
9509fun! s:NetrwTreeListing(dirname)
9510  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9511"   call Dfunc("s:NetrwTreeListing() bufname<".expand("%").">")
9512"   call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
9513"   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>"))
9514"   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>"))
9515
9516   " update the treetop
9517   if !exists("w:netrw_treetop")
9518"    call Decho("update the treetop  (w:netrw_treetop doesn't exist yet)",'~'.expand("<slnum>"))
9519    let w:netrw_treetop= a:dirname
9520    let s:netrw_treetop= w:netrw_treetop
9521"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>"))
9522   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
9523"    call Decho("update the treetop  (override w:netrw_treetop with a:dirname<".a:dirname.">)",'~'.expand("<slnum>"))
9524    let w:netrw_treetop= a:dirname
9525    let s:netrw_treetop= w:netrw_treetop
9526"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
9527   endif
9528   if exists("w:netrw_treetop")
9529    let s:netrw_treetop= w:netrw_treetop
9530   else
9531    let w:netrw_treetop= getcwd()
9532    let s:netrw_treetop= w:netrw_treetop
9533   endif
9534
9535   if !exists("w:netrw_treedict")
9536    " insure that we have a treedict, albeit empty
9537"    call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
9538    let w:netrw_treedict= {}
9539   endif
9540
9541   " update the dictionary for the current directory
9542"   call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>"))
9543"   call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9544   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
9545   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
9546"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
9547   exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9548
9549   " if past banner, record word
9550   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
9551    let fname= expand("<cword>")
9552   else
9553    let fname= ""
9554   endif
9555"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9556"   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>"))
9557
9558   " display from treetop on down
9559"   call Decho("(s:NetrwTreeListing) w:netrw_treetop<".w:netrw_treetop.">")
9560   NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
9561"   call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
9562
9563   " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
9564   while getline(1) =~ '^\s*$' && byte2line(1) > 0
9565"    call Decho("deleting blank line",'~'.expand("<slnum>"))
9566    1d
9567   endwhile
9568
9569   exe "setl ".g:netrw_bufsettings
9570
9571"   call Dret("s:NetrwTreeListing : bufname<".expand("%").">")
9572   return
9573  endif
9574endfun
9575
9576" ---------------------------------------------------------------------
9577" s:NetrwTreePath: returns path to current file/directory in tree listing {{{2
9578"                  Normally, treetop is w:netrw_treetop, but a
9579"                  user of the function ( netrw#SetTreetop() )
9580"                  wipes that out prior to calling this function
9581fun! s:NetrwTreePath(treetop)
9582"  call Dfunc("s:NetrwTreePath(treetop<".a:treetop.">) line#".line(".")."<".getline(".").">")
9583  if line(".") < w:netrw_bannercnt + 2
9584   let treedir= a:treetop
9585   if treedir !~ '/$'
9586    let treedir= treedir.'/'
9587   endif
9588"   call Dret("s:NetrwTreePath ".treedir." : line#".line(".")." ≤ ".(w:netrw_bannercnt+2))
9589   return treedir
9590  endif
9591
9592  let svpos = winsaveview()
9593"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9594  let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
9595"  call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
9596  let depth = substitute(depth,'^'.s:treedepthstring,'','')
9597"  call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
9598  let curline= getline('.')
9599"  call Decho("curline<".curline.'>','~'.expand("<slnum>"))
9600  if curline =~ '/$'
9601"   call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9602   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9603"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9604  elseif curline =~ '@\s\+-->'
9605"   call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9606   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9607   let treedir= substitute(treedir,'@\s\+-->.*$','','e')
9608"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9609  else
9610"   call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9611   let treedir= ""
9612  endif
9613  " construct treedir by searching backwards at correct depth
9614"  call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9615"  call Decho("initial      treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
9616  while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
9617   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9618   let treedir= dirname.treedir
9619   let depth  = substitute(depth,'^'.s:treedepthstring,'','')
9620"   call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
9621  endwhile
9622"  call Decho("treedir#1<".treedir.">",'~'.expand("<slnum>"))
9623  if a:treetop =~ '/$'
9624   let treedir= a:treetop.treedir
9625  else
9626   let treedir= a:treetop.'/'.treedir
9627  endif
9628"  call Decho("treedir#2<".treedir.">",'~'.expand("<slnum>"))
9629  let treedir= substitute(treedir,'//$','/','')
9630"  call Decho("treedir#3<".treedir.">",'~'.expand("<slnum>"))
9631"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
9632  call winrestview(svpos)
9633"  call Dret("s:NetrwTreePath <".treedir.">")
9634  return treedir
9635endfun
9636
9637" ---------------------------------------------------------------------
9638" s:NetrwWideListing: {{{2
9639fun! s:NetrwWideListing()
9640
9641  if w:netrw_liststyle == s:WIDELIST
9642"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9643   " look for longest filename (cpf=characters per filename)
9644   " cpf: characters per filename
9645   " fpl: filenames per line
9646   " fpc: filenames per column
9647   setl ma noro
9648   let keepa= @a
9649"   call Decho("setl ma noro",'~'.expand("<slnum>"))
9650   let b:netrw_cpf= 0
9651   if line("$") >= w:netrw_bannercnt
9652    " determine the maximum filename size; use that to set cpf
9653    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
9654    NetrwKeepj call histdel("/",-1)
9655   else
9656    let @a= keepa
9657"    call Dret("NetrwWideListing")
9658    return
9659   endif
9660   " allow for two spaces to separate columns
9661   let b:netrw_cpf= b:netrw_cpf + 2
9662"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
9663
9664   " determine qty files per line (fpl)
9665   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9666   if w:netrw_fpl <= 0
9667    let w:netrw_fpl= 1
9668   endif
9669"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
9670
9671   " make wide display
9672   "   fpc: files per column of wide listing
9673   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9674   NetrwKeepj call histdel("/",-1)
9675   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9676   let newcolstart = w:netrw_bannercnt + fpc
9677   let newcolend   = newcolstart + fpc - 1
9678"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9679   while line("$") >= newcolstart
9680    if newcolend > line("$") | let newcolend= line("$") | endif
9681    let newcolqty= newcolend - newcolstart
9682    exe newcolstart
9683    " COMBAK: both of the visual-mode using lines below are problematic vis-a-vis @*
9684    if newcolqty == 0
9685     exe "sil! NetrwKeepj norm! 0\<c-v>$h\"ax".w:netrw_bannercnt."G$\"ap"
9686    else
9687     exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$h"ax'.w:netrw_bannercnt.'G$"ap'
9688    endif
9689    exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
9690    exe 'sil! NetrwKeepj '.w:netrw_bannercnt
9691   endwhile
9692   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9693   NetrwKeepj call histdel("/",-1)
9694   exe 'nno <buffer> <silent> w	:call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9695   exe 'nno <buffer> <silent> b	:call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9696"   call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9697   exe "setl ".g:netrw_bufsettings
9698    let @a= keepa
9699"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9700"   call Dret("NetrwWideListing")
9701   return
9702  else
9703   if hasmapto("w","n")
9704    sil! nunmap <buffer> w
9705   endif
9706   if hasmapto("b","n")
9707    sil! nunmap <buffer> b
9708   endif
9709  endif
9710
9711endfun
9712
9713" ---------------------------------------------------------------------
9714" s:PerformListing: {{{2
9715fun! s:PerformListing(islocal)
9716"  call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9717"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9718"  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>"))
9719  sil! NetrwKeepj %d _
9720"  call DechoBuf(bufnr("%"))
9721
9722  " set up syntax highlighting {{{3
9723"  call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
9724  sil! setl ft=netrw
9725
9726  NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
9727  setl noro ma
9728"  call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
9729
9730"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
9731"   call Decho("Processing your browsing request...",'~'.expand("<slnum>"))
9732"  endif								" Decho
9733
9734"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9735  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
9736   " force a refresh for tree listings
9737"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9738   sil! NetrwKeepj %d _
9739  endif
9740
9741  " save current directory on directory history list
9742  NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
9743
9744  " Set up the banner {{{3
9745  if g:netrw_banner
9746"   call Decho("--set up banner",'~'.expand("<slnum>"))
9747   NetrwKeepj call setline(1,'" ============================================================================')
9748   if exists("g:netrw_pchk")
9749    " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9750    " failure detections.
9751    NetrwKeepj call setline(2,'" Netrw Directory Listing')
9752   else
9753    NetrwKeepj call setline(2,'" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')')
9754   endif
9755   if exists("g:netrw_pchk")
9756    let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9757   else
9758    let curdir= b:netrw_curdir
9759   endif
9760   if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9761    NetrwKeepj call setline(3,'"   '.substitute(curdir,'/','\\','g'))
9762   else
9763    NetrwKeepj call setline(3,'"   '.curdir)
9764   endif
9765   let w:netrw_bannercnt= 3
9766   NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
9767  else
9768"   call Decho("--no banner",'~'.expand("<slnum>"))
9769   NetrwKeepj 1
9770   let w:netrw_bannercnt= 1
9771  endif
9772"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9773"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9774
9775  " construct sortby string: [name|time|size|exten] [reversed]
9776  let sortby= g:netrw_sort_by
9777  if g:netrw_sort_direction =~# "^r"
9778   let sortby= sortby." reversed"
9779  endif
9780
9781  " Sorted by... {{{3
9782  if g:netrw_banner
9783"   call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9784   if g:netrw_sort_by =~# "^n"
9785"   call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9786    " sorted by name (also includes the sorting sequence in the banner)
9787    NetrwKeepj put ='\"   Sorted by      '.sortby
9788    NetrwKeepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
9789    let w:netrw_bannercnt= w:netrw_bannercnt + 2
9790   else
9791"   call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9792    " sorted by time, size, exten
9793    NetrwKeepj put ='\"   Sorted by '.sortby
9794    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9795   endif
9796   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9797"  else " Decho
9798"   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>"))
9799  endif
9800
9801  " show copy/move target, if any {{{3
9802  if g:netrw_banner
9803   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9804"    call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9805    NetrwKeepj put =''
9806    if s:netrwmftgt_islocal
9807     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9808    else
9809     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9810    endif
9811    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9812   else
9813"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
9814   endif
9815   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9816  endif
9817
9818  " Hiding...  -or-  Showing... {{{3
9819  if g:netrw_banner
9820"   call Decho("--handle hiding/showing in banner (g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9821   if g:netrw_list_hide != "" && g:netrw_hide
9822    if g:netrw_hide == 1
9823     NetrwKeepj put ='\"   Hiding:        '.g:netrw_list_hide
9824    else
9825     NetrwKeepj put ='\"   Showing:       '.g:netrw_list_hide
9826    endif
9827    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9828   endif
9829   exe "NetrwKeepj ".w:netrw_bannercnt
9830
9831"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9832   let quickhelp   = g:netrw_quickhelp%len(s:QuickHelp)
9833"   call Decho("quickhelp   =".quickhelp,'~'.expand("<slnum>"))
9834   NetrwKeepj put ='\"   Quick Help: <F1>:help  '.s:QuickHelp[quickhelp]
9835"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9836   NetrwKeepj put ='\" =============================================================================='
9837   let w:netrw_bannercnt= w:netrw_bannercnt + 2
9838"  else " Decho
9839"   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>"))
9840  endif
9841
9842  " bannercnt should index the line just after the banner
9843  if g:netrw_banner
9844   let w:netrw_bannercnt= w:netrw_bannercnt + 1
9845   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9846"   call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9847"  else " Decho
9848"   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>"))
9849  endif
9850
9851  " get list of files
9852"  call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
9853  if a:islocal
9854   NetrwKeepj call s:LocalListing()
9855  else " remote
9856   NetrwKeepj let badresult= s:NetrwRemoteListing()
9857   if badresult
9858"    call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9859"    call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9860    return
9861   endif
9862  endif
9863
9864  " manipulate the directory listing (hide, sort) {{{3
9865  if !exists("w:netrw_bannercnt")
9866   let w:netrw_bannercnt= 0
9867  endif
9868"  call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9869"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9870"  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>"))
9871
9872  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9873"   call Decho("manipulate directory listing (support hide)",'~'.expand("<slnum>"))
9874"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9875   if g:netrw_hide && g:netrw_list_hide != ""
9876    NetrwKeepj call s:NetrwListHide()
9877   endif
9878   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9879"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9880
9881    if g:netrw_sort_by =~# "^n"
9882     " sort by name
9883"     call Decho("sort by name",'~'.expand("<slnum>"))
9884     NetrwKeepj call s:NetrwSetSort()
9885
9886     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9887"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9888      if g:netrw_sort_direction =~# 'n'
9889       " name: sort by name of file
9890       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9891      else
9892       " reverse direction sorting
9893       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9894      endif
9895     endif
9896
9897     " remove priority pattern prefix
9898"     call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9899     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9900     NetrwKeepj call histdel("/",-1)
9901
9902    elseif g:netrw_sort_by =~# "^ext"
9903     " exten: sort by extension
9904     "   The histdel(...,-1) calls remove the last search from the search history
9905"     call Decho("sort by extension",'~'.expand("<slnum>"))
9906     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9907     NetrwKeepj call histdel("/",-1)
9908     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9909     NetrwKeepj call histdel("/",-1)
9910     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9911     NetrwKeepj call histdel("/",-1)
9912     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9913"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9914      if g:netrw_sort_direction =~# 'n'
9915       " normal direction sorting
9916       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9917      else
9918       " reverse direction sorting
9919       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9920      endif
9921     endif
9922     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9923     NetrwKeepj call histdel("/",-1)
9924
9925    elseif a:islocal
9926     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9927"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9928      if g:netrw_sort_direction =~# 'n'
9929"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9930       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9931      else
9932"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9933       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9934      endif
9935"     call Decho("remove leading digits/ (sorting) information from listing",'~'.expand("<slnum>"))
9936     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9937     NetrwKeepj call histdel("/",-1)
9938     endif
9939    endif
9940
9941   elseif g:netrw_sort_direction =~# 'r'
9942"    call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9943    if !g:netrw_banner || w:netrw_bannercnt < line('$')
9944     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9945     call histdel("/",-1)
9946    endif
9947   endif
9948  endif
9949"  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>"))
9950
9951  " convert to wide/tree listing {{{3
9952"  call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9953"  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>"))
9954  NetrwKeepj call s:NetrwWideListing()
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#2)",'~'.expand("<slnum>"))
9956  NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
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#3)",'~'.expand("<slnum>"))
9958
9959  " resolve symbolic links if local and (thin or tree)
9960  if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
9961"   call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9962   sil! g/@$/call s:ShowLink()
9963  endif
9964
9965  if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
9966   " place cursor on the top-left corner of the file listing
9967"   call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9968   exe 'sil! '.w:netrw_bannercnt
9969   sil! NetrwKeepj norm! 0
9970"   call Decho("  tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9971  else
9972"   call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9973"   call Decho("  w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9974"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
9975"   call Decho("  g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
9976  endif
9977
9978  " record previous current directory
9979  let w:netrw_prvdir= b:netrw_curdir
9980"  call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
9981
9982  " save certain window-oriented variables into buffer-oriented variables {{{3
9983"  call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9984"  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>"))
9985  NetrwKeepj call s:SetBufWinVars()
9986"  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>"))
9987  NetrwKeepj call s:NetrwOptionsRestore("w:")
9988"  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>"))
9989
9990  " set display to netrw display settings
9991"  call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
9992  exe "setl ".g:netrw_bufsettings
9993"  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>"))
9994  if g:netrw_liststyle == s:LONGLIST
9995"   call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9996   exe "setl ts=".(g:netrw_maxfilenamelen+1)
9997  endif
9998"  call Decho("PerformListing buffer:",'~'.expand("<slnum>"))
9999"  call DechoBuf(bufnr("%"))
10000
10001  if exists("s:treecurpos")
10002"   call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
10003"   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>"))
10004"   call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
10005   NetrwKeepj call winrestview(s:treecurpos)
10006   unlet s:treecurpos
10007  endif
10008
10009"  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>"))
10010"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
10011"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
10012endfun
10013
10014" ---------------------------------------------------------------------
10015" s:SetupNetrwStatusLine: {{{2
10016fun! s:SetupNetrwStatusLine(statline)
10017"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
10018
10019  if !exists("s:netrw_setup_statline")
10020   let s:netrw_setup_statline= 1
10021"   call Decho("do first-time status line setup",'~'.expand("<slnum>"))
10022
10023   if !exists("s:netrw_users_stl")
10024    let s:netrw_users_stl= &stl
10025   endif
10026   if !exists("s:netrw_users_ls")
10027    let s:netrw_users_ls= &laststatus
10028   endif
10029
10030   " set up User9 highlighting as needed
10031   let keepa= @a
10032   redir @a
10033   try
10034    hi User9
10035   catch /^Vim\%((\a\{3,})\)\=:E411/
10036    if &bg == "dark"
10037     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
10038    else
10039     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
10040    endif
10041   endtry
10042   redir END
10043   let @a= keepa
10044  endif
10045
10046  " set up status line (may use User9 highlighting)
10047  " insure that windows have a statusline
10048  " make sure statusline is displayed
10049  let &stl=a:statline
10050  setl laststatus=2
10051"  call Decho("stl=".&stl,'~'.expand("<slnum>"))
10052  redraw
10053
10054"  call Dret("SetupNetrwStatusLine : stl=".&stl)
10055endfun
10056
10057" =========================================
10058"  Remote Directory Browsing Support:  {{{1
10059" =========================================
10060
10061" ---------------------------------------------------------------------
10062" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
10063"  This function assumes that a long listing will be received.  Size, time,
10064"  and reverse sorts will be requested of the server but not otherwise
10065"  enforced here.
10066fun! s:NetrwRemoteFtpCmd(path,listcmd)
10067"  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 : "???")))
10068"  call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
10069  " sanity check: {{{3
10070  if !exists("w:netrw_method")
10071   if exists("b:netrw_method")
10072    let w:netrw_method= b:netrw_method
10073   else
10074    call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
10075"    call Dret("NetrwRemoteFtpCmd")
10076    return
10077   endif
10078  endif
10079
10080  " WinXX ftp uses unix style input, so set ff to unix	" {{{3
10081  let ffkeep= &ff
10082  setl ma ff=unix noro
10083"  call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
10084
10085  " clear off any older non-banner lines	" {{{3
10086  " note that w:netrw_bannercnt indexes the line after the banner
10087"  call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _  (clear off old non-banner lines)",'~'.expand("<slnum>"))
10088  exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
10089
10090  ".........................................
10091  if w:netrw_method == 2 || w:netrw_method == 5	" {{{3
10092   " ftp + <.netrc>:  Method #2
10093   if a:path != ""
10094    NetrwKeepj put ='cd \"'.a:path.'\"'
10095   endif
10096   if exists("g:netrw_ftpextracmd")
10097    NetrwKeepj put =g:netrw_ftpextracmd
10098"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
10099   endif
10100   NetrwKeepj call setline(line("$")+1,a:listcmd)
10101"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
10102   if exists("g:netrw_port") && g:netrw_port != ""
10103"    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>"))
10104    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)
10105   else
10106"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
10107    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
10108   endif
10109
10110  ".........................................
10111  elseif w:netrw_method == 3	" {{{3
10112   " ftp + machine,id,passwd,filename:  Method #3
10113    setl ff=unix
10114    if exists("g:netrw_port") && g:netrw_port != ""
10115     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
10116    else
10117     NetrwKeepj put ='open '.g:netrw_machine
10118    endif
10119
10120    " handle userid and password
10121    let host= substitute(g:netrw_machine,'\..*$','','')
10122"    call Decho("host<".host.">",'~'.expand("<slnum>"))
10123    if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
10124     call NetUserPass("ftp:".host)
10125    endif
10126    if exists("g:netrw_uid") && g:netrw_uid != ""
10127     if exists("g:netrw_ftp") && g:netrw_ftp == 1
10128      NetrwKeepj put =g:netrw_uid
10129      if exists("s:netrw_passwd") && s:netrw_passwd != ""
10130       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
10131      endif
10132     elseif exists("s:netrw_passwd")
10133      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
10134     endif
10135    endif
10136
10137   if a:path != ""
10138    NetrwKeepj put ='cd \"'.a:path.'\"'
10139   endif
10140   if exists("g:netrw_ftpextracmd")
10141    NetrwKeepj put =g:netrw_ftpextracmd
10142"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
10143   endif
10144   NetrwKeepj call setline(line("$")+1,a:listcmd)
10145
10146   " perform ftp:
10147   " -i       : turns off interactive prompting from ftp
10148   " -n  unix : DON'T use <.netrc>, even though it exists
10149   " -n  win32: quit being obnoxious about password
10150   if exists("w:netrw_bannercnt")
10151"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
10152    call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
10153"   else " Decho
10154"    call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
10155"    g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
10156   endif
10157
10158  ".........................................
10159  elseif w:netrw_method == 9	" {{{3
10160   " sftp username@machine: Method #9
10161   " s:netrw_sftp_cmd
10162   setl ff=unix
10163
10164   " restore settings
10165   let &ff= ffkeep
10166"   call Dret("NetrwRemoteFtpCmd")
10167   return
10168
10169  ".........................................
10170  else	" {{{3
10171   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
10172  endif
10173
10174  " cleanup for Windows " {{{3
10175  if has("win32") || has("win95") || has("win64") || has("win16")
10176   sil! NetrwKeepj %s/\r$//e
10177   NetrwKeepj call histdel("/",-1)
10178  endif
10179  if a:listcmd == "dir"
10180   " infer directory/link based on the file permission string
10181   sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
10182   sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
10183   NetrwKeepj call histdel("/",-1)
10184   NetrwKeepj call histdel("/",-1)
10185   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10186    exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
10187    NetrwKeepj call histdel("/",-1)
10188   endif
10189  endif
10190
10191  " ftp's listing doesn't seem to include ./ or ../ " {{{3
10192  if !search('^\.\/$\|\s\.\/$','wn')
10193   exe 'NetrwKeepj '.w:netrw_bannercnt
10194   NetrwKeepj put ='./'
10195  endif
10196  if !search('^\.\.\/$\|\s\.\.\/$','wn')
10197   exe 'NetrwKeepj '.w:netrw_bannercnt
10198   NetrwKeepj put ='../'
10199  endif
10200
10201  " restore settings " {{{3
10202  let &ff= ffkeep
10203"  call Dret("NetrwRemoteFtpCmd")
10204endfun
10205
10206" ---------------------------------------------------------------------
10207" s:NetrwRemoteListing: {{{2
10208fun! s:NetrwRemoteListing()
10209"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
10210
10211  if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
10212   let w:netrw_bannercnt= s:bannercnt
10213  endif
10214  if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
10215   let w:netrw_bannercnt= s:bannercnt
10216  endif
10217
10218  call s:RemotePathAnalysis(b:netrw_curdir)
10219
10220  " sanity check:
10221  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
10222"   call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
10223   if !executable("ftp")
10224"    call Decho("ftp is not executable",'~'.expand("<slnum>"))
10225    if !exists("g:netrw_quiet")
10226     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
10227    endif
10228    call s:NetrwOptionsRestore("w:")
10229"    call Dret("s:NetrwRemoteListing -1")
10230    return -1
10231   endif
10232
10233  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
10234"   call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
10235   if !exists("g:netrw_quiet")
10236    if g:netrw_list_cmd == ""
10237     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)
10238    else
10239     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
10240    endif
10241   endif
10242
10243   NetrwKeepj call s:NetrwOptionsRestore("w:")
10244"   call Dret("s:NetrwRemoteListing -1")
10245   return -1
10246  endif  " (remote handling sanity check)
10247"  call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
10248
10249  if exists("b:netrw_method")
10250"   call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
10251   let w:netrw_method= b:netrw_method
10252  endif
10253
10254  if s:method == "ftp"
10255   " use ftp to get remote file listing {{{3
10256"   call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
10257   let s:method  = "ftp"
10258   let listcmd = g:netrw_ftp_list_cmd
10259   if g:netrw_sort_by =~# '^t'
10260    let listcmd= g:netrw_ftp_timelist_cmd
10261   elseif g:netrw_sort_by =~# '^s'
10262    let listcmd= g:netrw_ftp_sizelist_cmd
10263   endif
10264"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
10265   call s:NetrwRemoteFtpCmd(s:path,listcmd)
10266"   exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
10267
10268   " report on missing file or directory messages
10269   if search('[Nn]o such file or directory\|Failed to change directory')
10270    let mesg= getline(".")
10271    if exists("w:netrw_bannercnt")
10272     setl ma
10273     exe w:netrw_bannercnt.",$d _"
10274     setl noma
10275    endif
10276    NetrwKeepj call s:NetrwOptionsRestore("w:")
10277    call netrw#ErrorMsg(s:WARNING,mesg,96)
10278"    call Dret("s:NetrwRemoteListing : -1")
10279    return -1
10280   endif
10281
10282   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10283    " shorten the listing
10284"    call Decho("generate short listing",'~'.expand("<slnum>"))
10285    exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
10286
10287    " cleanup
10288    if g:netrw_ftp_browse_reject != ""
10289     exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
10290     NetrwKeepj call histdel("/",-1)
10291    endif
10292    sil! NetrwKeepj %s/\r$//e
10293    NetrwKeepj call histdel("/",-1)
10294
10295    " if there's no ../ listed, then put ../ in
10296    let line1= line(".")
10297    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10298    let line2= search('\.\.\/\%(\s\|$\)','cnW')
10299"    call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2."  w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
10300    if line2 == 0
10301"     call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
10302     sil! NetrwKeepj put='../'
10303    endif
10304    exe "sil! NetrwKeepj ".line1
10305    sil! NetrwKeepj norm! 0
10306
10307"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
10308    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10309"     call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
10310     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
10311     NetrwKeepj call histdel("/",-1)
10312    else " normal ftp cleanup
10313"     call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
10314     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
10315     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
10316     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
10317     NetrwKeepj call histdel("/",-1)
10318     NetrwKeepj call histdel("/",-1)
10319     NetrwKeepj call histdel("/",-1)
10320    endif
10321   endif
10322
10323   else
10324   " use ssh to get remote file listing {{{3
10325"   call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
10326   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
10327"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
10328   if g:netrw_scp_cmd =~ '^pscp'
10329"    call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
10330    exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
10331    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
10332    sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
10333    sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
10334    sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
10335    NetrwKeepj call histdel("/",-1)
10336    NetrwKeepj call histdel("/",-1)
10337    NetrwKeepj call histdel("/",-1)
10338    if g:netrw_liststyle != s:LONGLIST
10339     sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
10340     NetrwKeepj call histdel("/",-1)
10341    endif
10342   else
10343    if s:path == ""
10344"     call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
10345     exe "NetrwKeepj keepalt r! ".listcmd
10346    else
10347"     call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
10348     exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
10349"     call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
10350    endif
10351   endif
10352
10353   " cleanup
10354   if g:netrw_ssh_browse_reject != ""
10355"    call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
10356    exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
10357    NetrwKeepj call histdel("/",-1)
10358   endif
10359  endif
10360
10361  if w:netrw_liststyle == s:LONGLIST
10362   " do a long listing; these substitutions need to be done prior to sorting {{{3
10363"   call Decho("fix long listing:",'~'.expand("<slnum>"))
10364
10365   if s:method == "ftp"
10366    " cleanup
10367    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10368    while getline('.') =~# g:netrw_ftp_browse_reject
10369     sil! NetrwKeepj d
10370    endwhile
10371    " if there's no ../ listed, then put ../ in
10372    let line1= line(".")
10373    sil! NetrwKeepj 1
10374    sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
10375    let line2= line(".")
10376    if line2 == 0
10377     if b:netrw_curdir != '/'
10378      exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
10379     endif
10380    endif
10381    exe "sil! NetrwKeepj ".line1
10382    sil! NetrwKeepj norm! 0
10383   endif
10384
10385   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10386"    call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
10387    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/'
10388   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
10389"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
10390    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
10391    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
10392    exe 'sil NetrwKeepj '.w:netrw_bannercnt
10393    NetrwKeepj call histdel("/",-1)
10394    NetrwKeepj call histdel("/",-1)
10395    NetrwKeepj call histdel("/",-1)
10396   endif
10397  endif
10398
10399"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
10400"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
10401"  endif " Decho
10402
10403"  call Dret("s:NetrwRemoteListing 0")
10404  return 0
10405endfun
10406
10407" ---------------------------------------------------------------------
10408" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
10409fun! s:NetrwRemoteRm(usrhost,path) range
10410"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
10411"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10412  let svpos= winsaveview()
10413"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10414
10415  let all= 0
10416  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10417   " remove all marked files
10418"   call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>"))
10419   for fname in s:netrwmarkfilelist_{bufnr("%")}
10420    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
10421    if ok =~# 'q\%[uit]'
10422     break
10423    elseif ok =~# 'a\%[ll]'
10424     let all= 1
10425    endif
10426   endfor
10427   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10428
10429  else
10430   " remove files specified by range
10431"   call Decho("remove files specified by range",'~'.expand("<slnum>"))
10432
10433   " preparation for removing multiple files/directories
10434   let keepsol = &l:sol
10435   setl nosol
10436   let ctr    = a:firstline
10437
10438   " remove multiple files and directories
10439   while ctr <= a:lastline
10440    exe "NetrwKeepj ".ctr
10441    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
10442    if ok =~# 'q\%[uit]'
10443     break
10444    elseif ok =~# 'a\%[ll]'
10445     let all= 1
10446    endif
10447    let ctr= ctr + 1
10448   endwhile
10449   let &l:sol = keepsol
10450  endif
10451
10452  " refresh the (remote) directory listing
10453"  call Decho("refresh remote directory listing",'~'.expand("<slnum>"))
10454  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10455"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10456  NetrwKeepj call winrestview(svpos)
10457
10458"  call Dret("s:NetrwRemoteRm")
10459endfun
10460
10461" ---------------------------------------------------------------------
10462" s:NetrwRemoteRmFile: {{{2
10463fun! s:NetrwRemoteRmFile(path,rmfile,all)
10464"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
10465
10466  let all= a:all
10467  let ok = ""
10468
10469  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
10470   " attempt to remove file
10471"    call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
10472   if !all
10473    echohl Statement
10474"    call Decho("case all=0:",'~'.expand("<slnum>"))
10475    call inputsave()
10476    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10477    call inputrestore()
10478    echohl NONE
10479    if ok == ""
10480     let ok="no"
10481    endif
10482    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10483    if ok =~# 'a\%[ll]'
10484     let all= 1
10485    endif
10486   endif
10487
10488   if all || ok =~# 'y\%[es]' || ok == ""
10489"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
10490    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10491"     call Decho("case ftp:",'~'.expand("<slnum>"))
10492     let path= a:path
10493     if path =~ '^\a\{3,}://'
10494      let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
10495     endif
10496     sil! NetrwKeepj .,$d _
10497     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
10498    else
10499"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
10500     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
10501"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10502     if !exists("b:netrw_curdir")
10503      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
10504      let ok="q"
10505     else
10506      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
10507"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10508"      call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
10509"      call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
10510      if remotedir != ""
10511       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
10512      else
10513       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
10514      endif
10515"      call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
10516      let ret= system(netrw_rm_cmd)
10517      if v:shell_error != 0
10518       if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
10519	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)
10520       else
10521        call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10522       endif
10523      elseif ret != 0
10524       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10525      endif
10526"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10527     endif
10528    endif
10529   elseif ok =~# 'q\%[uit]'
10530"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10531   endif
10532
10533  else
10534   " attempt to remove directory
10535"    call Decho("attempt to remove directory",'~'.expand("<slnum>"))
10536   if !all
10537    call inputsave()
10538    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10539    call inputrestore()
10540    if ok == ""
10541     let ok="no"
10542    endif
10543    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10544    if ok =~# 'a\%[ll]'
10545     let all= 1
10546    endif
10547   endif
10548
10549   if all || ok =~# 'y\%[es]' || ok == ""
10550    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10551     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
10552    else
10553     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
10554     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
10555"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
10556     let ret= system(netrw_rmdir_cmd)
10557"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10558
10559     if v:shell_error != 0
10560"      call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
10561      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
10562"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
10563      let ret= system(netrw_rmf_cmd)
10564"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10565
10566      if v:shell_error != 0 && !exists("g:netrw_quiet")
10567      	NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
10568      endif
10569     endif
10570    endif
10571
10572   elseif ok =~# 'q\%[uit]'
10573"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10574   endif
10575  endif
10576
10577"  call Dret("s:NetrwRemoteRmFile ".ok)
10578  return ok
10579endfun
10580
10581" ---------------------------------------------------------------------
10582" s:NetrwRemoteRename: rename a remote file or directory {{{2
10583fun! s:NetrwRemoteRename(usrhost,path) range
10584"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
10585
10586  " preparation for removing multiple files/directories
10587  let svpos      = winsaveview()
10588"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10589  let ctr        = a:firstline
10590  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10591
10592  " rename files given by the markfilelist
10593  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10594   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10595"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10596    if exists("subfrom")
10597     let newname= substitute(oldname,subfrom,subto,'')
10598"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10599    else
10600     call inputsave()
10601     let newname= input("Moving ".oldname." to : ",oldname)
10602     call inputrestore()
10603     if newname =~ '^s/'
10604      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10605      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10606      let newname = substitute(oldname,subfrom,subto,'')
10607"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10608     endif
10609    endif
10610
10611    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10612     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10613    else
10614     let oldname= s:ShellEscape(a:path.oldname)
10615     let newname= s:ShellEscape(a:path.newname)
10616"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10617     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10618    endif
10619
10620   endfor
10621   call s:NetrwUnMarkFile(1)
10622
10623  else
10624
10625  " attempt to rename files/directories
10626   let keepsol= &l:sol
10627   setl nosol
10628   while ctr <= a:lastline
10629    exe "NetrwKeepj ".ctr
10630
10631    let oldname= s:NetrwGetWord()
10632"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10633
10634    call inputsave()
10635    let newname= input("Moving ".oldname." to : ",oldname)
10636    call inputrestore()
10637
10638    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10639     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10640    else
10641     let oldname= s:ShellEscape(a:path.oldname)
10642     let newname= s:ShellEscape(a:path.newname)
10643"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10644     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10645    endif
10646
10647    let ctr= ctr + 1
10648   endwhile
10649   let &l:sol= keepsol
10650  endif
10651
10652  " refresh the directory
10653  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10654"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10655  NetrwKeepj call winrestview(svpos)
10656
10657"  call Dret("NetrwRemoteRename")
10658endfun
10659
10660" ==========================================
10661"  Local Directory Browsing Support:    {{{1
10662" ==========================================
10663
10664" ---------------------------------------------------------------------
10665" netrw#FileUrlEdit: handles editing file://* files {{{2
10666"   Should accept:   file://localhost/etc/fstab
10667"                    file:///etc/fstab
10668"                    file:///c:/WINDOWS/clock.avi
10669"                    file:///c|/WINDOWS/clock.avi
10670"                    file://localhost/c:/WINDOWS/clock.avi
10671"                    file://localhost/c|/WINDOWS/clock.avi
10672"                    file://c:/foo.txt
10673"                    file:///c:/foo.txt
10674" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
10675fun! netrw#FileUrlEdit(fname)
10676"  call Dfunc("netrw#FileUrlEdit(fname<".a:fname.">)")
10677  let fname = a:fname
10678  if fname =~ '^file://localhost/'
10679"   call Decho('converting file://localhost/   -to-  file:///','~'.expand("<slnum>"))
10680   let fname= substitute(fname,'^file://localhost/','file:///','')
10681"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10682  endif
10683  if (has("win32") || has("win95") || has("win64") || has("win16"))
10684   if fname  =~ '^file:///\=\a[|:]/'
10685"    call Decho('converting file:///\a|/   -to-  file://\a:/','~'.expand("<slnum>"))
10686    let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10687"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10688   endif
10689  endif
10690  let fname2396 = netrw#RFC2396(fname)
10691  let fname2396e= fnameescape(fname2396)
10692  let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
10693  if (has("win32") || has("win95") || has("win64") || has("win16"))
10694"   call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10695   if plainfname =~ '^/\+\a:'
10696"    call Decho('removing leading "/"s','~'.expand("<slnum>"))
10697    let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10698   endif
10699  endif
10700
10701"  call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10702"  call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
10703  exe "sil doau BufReadPre ".fname2396e
10704  exe 'NetrwKeepj keepalt edit '.plainfname
10705  exe 'sil! NetrwKeepj keepalt bdelete '.fnameescape(a:fname)
10706
10707"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10708"  call Dret("netrw#FileUrlEdit")
10709  exe "sil doau BufReadPost ".fname2396e
10710endfun
10711
10712" ---------------------------------------------------------------------
10713" netrw#LocalBrowseCheck: {{{2
10714fun! netrw#LocalBrowseCheck(dirname)
10715  " This function is called by netrwPlugin.vim's s:LocalBrowseCheck(), s:NetrwRexplore(),
10716  " and by <cr> when atop a listed file/directory (via a buffer-local map)
10717  "
10718  " unfortunate interaction -- split window debugging can't be used here, must use
10719  "                            D-echoRemOn or D-echoTabOn as the BufEnter event triggers
10720  "                            another call to LocalBrowseCheck() when attempts to write
10721  "                            to the DBG buffer are made.
10722  "
10723  " The &ft == "netrw" test was installed because the BufEnter event
10724  " would hit when re-entering netrw windows, creating unexpected
10725  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
10726"  call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">)")
10727"  call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>"))
10728"  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>"))
10729"  call Dredir("ls!","netrw#LocalBrowseCheck")
10730"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10731"  call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
10732
10733  let ykeep= @@
10734  if isdirectory(s:NetrwFile(a:dirname))
10735"   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>"))
10736
10737   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10738"    call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10739"    call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10740    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10741
10742   elseif &ft == "netrw" && line("$") == 1
10743"    call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10744    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10745
10746   elseif exists("s:treeforceredraw")
10747"    call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10748    unlet s:treeforceredraw
10749    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10750   endif
10751"   call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10752"   call Dret("netrw#LocalBrowseCheck")
10753   return
10754  endif
10755
10756  " The following code wipes out currently unused netrw buffers
10757  "       IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10758  "   AND IF the listing style is not a tree listing
10759  if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
10760"   call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10761   let ibuf    = 1
10762   let buflast = bufnr("$")
10763   while ibuf <= buflast
10764    if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10765     exe "sil! keepj keepalt ".ibuf."bw!"
10766    endif
10767    let ibuf= ibuf + 1
10768   endwhile
10769  endif
10770  let @@= ykeep
10771"  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>"))
10772"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10773  " not a directory, ignore it
10774"  call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
10775endfun
10776
10777" ---------------------------------------------------------------------
10778" s:LocalBrowseRefresh: this function is called after a user has {{{2
10779" performed any shell command.  The idea is to cause all local-browsing
10780" buffers to be refreshed after a user has executed some shell command,
10781" on the chance that s/he removed/created a file/directory with it.
10782fun! s:LocalBrowseRefresh()
10783"  call Dfunc("s:LocalBrowseRefresh() tabpagenr($)=".tabpagenr("$"))
10784"  call Decho("s:netrw_browselist =".(exists("s:netrw_browselist")?  string(s:netrw_browselist)  : '<n/a>'),'~'.expand("<slnum>"))
10785"  call Decho("w:netrw_bannercnt  =".(exists("w:netrw_bannercnt")?   string(w:netrw_bannercnt)   : '<n/a>'),'~'.expand("<slnum>"))
10786
10787  " determine which buffers currently reside in a tab
10788  if !exists("s:netrw_browselist")
10789"   call Dret("s:LocalBrowseRefresh : browselist is empty")
10790   return
10791  endif
10792  if !exists("w:netrw_bannercnt")
10793"   call Dret("s:LocalBrowseRefresh : don't refresh when focus not on netrw window")
10794   return
10795  endif
10796  if exists("s:netrw_events") && s:netrw_events == 1
10797   " s:LocalFastBrowser gets called (indirectly) from a
10798   let s:netrw_events= 2
10799"   call Dret("s:LocalBrowseRefresh : avoid initial double refresh")
10800   return
10801  endif
10802  let itab       = 1
10803  let buftablist = []
10804  let ykeep      = @@
10805  while itab <= tabpagenr("$")
10806   let buftablist = buftablist + tabpagebuflist()
10807   let itab       = itab + 1
10808   sil! tabn
10809  endwhile
10810"  call Decho("buftablist".string(buftablist),'~'.expand("<slnum>"))
10811"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("<slnum>"))
10812  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10813  "   | refresh any netrw window
10814  "   | wipe out any non-displaying netrw buffer
10815  let curwinid = win_getid(winnr())
10816  let ibl    = 0
10817  for ibuf in s:netrw_browselist
10818"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("<slnum>"))
10819   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10820    " wipe out any non-displaying netrw buffer
10821    " (ibuf not shown in a current window AND
10822    "  ibuf not in any tab)
10823"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("<slnum>"))
10824    exe "sil! keepj bd ".fnameescape(ibuf)
10825    call remove(s:netrw_browselist,ibl)
10826"    call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10827    continue
10828   elseif index(tabpagebuflist(),ibuf) != -1
10829    " refresh any netrw buffer
10830"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>"))
10831    exe bufwinnr(ibuf)."wincmd w"
10832    if getline(".") =~# 'Quick Help'
10833     " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10834     " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10835     let g:netrw_quickhelp= g:netrw_quickhelp - 1
10836    endif
10837"    call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>"))
10838    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10839     NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10840    endif
10841    NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10842   endif
10843   let ibl= ibl + 1
10844"   call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("<slnum>"))
10845  endfor
10846"  call Decho("restore window: win_gotoid(".curwinid.")")
10847  call win_gotoid(curwinid)
10848  let @@= ykeep
10849
10850"  call Dret("s:LocalBrowseRefresh")
10851endfun
10852
10853" ---------------------------------------------------------------------
10854" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10855"
10856"     g:netrw_    Directory Is
10857"     fastbrowse  Local  Remote
10858"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
10859"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
10860"  fast   2         H      H
10861"
10862"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10863"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
10864"                       (re-using a buffer may not be as accurate)
10865"
10866"  s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds with medium-speed or fast browsing
10867"                   =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10868"                       BufEnter may be first event, then a FocusGained event.  Ignore the first FocusGained event.
10869"                       If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10870"                   =2: autocmds installed (doesn't ignore any FocusGained events)
10871fun! s:LocalFastBrowser()
10872"  call Dfunc("s:LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
10873"  call Decho("s:netrw_events        ".(exists("s:netrw_events")? "exists"            : 'n/a'),'~'.expand("<slnum>"))
10874"  call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")?  "already installed" : "not installed"),'~'.expand("<slnum>"))
10875"  call Decho("autocmd: FocusGained  ".(exists("#FocusGained")?   "already installed" : "not installed"),'~'.expand("<slnum>"))
10876
10877  " initialize browselist, a list of buffer numbers that the local browser has used
10878  if !exists("s:netrw_browselist")
10879"   call Decho("initialize s:netrw_browselist",'~'.expand("<slnum>"))
10880   let s:netrw_browselist= []
10881  endif
10882
10883  " append current buffer to fastbrowse list
10884  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
10885"   call Decho("appendng current buffer to browselist",'~'.expand("<slnum>"))
10886   call add(s:netrw_browselist,bufnr("%"))
10887"   call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10888  endif
10889
10890  " enable autocmd events to handle refreshing/removing local browser buffers
10891  "    If local browse buffer is currently showing: refresh it
10892  "    If local browse buffer is currently hidden : wipe it
10893  "    g:netrw_fastbrowse=0 : slow   speed, never re-use directory listing
10894  "                      =1 : medium speed, re-use directory listing for remote only
10895  "                      =2 : fast   speed, always re-use directory listing when possible
10896  if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
10897   let s:netrw_events= 1
10898   augroup AuNetrwEvent
10899    au!
10900    if (has("win32") || has("win95") || has("win64") || has("win16"))
10901"     call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
10902     au ShellCmdPost			*	call s:LocalBrowseRefresh()
10903    else
10904"     call Decho("installing autocmds: ShellCmdPost FocusGained",'~'.expand("<slnum>"))
10905     au ShellCmdPost,FocusGained	*	call s:LocalBrowseRefresh()
10906    endif
10907   augroup END
10908
10909  " user must have changed fastbrowse to its fast setting, so remove
10910  " the associated autocmd events
10911  elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
10912"   call Decho("remove AuNetrwEvent autcmd group",'~'.expand("<slnum>"))
10913   unlet s:netrw_events
10914   augroup AuNetrwEvent
10915    au!
10916   augroup END
10917   augroup! AuNetrwEvent
10918  endif
10919
10920"  call Dret("s:LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
10921endfun
10922
10923" ---------------------------------------------------------------------
10924"  s:LocalListing: does the job of "ls" for local directories {{{2
10925fun! s:LocalListing()
10926"  call Dfunc("s:LocalListing()")
10927"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10928"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
10929"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10930
10931"  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
10932"  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
10933"  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>"))
10934
10935  " get the list of files contained in the current directory
10936  let dirname    = b:netrw_curdir
10937  let dirnamelen = strlen(b:netrw_curdir)
10938  let filelist   = s:NetrwGlob(dirname,"*",0)
10939  let filelist   = filelist + s:NetrwGlob(dirname,".*",0)
10940"  call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10941
10942  if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
10943"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10944  elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
10945    " include ../ in the glob() entry if its missing
10946"   call Decho("forcibly including on \"..\"",'~'.expand("<slnum>"))
10947   let filelist= filelist+[s:ComposePath(b:netrw_curdir,"../")]
10948"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10949  endif
10950
10951"  call Decho("before while: dirname   <".dirname.">",'~'.expand("<slnum>"))
10952"  call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>"))
10953"  call Decho("before while: filelist  =".string(filelist),'~'.expand("<slnum>"))
10954
10955  if get(g:, 'netrw_dynamic_maxfilenamelen', 0)
10956   let filelistcopy           = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10957   let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
10958"   call Decho("dynamic_maxfilenamelen: filenames             =".string(filelistcopy),'~'.expand("<slnum>"))
10959"   call Decho("dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen,'~'.expand("<slnum>"))
10960  endif
10961"  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>"))
10962
10963  for filename in filelist
10964"   call Decho(" ",'~'.expand("<slnum>"))
10965"   call Decho("for filename in filelist: filename<".filename.">",'~'.expand("<slnum>"))
10966
10967   if getftype(filename) == "link"
10968    " indicate a symbolic link
10969"    call Decho("indicate <".filename."> is a symbolic link with trailing @",'~'.expand("<slnum>"))
10970    let pfile= filename."@"
10971
10972   elseif getftype(filename) == "socket"
10973    " indicate a socket
10974"    call Decho("indicate <".filename."> is a socket with trailing =",'~'.expand("<slnum>"))
10975    let pfile= filename."="
10976
10977   elseif getftype(filename) == "fifo"
10978    " indicate a fifo
10979"    call Decho("indicate <".filename."> is a fifo with trailing |",'~'.expand("<slnum>"))
10980    let pfile= filename."|"
10981
10982   elseif isdirectory(s:NetrwFile(filename))
10983    " indicate a directory
10984"    call Decho("indicate <".filename."> is a directory with trailing /",'~'.expand("<slnum>"))
10985    let pfile= filename."/"
10986
10987   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10988    if (has("win32") || has("win95") || has("win64") || has("win16"))
10989     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10990      " indicate an executable
10991"      call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10992      let pfile= filename."*"
10993     else
10994      " normal file
10995      let pfile= filename
10996     endif
10997    elseif executable(filename)
10998     " indicate an executable
10999"     call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
11000     let pfile= filename."*"
11001    else
11002     " normal file
11003     let pfile= filename
11004    endif
11005
11006   else
11007    " normal file
11008    let pfile= filename
11009   endif
11010"   call Decho("pfile<".pfile."> (after *@/ appending)",'~'.expand("<slnum>"))
11011
11012   if pfile =~ '//$'
11013    let pfile= substitute(pfile,'//$','/','e')
11014"    call Decho("change // to /: pfile<".pfile.">",'~'.expand("<slnum>"))
11015   endif
11016   let pfile= strpart(pfile,dirnamelen)
11017   let pfile= substitute(pfile,'^[/\\]','','e')
11018"   call Decho("filename<".filename.">",'~'.expand("<slnum>"))
11019"   call Decho("pfile   <".pfile.">",'~'.expand("<slnum>"))
11020
11021   if w:netrw_liststyle == s:LONGLIST
11022    let sz   = getfsize(filename)
11023    let fsz  = strpart("               ",1,15-strlen(sz)).sz
11024    if g:netrw_sizestyle =~# "[hH]"
11025     let sz= s:NetrwHumanReadable(sz)
11026    endif
11027    let longfile= printf("%-".(g:netrw_maxfilenamelen+1)."s",pfile)
11028    let pfile   = longfile.sz." ".strftime(g:netrw_timefmt,getftime(filename))
11029"    call Decho("longlist support: sz=".sz." fsz=".fsz,'~'.expand("<slnum>"))
11030   endif
11031
11032   if     g:netrw_sort_by =~# "^t"
11033    " sort by time (handles time up to 1 quintillion seconds, US)
11034    " Decorate listing by prepending a timestamp/  .  Sorting will then be done based on time.
11035"    call Decho("implementing g:netrw_sort_by=".g:netrw_sort_by." (time)")
11036"    call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>"))
11037    let t  = getftime(filename)
11038    let ft = strpart("000000000000000000",1,18-strlen(t)).t
11039"    call Decho("exe NetrwKeepj put ='".ft.'/'.pfile."'",'~'.expand("<slnum>"))
11040    let ftpfile= ft.'/'.pfile
11041    sil! NetrwKeepj put=ftpfile
11042
11043   elseif g:netrw_sort_by =~ "^s"
11044    " sort by size (handles file sizes up to 1 quintillion bytes, US)
11045"    call Decho("implementing g:netrw_sort_by=".g:netrw_sort_by." (size)")
11046"    call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>"))
11047    let sz   = getfsize(filename)
11048    if g:netrw_sizestyle =~# "[hH]"
11049     let sz= s:NetrwHumanReadable(sz)
11050    endif
11051    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
11052"    call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>"))
11053    let fszpfile= fsz.'/'.pfile
11054    sil! NetrwKeepj put =fszpfile
11055
11056   else
11057    " sort by name
11058"    call Decho("implementing g:netrw_sort_by=".g:netrw_sort_by." (name)")
11059"    call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("<slnum>"))
11060    sil! NetrwKeepj put=pfile
11061   endif
11062"   call DechoBuf(bufnr("%"),"bufnr(%)")
11063  endfor
11064
11065  " cleanup any windows mess at end-of-line
11066  sil! NetrwKeepj g/^$/d
11067  sil! NetrwKeepj %s/\r$//e
11068  call histdel("/",-1)
11069"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
11070  exe "setl ts=".(g:netrw_maxfilenamelen+1)
11071
11072"  call Dret("s:LocalListing")
11073endfun
11074
11075" ---------------------------------------------------------------------
11076" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
11077fun! s:NetrwLocalExecute(cmd)
11078"  call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
11079  let ykeep= @@
11080  " sanity check
11081  if !executable(a:cmd)
11082   call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
11083   let @@= ykeep
11084"   call Dret("s:NetrwLocalExecute")
11085   return
11086  endif
11087
11088  let optargs= input(":!".a:cmd,"","file")
11089"  call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
11090  let result= system(a:cmd.optargs)
11091"  call Decho("result,'~'.expand("<slnum>"))
11092
11093  " strip any ansi escape sequences off
11094  let result = substitute(result,"\e\\[[0-9;]*m","","g")
11095
11096  " show user the result(s)
11097  echomsg result
11098  let @@= ykeep
11099
11100"  call Dret("s:NetrwLocalExecute")
11101endfun
11102
11103" ---------------------------------------------------------------------
11104" s:NetrwLocalRename: rename a local file or directory {{{2
11105fun! s:NetrwLocalRename(path) range
11106"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
11107
11108  " preparation for removing multiple files/directories
11109  let ykeep     = @@
11110  let ctr       = a:firstline
11111  let svpos     = winsaveview()
11112  let all       = 0
11113"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11114
11115  " rename files given by the markfilelist
11116  if exists("s:netrwmarkfilelist_{bufnr('%')}")
11117   for oldname in s:netrwmarkfilelist_{bufnr("%")}
11118"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
11119    if exists("subfrom")
11120     let newname= substitute(oldname,subfrom,subto,'')
11121"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
11122    else
11123     call inputsave()
11124     let newname= input("Moving ".oldname." to : ",oldname,"file")
11125     call inputrestore()
11126     if newname =~ ''
11127      " two ctrl-x's : ignore all of string preceding the ctrl-x's
11128      let newname = substitute(newname,'^.*','','')
11129     elseif newname =~ ''
11130      " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
11131      let newname = substitute(newname,'[^/]*','','')
11132     endif
11133     if newname =~ '^s/'
11134      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
11135      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
11136"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
11137      let newname = substitute(oldname,subfrom,subto,'')
11138     endif
11139    endif
11140    if !all && filereadable(newname)
11141     call inputsave()
11142      let response= input("File<".newname."> already exists; do you want to overwrite it? (y/all/n) ")
11143     call inputrestore()
11144     if response == "all"
11145      let all= 1
11146     elseif response != "y" && response != "yes"
11147      " refresh the directory
11148"      call Decho("refresh the directory listing",'~'.expand("<slnum>"))
11149      NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11150"      call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11151      NetrwKeepj call winrestview(svpos)
11152      let @@= ykeep
11153"      call Dret("NetrwLocalRename")
11154      return
11155     endif
11156    endif
11157    call rename(oldname,newname)
11158   endfor
11159   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
11160
11161  else
11162
11163   " attempt to rename files/directories
11164   while ctr <= a:lastline
11165    exe "NetrwKeepj ".ctr
11166
11167    " sanity checks
11168    if line(".") < w:netrw_bannercnt
11169     let ctr= ctr + 1
11170     continue
11171    endif
11172    let curword= s:NetrwGetWord()
11173    if curword == "./" || curword == "../"
11174     let ctr= ctr + 1
11175     continue
11176    endif
11177
11178    NetrwKeepj norm! 0
11179    let oldname= s:ComposePath(a:path,curword)
11180"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
11181
11182    call inputsave()
11183    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
11184    call inputrestore()
11185
11186    call rename(oldname,newname)
11187"    call Decho("renaming <".oldname."> to <".newname.">",'~'.expand("<slnum>"))
11188
11189    let ctr= ctr + 1
11190   endwhile
11191  endif
11192
11193  " refresh the directory
11194"  call Decho("refresh the directory listing",'~'.expand("<slnum>"))
11195  NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11196"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11197  NetrwKeepj call winrestview(svpos)
11198  let @@= ykeep
11199
11200"  call Dret("NetrwLocalRename")
11201endfun
11202
11203" ---------------------------------------------------------------------
11204" s:NetrwLocalRm: {{{2
11205fun! s:NetrwLocalRm(path) range
11206"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
11207"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
11208
11209  " preparation for removing multiple files/directories
11210  let ykeep = @@
11211  let ret   = 0
11212  let all   = 0
11213  let svpos = winsaveview()
11214"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11215
11216  if exists("s:netrwmarkfilelist_{bufnr('%')}")
11217   " remove all marked files
11218"   call Decho("remove all marked files",'~'.expand("<slnum>"))
11219   for fname in s:netrwmarkfilelist_{bufnr("%")}
11220    let ok= s:NetrwLocalRmFile(a:path,fname,all)
11221    if ok =~# 'q\%[uit]' || ok == "no"
11222     break
11223    elseif ok =~# 'a\%[ll]'
11224     let all= 1
11225    endif
11226   endfor
11227   call s:NetrwUnMarkFile(1)
11228
11229  else
11230  " remove (multiple) files and directories
11231"   call Decho("remove files in range [".a:firstline.",".a:lastline."]",'~'.expand("<slnum>"))
11232
11233   let keepsol= &l:sol
11234   setl nosol
11235   let ctr = a:firstline
11236   while ctr <= a:lastline
11237    exe "NetrwKeepj ".ctr
11238
11239    " sanity checks
11240    if line(".") < w:netrw_bannercnt
11241     let ctr= ctr + 1
11242     continue
11243    endif
11244    let curword= s:NetrwGetWord()
11245    if curword == "./" || curword == "../"
11246     let ctr= ctr + 1
11247     continue
11248    endif
11249    let ok= s:NetrwLocalRmFile(a:path,curword,all)
11250    if ok =~# 'q\%[uit]' || ok == "no"
11251     break
11252    elseif ok =~# 'a\%[ll]'
11253     let all= 1
11254    endif
11255    let ctr= ctr + 1
11256   endwhile
11257   let &l:sol= keepsol
11258  endif
11259
11260  " refresh the directory
11261"  call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>"))
11262  if bufname("%") != "NetrwMessage"
11263   NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11264"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11265   NetrwKeepj call winrestview(svpos)
11266  endif
11267  let @@= ykeep
11268
11269"  call Dret("s:NetrwLocalRm")
11270endfun
11271
11272" ---------------------------------------------------------------------
11273" s:NetrwLocalRmFile: remove file fname given the path {{{2
11274"                     Give confirmation prompt unless all==1
11275fun! s:NetrwLocalRmFile(path,fname,all)
11276"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
11277
11278  let all= a:all
11279  let ok = ""
11280  NetrwKeepj norm! 0
11281  let rmfile= s:NetrwFile(s:ComposePath(a:path,a:fname))
11282"  call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
11283
11284  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
11285   " attempt to remove file
11286"   call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
11287   if !all
11288    echohl Statement
11289    call inputsave()
11290    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11291    call inputrestore()
11292    echohl NONE
11293    if ok == ""
11294     let ok="no"
11295    endif
11296"    call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
11297    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11298"    call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
11299    if ok =~# 'a\%[ll]'
11300     let all= 1
11301    endif
11302   endif
11303
11304   if all || ok =~# 'y\%[es]' || ok == ""
11305    let ret= s:NetrwDelete(rmfile)
11306"    call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
11307   endif
11308
11309  else
11310   " attempt to remove directory
11311   if !all
11312    echohl Statement
11313    call inputsave()
11314    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11315    call inputrestore()
11316    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11317    if ok == ""
11318     let ok="no"
11319    endif
11320    if ok =~# 'a\%[ll]'
11321     let all= 1
11322    endif
11323   endif
11324   let rmfile= substitute(rmfile,'[\/]$','','e')
11325
11326   if all || ok =~# 'y\%[es]' || ok == ""
11327    if v:version < 704 || (v:version == 704 && !has("patch1107"))
11328" "    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>"))
11329     call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile))
11330" "    call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>"))
11331
11332     if v:shell_error != 0
11333" "     call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11334      let errcode= s:NetrwDelete(rmfile)
11335" "     call Decho("errcode=".errcode,'~'.expand("<slnum>"))
11336
11337      if errcode != 0
11338       if has("unix")
11339" "       call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11340	call system("rm ".s:ShellEscape(rmfile))
11341	if v:shell_error != 0 && !exists("g:netrw_quiet")
11342	 call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
11343	 let ok="no"
11344	endif
11345       elseif !exists("g:netrw_quiet")
11346	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
11347	let ok="no"
11348       endif
11349      endif
11350     endif
11351    else
11352     if delete(rmfile,"d")
11353      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
11354     endif
11355    endif
11356   endif
11357  endif
11358
11359"  call Dret("s:NetrwLocalRmFile ".ok)
11360  return ok
11361endfun
11362
11363" =====================================================================
11364" Support Functions: {{{1
11365
11366" ---------------------------------------------------------------------
11367" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
11368"   0: marked file list of current buffer
11369"   1: marked file target
11370fun! netrw#Access(ilist)
11371  if     a:ilist == 0
11372   if exists("s:netrwmarkfilelist_".bufnr('%'))
11373    return s:netrwmarkfilelist_{bufnr('%')}
11374   else
11375    return "no-list-buf#".bufnr('%')
11376   endif
11377  elseif a:ilist == 1
11378   return s:netrwmftgt
11379  endif
11380endfun
11381
11382" ---------------------------------------------------------------------
11383" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
11384fun! netrw#Call(funcname,...)
11385  return call("s:".a:funcname,a:000)
11386endfun
11387
11388" ---------------------------------------------------------------------
11389" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
11390"               I expect this function to be used in
11391"                 :PChkAssert netrw#Expose("netrwmarkfilelist")
11392"               for example.
11393fun! netrw#Expose(varname)
11394"   call Dfunc("netrw#Expose(varname<".a:varname.">)")
11395  if exists("s:".a:varname)
11396   exe "let retval= s:".a:varname
11397"   call Decho("retval=".retval,'~'.expand("<slnum>"))
11398   if exists("g:netrw_pchk")
11399"    call Decho("type(g:netrw_pchk=".g:netrw_pchk.")=".type(retval),'~'.expand("<slnum>"))
11400    if type(retval) == 3
11401     let retval = copy(retval)
11402     let i      = 0
11403     while i < len(retval)
11404      let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
11405      let i        = i + 1
11406     endwhile
11407    endif
11408"     call Dret("netrw#Expose ".string(retval)),'~'.expand("<slnum>"))
11409    return string(retval)
11410   else
11411"    call Decho("g:netrw_pchk doesn't exist",'~'.expand("<slnum>"))
11412   endif
11413  else
11414"   call Decho("s:".a:varname." doesn't exist",'~'.expand("<slnum>"))
11415   let retval= "n/a"
11416  endif
11417
11418"  call Dret("netrw#Expose ".string(retval))
11419  return retval
11420endfun
11421
11422" ---------------------------------------------------------------------
11423" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
11424fun! netrw#Modify(varname,newvalue)
11425"  call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
11426  exe "let s:".a:varname."= ".string(a:newvalue)
11427"  call Dret("netrw#Modify")
11428endfun
11429
11430" ---------------------------------------------------------------------
11431"  netrw#RFC2396: converts %xx into characters {{{2
11432fun! netrw#RFC2396(fname)
11433"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
11434  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
11435"  call Dret("netrw#RFC2396 ".fname)
11436  return fname
11437endfun
11438
11439" ---------------------------------------------------------------------
11440" netrw#UserMaps: supports user-specified maps {{{2
11441"                 see :help function()
11442"
11443"                 g:Netrw_UserMaps is a List with members such as:
11444"                       [[keymap sequence, function reference],...]
11445"
11446"                 The referenced function may return a string,
11447"                 	refresh : refresh the display
11448"                 	-other- : this string will be executed
11449"                 or it may return a List of strings.
11450"
11451"                 Each keymap-sequence will be set up with a nnoremap
11452"                 to invoke netrw#UserMaps(a:islocal).
11453"                 Related functions:
11454"                   netrw#Expose(varname)          -- see s:varname variables
11455"                   netrw#Modify(varname,newvalue) -- modify value of s:varname variable
11456"                   netrw#Call(funcname,...)       -- call internal netrw function with optional arguments
11457fun! netrw#UserMaps(islocal)
11458"  call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
11459"  call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
11460
11461   " set up usermaplist
11462   if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
11463"    call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
11464    for umap in g:Netrw_UserMaps
11465"     call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
11466"     call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
11467     " if umap[0] is a string and umap[1] is a string holding a function name
11468     if type(umap[0]) == 1 && type(umap[1]) == 1
11469"      call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
11470      exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
11471      else
11472       call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
11473     endif
11474    endfor
11475   endif
11476"  call Dret("netrw#UserMaps")
11477endfun
11478
11479" ---------------------------------------------------------------------
11480" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
11481fun! netrw#WinPath(path)
11482"  call Dfunc("netrw#WinPath(path<".a:path.">)")
11483  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
11484   " remove cygdrive prefix, if present
11485   let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
11486   " remove trailing slash (Win95)
11487   let path = substitute(path, '\(\\\|/\)$', '', 'g')
11488   " remove escaped spaces
11489   let path = substitute(path, '\ ', ' ', 'g')
11490   " convert slashes to backslashes
11491   let path = substitute(path, '/', '\', 'g')
11492  else
11493   let path= a:path
11494  endif
11495"  call Dret("netrw#WinPath <".path.">")
11496  return path
11497endfun
11498
11499" ---------------------------------------------------------------------
11500" s:NetrwBadd: adds marked files to buffer list or vice versa {{{2
11501"              cb : bl2mf=0  add marked files to buffer list
11502"              cB : bl2mf=1  use bufferlist to mark files
11503"              (mnemonic: cb = copy (marked files) to buffer list)
11504fun! s:NetrwBadd(islocal,bl2mf)
11505"  "  call Dfunc("s:NetrwBadd(islocal=".a:islocal." mf2bl=".mf2bl.")")
11506  if a:bl2mf
11507   " cB: add buffer list to marked files
11508   redir => bufl
11509    ls
11510   redir END
11511   let bufl = map(split(bufl,"\n"),'substitute(v:val,''^.\{-}"\(.*\)".\{-}$'',''\1'','''')')
11512   for fname in bufl
11513    call s:NetrwMarkFile(a:islocal,fname)
11514   endfor
11515  else
11516   " cb: add marked files to buffer list
11517   for fname in s:netrwmarkfilelist_{bufnr("%")}
11518" "   call Decho("badd ".fname,'~'.expand("<slnum>"))
11519    exe "badd ".fnameescape(fname)
11520   endfor
11521   let curbufnr = bufnr("%")
11522   let curdir   = s:NetrwGetCurdir(a:islocal)
11523   call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
11524  endif
11525"  call Dret("s:NetrwBadd")
11526endfun
11527
11528" ---------------------------------------------------------------------
11529"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
11530fun! s:ComposePath(base,subdir)
11531"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
11532
11533  if has("amiga")
11534"   call Decho("amiga",'~'.expand("<slnum>"))
11535   let ec = a:base[s:Strlen(a:base)-1]
11536   if ec != '/' && ec != ':'
11537    let ret = a:base."/" . a:subdir
11538   else
11539    let ret = a:base.a:subdir
11540   endif
11541
11542   " COMBAK: test on windows with changing to root directory: :e C:/
11543  elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11544"   call Decho("windows",'~'.expand("<slnum>"))
11545   let ret= a:subdir
11546
11547  elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11548"   call Decho("windows",'~'.expand("<slnum>"))
11549   if a:base =~ '[/\\]$'
11550    let ret= a:base.a:subdir
11551   else
11552    let ret= a:base.'/'.a:subdir
11553   endif
11554
11555  elseif a:base =~ '^\a\{3,}://'
11556"   call Decho("remote linux/macos",'~'.expand("<slnum>"))
11557   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
11558   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
11559   if a:subdir == '../'
11560    if curpath =~ '[^/]/[^/]\+/$'
11561     let curpath= substitute(curpath,'[^/]\+/$','','')
11562    else
11563     let curpath=""
11564    endif
11565    let ret= urlbase.curpath
11566   else
11567    let ret= urlbase.curpath.a:subdir
11568   endif
11569"   call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
11570"   call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
11571"   call Decho("ret<".ret.">",'~'.expand("<slnum>"))
11572
11573  else
11574"   call Decho("local linux/macos",'~'.expand("<slnum>"))
11575   let ret = substitute(a:base."/".a:subdir,"//","/","g")
11576   if a:base =~ '^//'
11577    " keeping initial '//' for the benefit of network share listing support
11578    let ret= '/'.ret
11579   endif
11580   let ret= simplify(ret)
11581  endif
11582
11583"  call Dret("s:ComposePath ".ret)
11584  return ret
11585endfun
11586
11587" ---------------------------------------------------------------------
11588" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
11589"   Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
11590fun! s:DeleteBookmark(fname)
11591"  call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
11592  call s:MergeBookmarks()
11593
11594  if exists("g:netrw_bookmarklist")
11595   let indx= index(g:netrw_bookmarklist,a:fname)
11596   if indx == -1
11597    let indx= 0
11598    while indx < len(g:netrw_bookmarklist)
11599     if g:netrw_bookmarklist[indx] =~ a:fname
11600      call remove(g:netrw_bookmarklist,indx)
11601      let indx= indx - 1
11602     endif
11603     let indx= indx + 1
11604    endwhile
11605   else
11606    " remove exact match
11607    call remove(g:netrw_bookmarklist,indx)
11608   endif
11609  endif
11610
11611"  call Dret("s:DeleteBookmark")
11612endfun
11613
11614" ---------------------------------------------------------------------
11615" s:FileReadable: o/s independent filereadable {{{2
11616fun! s:FileReadable(fname)
11617"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
11618
11619  if g:netrw_cygwin
11620   let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
11621  else
11622   let ret= filereadable(s:NetrwFile(a:fname))
11623  endif
11624
11625"  call Dret("s:FileReadable ".ret)
11626  return ret
11627endfun
11628
11629" ---------------------------------------------------------------------
11630"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
11631"                 Places correct suffix on end of temporary filename,
11632"                 using the suffix provided with fname
11633fun! s:GetTempfile(fname)
11634"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
11635
11636  if !exists("b:netrw_tmpfile")
11637   " get a brand new temporary filename
11638   let tmpfile= tempname()
11639"   call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
11640
11641   let tmpfile= substitute(tmpfile,'\','/','ge')
11642"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
11643
11644   " sanity check -- does the temporary file's directory exist?
11645   if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
11646"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11647    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
11648"    call Dret("s:GetTempfile getcwd<".getcwd().">")
11649    return ""
11650   endif
11651
11652   " let netrw#NetSource() know about the tmpfile
11653   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
11654"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
11655
11656   " o/s dependencies
11657   if g:netrw_cygwin != 0
11658    let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
11659   elseif has("win32") || has("win95") || has("win64") || has("win16")
11660    if !exists("+shellslash") || !&ssl
11661     let tmpfile = substitute(tmpfile,'/','\','g')
11662    endif
11663   else
11664    let tmpfile = tmpfile
11665   endif
11666   let b:netrw_tmpfile= tmpfile
11667"   call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
11668  else
11669   " re-use temporary filename
11670   let tmpfile= b:netrw_tmpfile
11671"   call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
11672  endif
11673
11674  " use fname's suffix for the temporary file
11675  if a:fname != ""
11676   if a:fname =~ '\.[^./]\+$'
11677"    call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11678    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11679     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11680    elseif a:fname =~ '.txz$'
11681     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11682    else
11683     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11684    endif
11685"    call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11686    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11687"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11688    let tmpfile .= suffix
11689"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11690    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
11691   endif
11692  endif
11693
11694"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11695"  call Dret("s:GetTempfile <".tmpfile.">")
11696  return tmpfile
11697endfun
11698
11699" ---------------------------------------------------------------------
11700" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
11701"               a correct command for use with a system() call
11702fun! s:MakeSshCmd(sshcmd)
11703"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
11704  if s:user == ""
11705   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
11706  else
11707   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
11708  endif
11709  if exists("g:netrw_port") && g:netrw_port != ""
11710   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
11711  elseif exists("s:port") && s:port != ""
11712   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
11713  else
11714   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
11715  endif
11716"  call Dret("s:MakeSshCmd <".sshcmd.">")
11717  return sshcmd
11718endfun
11719
11720" ---------------------------------------------------------------------
11721" s:MakeBookmark: enters a bookmark into Netrw's bookmark system   {{{2
11722fun! s:MakeBookmark(fname)
11723"  call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
11724
11725  if !exists("g:netrw_bookmarklist")
11726   let g:netrw_bookmarklist= []
11727  endif
11728
11729  if index(g:netrw_bookmarklist,a:fname) == -1
11730   " curdir not currently in g:netrw_bookmarklist, so include it
11731   if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11732    call add(g:netrw_bookmarklist,a:fname.'/')
11733   elseif a:fname !~ '/'
11734    call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11735   else
11736    call add(g:netrw_bookmarklist,a:fname)
11737   endif
11738   call sort(g:netrw_bookmarklist)
11739  endif
11740
11741"  call Dret("s:MakeBookmark")
11742endfun
11743
11744" ---------------------------------------------------------------------
11745" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11746fun! s:MergeBookmarks()
11747"  call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
11748  " get bookmarks from .netrwbook file
11749  let savefile= s:NetrwHome()."/.netrwbook"
11750  if filereadable(s:NetrwFile(savefile))
11751"   call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11752   NetrwKeepj call s:NetrwBookHistSave()
11753"   call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11754   NetrwKeepj call delete(savefile)
11755  endif
11756"  call Dret("s:MergeBookmarks")
11757endfun
11758
11759" ---------------------------------------------------------------------
11760" s:NetrwBMShow: {{{2
11761fun! s:NetrwBMShow()
11762"  call Dfunc("s:NetrwBMShow()")
11763  redir => bmshowraw
11764   menu
11765  redir END
11766  let bmshowlist = split(bmshowraw,'\n')
11767  if bmshowlist != []
11768   let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"')
11769   if bmshowfuncs != []
11770    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11771    if bmshowfunc =~# '^call.*BMShow()'
11772     exe "sil! NetrwKeepj ".bmshowfunc
11773    endif
11774   endif
11775  endif
11776"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
11777endfun
11778
11779" ---------------------------------------------------------------------
11780" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
11781fun! s:NetrwCursor(editfile)
11782  if !exists("w:netrw_liststyle")
11783   let w:netrw_liststyle= g:netrw_liststyle
11784  endif
11785"  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)
11786
11787"  call Decho("(s:NetrwCursor) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11788
11789  if &ft != "netrw"
11790   " if the current window isn't a netrw directory listing window, then use user cursorline/column
11791   " settings.  Affects when netrw is used to read/write a file using scp/ftp/etc.
11792"   call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
11793
11794  elseif g:netrw_cursor == 8
11795   if w:netrw_liststyle == s:WIDELIST
11796    setl cursorline
11797    setl cursorcolumn
11798   else
11799    setl cursorline
11800   endif
11801  elseif g:netrw_cursor == 7
11802    setl cursorline
11803  elseif g:netrw_cursor == 6
11804   if w:netrw_liststyle == s:WIDELIST
11805    setl cursorline
11806   endif
11807  elseif g:netrw_cursor == 4
11808   " all styles: cursorline, cursorcolumn
11809"   call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
11810   setl cursorline
11811   setl cursorcolumn
11812
11813  elseif g:netrw_cursor == 3
11814   " thin-long-tree: cursorline, user's cursorcolumn
11815   " wide          : cursorline, cursorcolumn
11816   if w:netrw_liststyle == s:WIDELIST
11817"    call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11818    setl cursorline
11819    setl cursorcolumn
11820   else
11821"    call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11822    setl cursorline
11823   endif
11824
11825  elseif g:netrw_cursor == 2
11826   " thin-long-tree: cursorline, user's cursorcolumn
11827   " wide          : cursorline, user's cursorcolumn
11828"   call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11829   setl cursorline
11830
11831  elseif g:netrw_cursor == 1
11832   " thin-long-tree: user's cursorline, user's cursorcolumn
11833   " wide          : cursorline,        user's cursorcolumn
11834   if w:netrw_liststyle == s:WIDELIST
11835"    call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11836    setl cursorline
11837   else
11838"    call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11839   endif
11840
11841  else
11842   " all styles: user's cursorline, user's cursorcolumn
11843"   call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11844   let &l:cursorline   = s:netrw_usercul
11845   let &l:cursorcolumn = s:netrw_usercuc
11846  endif
11847
11848" call Decho("(s:NetrwCursor) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11849"  call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
11850endfun
11851
11852" ---------------------------------------------------------------------
11853" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11854fun! s:RestoreCursorline()
11855"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
11856  if exists("s:netrw_usercul")
11857   let &l:cursorline   = s:netrw_usercul
11858  endif
11859  if exists("s:netrw_usercuc")
11860   let &l:cursorcolumn = s:netrw_usercuc
11861  endif
11862"  call Decho("(s:RestoreCursorline) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11863"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
11864endfun
11865
11866" ---------------------------------------------------------------------
11867" s:NetrwDelete: Deletes a file. {{{2
11868"           Uses Steve Hall's idea to insure that Windows paths stay
11869"           acceptable.  No effect on Unix paths.
11870"  Examples of use:  let result= s:NetrwDelete(path)
11871fun! s:NetrwDelete(path)
11872"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
11873
11874  let path = netrw#WinPath(a:path)
11875  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
11876   if exists("+shellslash")
11877    let sskeep= &shellslash
11878    setl noshellslash
11879    let result      = delete(path)
11880    let &shellslash = sskeep
11881   else
11882"    call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11883    let result= delete(path)
11884   endif
11885  else
11886"   call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11887   let result= delete(path)
11888  endif
11889  if result < 0
11890   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
11891  endif
11892
11893"  call Dret("s:NetrwDelete ".result)
11894  return result
11895endfun
11896
11897" ---------------------------------------------------------------------
11898" s:NetrwBufRemover: removes a buffer that: {{{2s
11899"                    has buffer-id > 1
11900"                    is unlisted
11901"                    is unnamed
11902"                    does not appear in any window
11903fun! s:NetrwBufRemover(bufid)
11904"  call Dfunc("s:NetrwBufRemover(".a:bufid.")")
11905"  call Decho("buf#".a:bufid."           ".((a:bufid > 1)? ">" : "≯")." must be >1 for removal","~".expand("<slnum>"))
11906"  call Decho("buf#".a:bufid." is        ".(buflisted(a:bufid)? "listed" : "unlisted"),"~".expand("<slnum>"))
11907"  call Decho("buf#".a:bufid." has name <".bufname(a:bufid).">","~".expand("<slnum>"))
11908"  call Decho("buf#".a:bufid." has winid#".bufwinid(a:bufid),"~".expand("<slnum>"))
11909
11910  if a:bufid > 1 && !buflisted(a:bufid) && bufname(a:bufid) == "" && bufwinid(a:bufid) == -1
11911"   call Decho("(s:NetrwBufRemover) removing buffer#".a:bufid,"~".expand("<slnum>"))
11912   exe "bd! ".a:bufid
11913  endif
11914
11915"  call Dret("s:NetrwBufRemover")
11916endfun
11917
11918" ---------------------------------------------------------------------
11919" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
11920fun! s:NetrwEnew(...)
11921"  call Dfunc("s:NetrwEnew() a:0=".a:0." win#".winnr()." winnr($)=".winnr("$")." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
11922"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
11923
11924  " Clean out the last buffer:
11925  " Check if the last buffer has # > 1, is unlisted, is unnamed, and does not appear in a window
11926  " If so, delete it.
11927  call s:NetrwBufRemover(bufnr("$"))
11928
11929  " grab a function-local-variable copy of buffer variables
11930"  call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
11931  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
11932  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
11933  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
11934  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
11935  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11936  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
11937  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
11938  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
11939  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11940  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11941  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
11942  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
11943  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
11944  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
11945  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
11946  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
11947
11948  NetrwKeepj call s:NetrwOptionsRestore("w:")
11949"  call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>"))
11950  " when tree listing uses file TreeListing... a new buffer is made.
11951  " Want the old buffer to be unlisted.
11952  " COMBAK: this causes a problem, see P43
11953"  setl nobl
11954  let netrw_keepdiff= &l:diff
11955  noswapfile NetrwKeepj keepalt enew!
11956  let &l:diff= netrw_keepdiff
11957"  call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
11958  NetrwKeepj call s:NetrwOptionsSave("w:")
11959
11960  " copy function-local-variables to buffer variable equivalents
11961"  call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
11962  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
11963  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
11964  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
11965  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
11966  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
11967  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
11968  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
11969  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
11970  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11971  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11972  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
11973  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
11974  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
11975  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
11976  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
11977  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
11978
11979  if a:0 > 0
11980   let b:netrw_curdir= a:1
11981   if b:netrw_curdir =~ '/$'
11982    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11983     setl nobl
11984     file NetrwTreeListing
11985     setl nobl bt=nowrite bh=hide
11986     nno <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
11987     nno <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
11988    else
11989     call s:NetrwBufRename(b:netrw_curdir)
11990    endif
11991   endif
11992  endif
11993  if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
11994   let &l:bexpr = "netrw#BalloonHelp()"
11995  endif
11996
11997"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
11998endfun
11999
12000" ---------------------------------------------------------------------
12001" s:NetrwExe: executes a string using "!" {{{2
12002fun! s:NetrwExe(cmd)
12003"  call Dfunc("s:NetrwExe(a:cmd<".a:cmd.">)")
12004  if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin
12005"    call Decho("using win32:",expand("<slnum>"))
12006    let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
12007    set shell& shellcmdflag& shellxquote& shellxescape&
12008    set shellquote& shellpipe& shellredir& shellslash&
12009    exe a:cmd
12010    let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
12011  else
12012"   call Decho("exe ".a:cmd,'~'.expand("<slnum>"))
12013   exe a:cmd
12014  endif
12015  if v:shell_error
12016   call netrw#ErrorMsg(s:WARNING,"shell signalled an error",106)
12017  endif
12018"  call Dret("s:NetrwExe : v:shell_error=".v:shell_error)
12019endfun
12020
12021" ---------------------------------------------------------------------
12022" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
12023fun! s:NetrwInsureWinVars()
12024  if !exists("w:netrw_liststyle")
12025"   call Dfunc("s:NetrwInsureWinVars() win#".winnr())
12026   let curbuf = bufnr("%")
12027   let curwin = winnr()
12028   let iwin   = 1
12029   while iwin <= winnr("$")
12030    exe iwin."wincmd w"
12031    if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
12032     " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
12033     let winvars= w:
12034     break
12035    endif
12036    let iwin= iwin + 1
12037   endwhile
12038   exe "keepalt ".curwin."wincmd w"
12039   if exists("winvars")
12040"    call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
12041    for k in keys(winvars)
12042     let w:{k}= winvars[k]
12043    endfor
12044   endif
12045"   call Dret("s:NetrwInsureWinVars win#".winnr())
12046  endif
12047endfun
12048
12049" ---------------------------------------------------------------------
12050" s:NetrwLcd: handles changing the (local) directory {{{2
12051"   Returns: 0=success
12052"           -1=failed
12053fun! s:NetrwLcd(newdir)
12054"  call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
12055"  call Decho("changing local directory",'~'.expand("<slnum>"))
12056
12057  let err472= 0
12058  try
12059   exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
12060  catch /^Vim\%((\a\+)\)\=:E344/
12061     " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
12062     " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
12063     " 'root' (ie. '\').  The share name may start with either backslashes ('\\Foo') or
12064     " forward slashes ('//Foo'), depending on whether backslashes have been converted to
12065     " forward slashes by earlier code; so check for both.
12066     if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
12067       if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
12068         let dirname = '\'
12069	 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
12070       endif
12071     endif
12072  catch /^Vim\%((\a\+)\)\=:E472/
12073   let err472= 1
12074  endtry
12075
12076  if err472
12077   call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
12078   if exists("w:netrw_prvdir")
12079    let a:newdir= w:netrw_prvdir
12080   else
12081    call s:NetrwOptionsRestore("w:")
12082"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
12083    exe "setl ".g:netrw_bufsettings
12084"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
12085    let a:newdir= dirname
12086   endif
12087"   call Dret("s:NetrwBrowse -1 : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
12088   return -1
12089  endif
12090
12091"  call Decho("getcwd        <".getcwd().">")
12092"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
12093"  call Dret("s:NetrwLcd 0")
12094  return 0
12095endfun
12096
12097" ------------------------------------------------------------------------
12098" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
12099" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
12100fun! s:NetrwSaveWordPosn()
12101"  call Dfunc("NetrwSaveWordPosn()")
12102  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
12103"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
12104endfun
12105
12106" ---------------------------------------------------------------------
12107" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
12108"                       1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
12109fun! s:NetrwHumanReadable(sz)
12110"  call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
12111
12112  if g:netrw_sizestyle == 'h'
12113   if a:sz >= 1000000000
12114    let sz = printf("%.1f",a:sz/1000000000.0)."g"
12115   elseif a:sz >= 10000000
12116    let sz = printf("%d",a:sz/1000000)."m"
12117   elseif a:sz >= 1000000
12118    let sz = printf("%.1f",a:sz/1000000.0)."m"
12119   elseif a:sz >= 10000
12120    let sz = printf("%d",a:sz/1000)."k"
12121   elseif a:sz >= 1000
12122    let sz = printf("%.1f",a:sz/1000.0)."k"
12123   else
12124    let sz= a:sz
12125   endif
12126
12127  elseif g:netrw_sizestyle == 'H'
12128   if a:sz >= 1073741824
12129    let sz = printf("%.1f",a:sz/1073741824.0)."G"
12130   elseif a:sz >= 10485760
12131    let sz = printf("%d",a:sz/1048576)."M"
12132   elseif a:sz >= 1048576
12133    let sz = printf("%.1f",a:sz/1048576.0)."M"
12134   elseif a:sz >= 10240
12135    let sz = printf("%d",a:sz/1024)."K"
12136   elseif a:sz >= 1024
12137    let sz = printf("%.1f",a:sz/1024.0)."K"
12138   else
12139    let sz= a:sz
12140   endif
12141
12142  else
12143   let sz= a:sz
12144  endif
12145
12146"  call Dret("s:NetrwHumanReadable ".sz)
12147  return sz
12148endfun
12149
12150" ---------------------------------------------------------------------
12151" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
12152"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
12153fun! s:NetrwRestoreWordPosn()
12154"  call Dfunc("NetrwRestoreWordPosn()")
12155  sil! call search(s:netrw_saveword,'w')
12156"  call Dret("NetrwRestoreWordPosn")
12157endfun
12158
12159" ---------------------------------------------------------------------
12160" s:RestoreBufVars: {{{2
12161fun! s:RestoreBufVars()
12162"  call Dfunc("s:RestoreBufVars()")
12163
12164  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
12165  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
12166  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
12167  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
12168  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
12169  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
12170
12171"  call Dret("s:RestoreBufVars")
12172endfun
12173
12174" ---------------------------------------------------------------------
12175" s:RemotePathAnalysis: {{{2
12176fun! s:RemotePathAnalysis(dirname)
12177"  call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
12178
12179  "                method   ://    user  @      machine      :port            /path
12180  let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
12181  let s:method  = substitute(a:dirname,dirpat,'\1','')
12182  let s:user    = substitute(a:dirname,dirpat,'\3','')
12183  let s:machine = substitute(a:dirname,dirpat,'\4','')
12184  let s:port    = substitute(a:dirname,dirpat,'\5','')
12185  let s:path    = substitute(a:dirname,dirpat,'\6','')
12186  let s:fname   = substitute(s:path,'^.*/\ze.','','')
12187  if s:machine =~ '@'
12188   let dirpat    = '^\(.*\)@\(.\{-}\)$'
12189   let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')
12190   let s:machine = substitute(s:machine,dirpat,'\2','')
12191  endif
12192
12193"  call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
12194"  call Decho("set up s:user   <".s:user   .">",'~'.expand("<slnum>"))
12195"  call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
12196"  call Decho("set up s:port   <".s:port.">",'~'.expand("<slnum>"))
12197"  call Decho("set up s:path   <".s:path   .">",'~'.expand("<slnum>"))
12198"  call Decho("set up s:fname  <".s:fname  .">",'~'.expand("<slnum>"))
12199
12200"  call Dret("s:RemotePathAnalysis")
12201endfun
12202
12203" ---------------------------------------------------------------------
12204" s:RemoteSystem: runs a command on a remote host using ssh {{{2
12205"                 Returns status
12206" Runs system() on
12207"    [cd REMOTEDIRPATH;] a:cmd
12208" Note that it doesn't do s:ShellEscape(a:cmd)!
12209fun! s:RemoteSystem(cmd)
12210"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
12211  if !executable(g:netrw_ssh_cmd)
12212   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
12213  elseif !exists("b:netrw_curdir")
12214   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
12215  else
12216   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
12217   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
12218   if remotedir != ""
12219    let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
12220   else
12221    let cmd= cmd.' '
12222   endif
12223   let cmd= cmd.a:cmd
12224"   call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
12225   let ret= system(cmd)
12226  endif
12227"  call Dret("s:RemoteSystem ".ret)
12228  return ret
12229endfun
12230
12231" ---------------------------------------------------------------------
12232" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
12233fun! s:RestoreWinVars()
12234"  call Dfunc("s:RestoreWinVars()")
12235  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
12236  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
12237  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
12238  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
12239  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
12240  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
12241  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
12242  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
12243  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
12244  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
12245  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
12246  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
12247  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
12248  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
12249  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
12250  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
12251  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
12252  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
12253"  call Dret("s:RestoreWinVars")
12254endfun
12255
12256" ---------------------------------------------------------------------
12257" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
12258"
12259"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
12260"             is true) and a command, :Rexplore, which call this function.
12261"
12262"             s:netrw_posn is set up by s:NetrwBrowseChgDir()
12263"
12264"             s:rexposn_BUFNR used to save/restore cursor position
12265fun! s:NetrwRexplore(islocal,dirname)
12266  if exists("s:netrwdrag")
12267   return
12268  endif
12269"  call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
12270"  call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
12271"  call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
12272
12273  if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
12274   " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
12275"   call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
12276   exe "NetrwKeepj e ".w:netrw_rexfile
12277   unlet w:netrw_rexfile
12278"   call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%").">  (ft=".&ft.")")
12279   return
12280"  else " Decho
12281"   call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
12282"   call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
12283  endif
12284
12285  " ---------------------------
12286  " :Rex issued while in a file
12287  " ---------------------------
12288
12289  " record current file so :Rex can return to it from netrw
12290  let w:netrw_rexfile= expand("%")
12291"  call Decho("set w:netrw_rexfile<".w:netrw_rexfile.">  (win#".winnr().")",'~'.expand("<slnum>"))
12292
12293  if !exists("w:netrw_rexlocal")
12294"   call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
12295   return
12296  endif
12297"  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>"))
12298  if w:netrw_rexlocal
12299   NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
12300  else
12301   NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
12302  endif
12303  if exists("s:initbeval")
12304   setl beval
12305  endif
12306  if exists("s:rexposn_".bufnr("%"))
12307"   call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
12308   " restore position in directory listing
12309"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
12310   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
12311   if exists("s:rexposn_".bufnr('%'))
12312    unlet s:rexposn_{bufnr('%')}
12313   endif
12314  else
12315"   call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
12316  endif
12317
12318  if has("syntax") && exists("g:syntax_on") && g:syntax_on
12319   if exists("s:explore_match")
12320    exe "2match netrwMarkFile /".s:explore_match."/"
12321   endif
12322  endif
12323
12324"  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>"))
12325"  call Dret("s:NetrwRexplore : ft=".&ft)
12326endfun
12327
12328" ---------------------------------------------------------------------
12329" s:SaveBufVars: save selected b: variables to s: variables {{{2
12330"                use s:RestoreBufVars() to restore b: variables from s: variables
12331fun! s:SaveBufVars()
12332"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
12333
12334  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
12335  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
12336  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
12337  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
12338  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
12339  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
12340
12341"  call Dret("s:SaveBufVars")
12342endfun
12343
12344" ---------------------------------------------------------------------
12345" s:SavePosn: saves position associated with current buffer into a dictionary {{{2
12346fun! s:SavePosn(posndict)
12347"  call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12348
12349  if !exists("a:posndict[bufnr('%')]")
12350   let a:posndict[bufnr("%")]= []
12351  endif
12352"  call Decho("before push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12353  call add(a:posndict[bufnr("%")],winsaveview())
12354"  call Decho("after  push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12355
12356"  call Dret("s:SavePosn posndict")
12357  return a:posndict
12358endfun
12359
12360" ---------------------------------------------------------------------
12361" s:RestorePosn: restores position associated with current buffer using dictionary {{{2
12362fun! s:RestorePosn(posndict)
12363"  call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12364  if exists("a:posndict")
12365   if has_key(a:posndict,bufnr("%"))
12366"    call Decho("before pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12367    let posnlen= len(a:posndict[bufnr("%")])
12368    if posnlen > 0
12369     let posnlen= posnlen - 1
12370"     call Decho("restoring posn posndict[".bufnr("%")."][".posnlen."]=".string(a:posndict[bufnr("%")][posnlen]),'~'.expand("<slnum>"))
12371     call winrestview(a:posndict[bufnr("%")][posnlen])
12372     call remove(a:posndict[bufnr("%")],posnlen)
12373"     call Decho("after  pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12374    endif
12375   endif
12376  endif
12377"  call Dret("s:RestorePosn")
12378endfun
12379
12380" ---------------------------------------------------------------------
12381" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
12382fun! s:SaveWinVars()
12383"  call Dfunc("s:SaveWinVars() win#".winnr())
12384  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
12385  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
12386  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
12387  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
12388  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
12389  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
12390  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
12391  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
12392  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
12393  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
12394  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
12395  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
12396  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
12397  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
12398  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
12399  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
12400  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
12401  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
12402"  call Dret("s:SaveWinVars")
12403endfun
12404
12405" ---------------------------------------------------------------------
12406" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
12407"   To allow separate windows to have their own activities, such as
12408"   Explore **/pattern, several variables have been made window-oriented.
12409"   However, when the user splits a browser window (ex: ctrl-w s), these
12410"   variables are not inherited by the new window.  SetBufWinVars() and
12411"   UseBufWinVars() get around that.
12412fun! s:SetBufWinVars()
12413"  call Dfunc("s:SetBufWinVars() win#".winnr())
12414  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
12415  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
12416  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
12417  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
12418  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
12419  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
12420  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
12421  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
12422  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
12423  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
12424"  call Dret("s:SetBufWinVars")
12425endfun
12426
12427" ---------------------------------------------------------------------
12428" s:SetRexDir: set directory for :Rexplore {{{2
12429fun! s:SetRexDir(islocal,dirname)
12430"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
12431  let w:netrw_rexdir         = a:dirname
12432  let w:netrw_rexlocal       = a:islocal
12433  let s:rexposn_{bufnr("%")} = winsaveview()
12434"  call Decho("setting w:netrw_rexdir  =".w:netrw_rexdir,'~'.expand("<slnum>"))
12435"  call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>"))
12436"  call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
12437"  call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>"))
12438"  call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
12439endfun
12440
12441" ---------------------------------------------------------------------
12442" s:ShowLink: used to modify thin and tree listings to show links {{{2
12443fun! s:ShowLink()
12444" "  call Dfunc("s:ShowLink()")
12445" "  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
12446" "  call Decho(printf("line#%4d: %s",line("."),getline(".")),'~'.expand("<slnum>"))
12447  if exists("b:netrw_curdir")
12448   norm! $?\a
12449   let fname   = b:netrw_curdir.'/'.s:NetrwGetWord()
12450   let resname = resolve(fname)
12451" "   call Decho("fname         <".fname.">",'~'.expand("<slnum>"))
12452" "   call Decho("resname       <".resname.">",'~'.expand("<slnum>"))
12453" "   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
12454   if resname =~ '^\M'.b:netrw_curdir.'/'
12455    let dirlen  = strlen(b:netrw_curdir)
12456    let resname = strpart(resname,dirlen+1)
12457" "    call Decho("resname<".resname.">  (b:netrw_curdir elided)",'~'.expand("<slnum>"))
12458   endif
12459   let modline = getline(".")."\t --> ".resname
12460" "   call Decho("fname  <".fname.">",'~'.expand("<slnum>"))
12461" "   call Decho("modline<".modline.">",'~'.expand("<slnum>"))
12462   setl noro ma
12463   call setline(".",modline)
12464   setl ro noma nomod
12465  endif
12466" "  call Dret("s:ShowLink".((exists("fname")? ' : '.fname : 'n/a')))
12467endfun
12468
12469" ---------------------------------------------------------------------
12470" s:ShowStyle: {{{2
12471fun! s:ShowStyle()
12472  if !exists("w:netrw_liststyle")
12473   let liststyle= g:netrw_liststyle
12474  else
12475   let liststyle= w:netrw_liststyle
12476  endif
12477  if     liststyle == s:THINLIST
12478   return s:THINLIST.":thin"
12479  elseif liststyle == s:LONGLIST
12480   return s:LONGLIST.":long"
12481  elseif liststyle == s:WIDELIST
12482   return s:WIDELIST.":wide"
12483  elseif liststyle == s:TREELIST
12484   return s:TREELIST.":tree"
12485  else
12486   return 'n/a'
12487  endif
12488endfun
12489
12490" ---------------------------------------------------------------------
12491" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
12492"           Solution from Nicolai Weibull, vim docs (:help strlen()),
12493"           Tony Mechelynck, and my own invention.
12494fun! s:Strlen(x)
12495"  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
12496
12497  if v:version >= 703 && exists("*strdisplaywidth")
12498   let ret= strdisplaywidth(a:x)
12499
12500  elseif type(g:Align_xstrlen) == 1
12501   " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
12502   exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
12503
12504  elseif g:Align_xstrlen == 1
12505   " number of codepoints (Latin a + combining circumflex is two codepoints)
12506   " (comment from TM, solution from NW)
12507   let ret= strlen(substitute(a:x,'.','c','g'))
12508
12509  elseif g:Align_xstrlen == 2
12510   " number of spacing codepoints (Latin a + combining circumflex is one spacing
12511   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
12512   " (comment from TM, solution from TM)
12513   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
12514
12515  elseif g:Align_xstrlen == 3
12516   " virtual length (counting, for instance, tabs as anything between 1 and
12517   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
12518   " preceded by lam, one otherwise, etc.)
12519   " (comment from TM, solution from me)
12520   let modkeep= &l:mod
12521   exe "norm! o\<esc>"
12522   call setline(line("."),a:x)
12523   let ret= virtcol("$") - 1
12524   d
12525   NetrwKeepj norm! k
12526   let &l:mod= modkeep
12527
12528  else
12529   " at least give a decent default
12530    let ret= strlen(a:x)
12531  endif
12532"  "" call Dret("s:Strlen ".ret)
12533  return ret
12534endfun
12535
12536" ---------------------------------------------------------------------
12537" s:ShellEscape: shellescape(), or special windows handling {{{2
12538fun! s:ShellEscape(s, ...)
12539  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
12540    return printf('"%s"', substitute(a:s, '"', '""', 'g'))
12541  endif
12542  let f = a:0 > 0 ? a:1 : 0
12543  return shellescape(a:s, f)
12544endfun
12545
12546" ---------------------------------------------------------------------
12547" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
12548fun! s:TreeListMove(dir)
12549"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
12550  let curline      = getline('.')
12551  let prvline      = (line(".") > 1)?         getline(line(".")-1) : ''
12552  let nxtline      = (line(".") < line("$"))? getline(line(".")+1) : ''
12553  let curindent    = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
12554  let indentm1     = substitute(curindent,'^'.s:treedepthstring,'','')
12555  let treedepthchr = substitute(s:treedepthstring,' ','','g')
12556  let stopline     = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
12557"  call Decho("prvline  <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
12558"  call Decho("curline  <".curline."> #".line(".")    , '~'.expand("<slnum>"))
12559"  call Decho("nxtline  <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
12560"  call Decho("curindent<".curindent.">"              , '~'.expand("<slnum>"))
12561"  call Decho("indentm1 <".indentm1.">"               , '~'.expand("<slnum>"))
12562  "  COMBAK : need to handle when on a directory
12563  "  COMBAK : need to handle ]] and ][.  In general, needs work!!!
12564  if curline !~ '/$'
12565   if     a:dir == '[[' && prvline != ''
12566    NetrwKeepj norm! 0
12567    let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
12568"    call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
12569   elseif a:dir == '[]' && nxtline != ''
12570    NetrwKeepj norm! 0
12571"    call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>"))
12572    let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
12573    if nl != 0
12574     NetrwKeepj norm! k
12575    else
12576     NetrwKeepj norm! G
12577    endif
12578"    call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
12579   endif
12580  endif
12581
12582"  call Dret("s:TreeListMove")
12583endfun
12584
12585" ---------------------------------------------------------------------
12586" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
12587"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
12588"                      can't be called except via emenu.  But due to locale, that menu line may not be called
12589"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
12590fun! s:UpdateBuffersMenu()
12591"  call Dfunc("s:UpdateBuffersMenu()")
12592  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
12593   try
12594    sil emenu Buffers.Refresh\ menu
12595   catch /^Vim\%((\a\+)\)\=:E/
12596    let v:errmsg= ""
12597    sil NetrwKeepj call s:NetrwBMShow()
12598   endtry
12599  endif
12600"  call Dret("s:UpdateBuffersMenu")
12601endfun
12602
12603" ---------------------------------------------------------------------
12604" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
12605"              Matching function to s:SetBufWinVars()
12606fun! s:UseBufWinVars()
12607"  call Dfunc("s:UseBufWinVars()")
12608  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
12609  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
12610  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
12611  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
12612  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
12613  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
12614  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
12615  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
12616  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
12617  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
12618"  call Dret("s:UseBufWinVars")
12619endfun
12620
12621" ---------------------------------------------------------------------
12622" s:UserMaps: supports user-defined UserMaps {{{2
12623"               * calls a user-supplied funcref(islocal,curdir)
12624"               * interprets result
12625"             See netrw#UserMaps()
12626fun! s:UserMaps(islocal,funcname)
12627"  call Dfunc("s:UserMaps(islocal=".a:islocal.",funcname<".a:funcname.">)")
12628
12629  if !exists("b:netrw_curdir")
12630   let b:netrw_curdir= getcwd()
12631  endif
12632  let Funcref = function(a:funcname)
12633  let result  = Funcref(a:islocal)
12634
12635  if     type(result) == 1
12636   " if result from user's funcref is a string...
12637"   call Decho("result string from user funcref<".result.">",'~'.expand("<slnum>"))
12638   if result == "refresh"
12639"    call Decho("refreshing display",'~'.expand("<slnum>"))
12640    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12641   elseif result != ""
12642"    call Decho("executing result<".result.">",'~'.expand("<slnum>"))
12643    exe result
12644   endif
12645
12646  elseif type(result) == 3
12647   " if result from user's funcref is a List...
12648"   call Decho("result List from user funcref<".string(result).">",'~'.expand("<slnum>"))
12649   for action in result
12650    if action == "refresh"
12651"     call Decho("refreshing display",'~'.expand("<slnum>"))
12652     call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12653    elseif action != ""
12654"     call Decho("executing action<".action.">",'~'.expand("<slnum>"))
12655     exe action
12656    endif
12657   endfor
12658  endif
12659
12660"  call Dret("s:UserMaps")
12661endfun
12662
12663" ==========================
12664" Settings Restoration: {{{1
12665" ==========================
12666let &cpo= s:keepcpo
12667unlet s:keepcpo
12668
12669" ===============
12670" Modelines: {{{1
12671" ===============
12672" vim:ts=8 fdm=marker
12673