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  if has("clipboard") && g:netrw_clipboard
709"   call Decho("(netrw#Explore) save @* and @+",'~'.expand("<slnum>"))
710   sil! let keepregstar = @*
711   sil! let keepregplus = @+
712  endif
713  sil! let keepregslash= @/
714
715  " if   dosplit
716  " -or- file has been modified AND file not hidden when abandoned
717  " -or- Texplore used
718  if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
719"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified",'~'.expand("<slnum>"))
720   call s:SaveWinVars()
721   let winsz= g:netrw_winsize
722   if a:indx > 0
723    let winsz= a:indx
724   endif
725
726   if a:style == 0      " Explore, Sexplore
727"    call Decho("style=0: Explore or Sexplore",'~'.expand("<slnum>"))
728    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
729    if winsz == 0|let winsz= ""|endif
730    exe "noswapfile ".winsz."wincmd s"
731"    call Decho("exe noswapfile ".winsz."wincmd s",'~'.expand("<slnum>"))
732
733   elseif a:style == 1  "Explore!, Sexplore!
734"    call Decho("style=1: Explore! or Sexplore!",'~'.expand("<slnum>"))
735    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
736    if winsz == 0|let winsz= ""|endif
737    exe "keepalt noswapfile ".winsz."wincmd v"
738"    call Decho("exe keepalt noswapfile ".winsz."wincmd v",'~'.expand("<slnum>"))
739
740   elseif a:style == 2  " Hexplore
741"    call Decho("style=2: Hexplore",'~'.expand("<slnum>"))
742    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
743    if winsz == 0|let winsz= ""|endif
744    exe "keepalt noswapfile bel ".winsz."wincmd s"
745"    call Decho("exe keepalt noswapfile bel ".winsz."wincmd s",'~'.expand("<slnum>"))
746
747   elseif a:style == 3  " Hexplore!
748"    call Decho("style=3: Hexplore!",'~'.expand("<slnum>"))
749    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
750    if winsz == 0|let winsz= ""|endif
751    exe "keepalt noswapfile abo ".winsz."wincmd s"
752"    call Decho("exe keepalt noswapfile abo ".winsz."wincmd s",'~'.expand("<slnum>"))
753
754   elseif a:style == 4  " Vexplore
755"    call Decho("style=4: Vexplore",'~'.expand("<slnum>"))
756    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
757    if winsz == 0|let winsz= ""|endif
758    exe "keepalt noswapfile lefta ".winsz."wincmd v"
759"    call Decho("exe keepalt noswapfile lefta ".winsz."wincmd v",'~'.expand("<slnum>"))
760
761   elseif a:style == 5  " Vexplore!
762"    call Decho("style=5: Vexplore!",'~'.expand("<slnum>"))
763    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
764    if winsz == 0|let winsz= ""|endif
765    exe "keepalt noswapfile rightb ".winsz."wincmd v"
766"    call Decho("exe keepalt noswapfile rightb ".winsz."wincmd v",'~'.expand("<slnum>"))
767
768   elseif a:style == 6  " Texplore
769    call s:SaveBufVars()
770"    call Decho("style  = 6: Texplore",'~'.expand("<slnum>"))
771    exe "keepalt tabnew ".fnameescape(curdir)
772"    call Decho("exe keepalt tabnew ".fnameescape(curdir),'~'.expand("<slnum>"))
773    call s:RestoreBufVars()
774   endif
775   call s:RestoreWinVars()
776"  else " Decho
777"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6",'~'.expand("<slnum>"))
778  endif
779  NetrwKeepj norm! 0
780
781  if a:0 > 0
782"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">",'~'.expand("<slnum>"))
783   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
784"    call Decho("..case a:1<".a:1.">: starts with ~ and unix or cygwin",'~'.expand("<slnum>"))
785    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
786"    call Decho("..using dirname<".dirname.">  (case: ~ && unix||cygwin)",'~'.expand("<slnum>"))
787   elseif a:1 == '.'
788"    call Decho("..case a:1<".a:1.">: matches .",'~'.expand("<slnum>"))
789    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
790    if dirname !~ '/$'
791     let dirname= dirname."/"
792    endif
793"    call Decho("..using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")",'~'.expand("<slnum>"))
794   elseif a:1 =~ '\$'
795"    call Decho("..case a:1<".a:1.">: matches ending $",'~'.expand("<slnum>"))
796    let dirname= simplify(expand(a:1))
797"    call Decho("..using user-specified dirname<".dirname."> with $env-var",'~'.expand("<slnum>"))
798   elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
799"    call Decho("..case a:1<".a:1.">: other, not pattern or filepattern",'~'.expand("<slnum>"))
800    let dirname= simplify(a:1)
801"    call Decho("..using user-specified dirname<".dirname.">",'~'.expand("<slnum>"))
802   else
803"    call Decho("..case a:1: pattern or filepattern",'~'.expand("<slnum>"))
804    let dirname= a:1
805   endif
806  else
807   " clear explore
808"   call Decho("case a:0=".a:0.": clearing Explore list",'~'.expand("<slnum>"))
809   call s:NetrwClearExplore()
810"   call Dret("netrw#Explore : cleared list")
811   return
812  endif
813
814"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
815  if dirname =~ '\.\./\=$'
816   let dirname= simplify(fnamemodify(dirname,':p:h'))
817  elseif dirname =~ '\.\.' || dirname == '.'
818   let dirname= simplify(fnamemodify(dirname,':p'))
819  endif
820"  call Decho("dirname<".dirname.">  (after simplify)",'~'.expand("<slnum>"))
821
822  if dirname =~ '^\*//'
823   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
824"   call Decho("case starpat=1: Explore *//pattern",'~'.expand("<slnum>"))
825   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
826   let starpat= 1
827"   call Decho("..Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
828   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
829
830  elseif dirname =~ '^\*\*//'
831   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
832"   call Decho("case starpat=2: Explore **//pattern",'~'.expand("<slnum>"))
833   let pattern= substitute(dirname,'^\*\*//','','')
834   let starpat= 2
835"   call Decho("..Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
836
837  elseif dirname =~ '/\*\*/'
838   " handle .../**/.../filepat
839"   call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
840   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
841   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
842    let b:netrw_curdir = prefixdir
843   else
844    let b:netrw_curdir= getcwd().'/'.prefixdir
845   endif
846   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
847   let starpat= 4
848"   call Decho("..pwd<".getcwd()."> dirname<".dirname.">",'~'.expand("<slnum>"))
849"   call Decho("..case Explore ../**/../filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
850
851  elseif dirname =~ '^\*/'
852   " case starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
853   let starpat= 3
854"   call Decho("case starpat=3: Explore */filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
855
856  elseif dirname=~ '^\*\*/'
857   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
858   let starpat= 4
859"   call Decho("case starpat=4: Explore **/filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
860
861  else
862   let starpat= 0
863"   call Decho("case starpat=0: default",'~'.expand("<slnum>"))
864  endif
865
866  if starpat == 0 && a:indx >= 0
867   " [Explore Hexplore Vexplore Sexplore] [dirname]
868"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname.">, handles Explore Hexplore Vexplore Sexplore",'~'.expand("<slnum>"))
869   if dirname == ""
870    let dirname= curfiledir
871"    call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>"))
872   endif
873   if dirname =~# '^scp://' || dirname =~ '^ftp://'
874    call netrw#Nread(2,dirname)
875   else
876    if dirname == ""
877     let dirname= getcwd()
878    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
879     " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
880     " depending on whether backslashes have been converted to forward slashes by earlier code).
881     if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
882      let dirname= b:netrw_curdir."/".dirname
883     endif
884    elseif dirname !~ '^/'
885     let dirname= b:netrw_curdir."/".dirname
886    endif
887"    call Decho("..calling LocalBrowseCheck(dirname<".dirname.">)",'~'.expand("<slnum>"))
888    call netrw#LocalBrowseCheck(dirname)
889"    call Decho(" modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
890"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
891   endif
892   if exists("w:netrw_bannercnt")
893    " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
894    " If one wants to return the same place in the netrw window, use :Rex instead.
895    exe w:netrw_bannercnt
896   endif
897
898"   call Decho("curdir<".curdir.">",'~'.expand("<slnum>"))
899   " ---------------------------------------------------------------------
900   " Jan 24, 2013: not sure why the following was present.  See P08-Ingelrest
901"   if has("win32") || has("win95") || has("win64") || has("win16")
902"    NetrwKeepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
903"   else
904"    NetrwKeepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
905"   endif
906   " ---------------------------------------------------------------------
907
908  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
909  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
910  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
911  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
912  elseif a:indx <= 0
913   " Nexplore, Pexplore, Explore: handle starpat
914"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx,'~'.expand("<slnum>"))
915   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
916"    call Decho("..set up <s-up> and <s-down> maps",'~'.expand("<slnum>"))
917    let s:didstarstar= 1
918    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
919    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
920   endif
921
922   if has("path_extra")
923"    call Decho("..starpat=".starpat.": has +path_extra",'~'.expand("<slnum>"))
924    if !exists("w:netrw_explore_indx")
925     let w:netrw_explore_indx= 0
926    endif
927
928    let indx = a:indx
929"    call Decho("..starpat=".starpat.": set indx= [a:indx=".indx."]",'~'.expand("<slnum>"))
930
931    if indx == -1
932     " Nexplore
933"     call Decho("..case Nexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
934     if !exists("w:netrw_explore_list") " sanity check
935      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
936      if has("clipboard") && g:netrw_clipboard
937"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
938       if @* != keepregstar | sil! let @* = keepregstar | endif
939       if @+ != keepregplus | sil! let @+ = keepregplus | endif
940      endif
941      sil! let @/ = keepregslash
942"      call Dret("netrw#Explore")
943      return
944     endif
945     let indx= w:netrw_explore_indx
946     if indx < 0                        | let indx= 0                           | endif
947     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
948     let curfile= w:netrw_explore_list[indx]
949"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
950     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
951      let indx= indx + 1
952"      call Decho("....indx=".indx." (Nexplore while loop)",'~'.expand("<slnum>"))
953     endwhile
954     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
955"     call Decho("....Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
956
957    elseif indx == -2
958     " Pexplore
959"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
960     if !exists("w:netrw_explore_list") " sanity check
961      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
962      if has("clipboard") && g:netrw_clipboard
963"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
964       if @* != keepregstar | sil! let @* = keepregstar | endif
965       if @+ != keepregplus | sil! let @+ = keepregplus | endif
966      endif
967      sil! let @/ = keepregslash
968"      call Dret("netrw#Explore")
969      return
970     endif
971     let indx= w:netrw_explore_indx
972     if indx < 0                        | let indx= 0                           | endif
973     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
974     let curfile= w:netrw_explore_list[indx]
975"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
976     while indx >= 0 && curfile == w:netrw_explore_list[indx]
977      let indx= indx - 1
978"      call Decho("....indx=".indx." (Pexplore while loop)",'~'.expand("<slnum>"))
979     endwhile
980     if indx < 0                        | let indx= 0                           | endif
981"     call Decho("....Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
982
983    else
984     " Explore -- initialize
985     " build list of files to Explore with Nexplore/Pexplore
986"     call Decho("..starpat=".starpat.": case Explore: initialize (indx=".indx.")",'~'.expand("<slnum>"))
987     NetrwKeepj keepalt call s:NetrwClearExplore()
988     let w:netrw_explore_indx= 0
989     if !exists("b:netrw_curdir")
990      let b:netrw_curdir= getcwd()
991     endif
992"     call Decho("....starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
993
994     " switch on starpat to build the w:netrw_explore_list of files
995     if starpat == 1
996      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
997"      call Decho("..case starpat=".starpat.": build *//pattern list  (curdir-only srch for files containing pattern)  &hls=".&hls,'~'.expand("<slnum>"))
998"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
999      try
1000       exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
1001      catch /^Vim\%((\a\+)\)\=:E480/
1002       keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
1003"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
1004       return
1005      endtry
1006      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
1007      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1008
1009     elseif starpat == 2
1010      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
1011"      call Decho("..case starpat=".starpat.": build **//pattern list  (recursive descent files containing pattern)",'~'.expand("<slnum>"))
1012"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
1013      try
1014       exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
1015      catch /^Vim\%((\a\+)\)\=:E480/
1016       keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
1017       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1018       if has("clipboard") && g:netrw_clipboard
1019"        call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1020        if @* != keepregstar | sil! let @* = keepregstar | endif
1021        if @+ != keepregplus | sil! let @+ = keepregplus | endif
1022       endif
1023       sil! let @/ = keepregslash
1024"       call Dret("netrw#Explore : no files matched pattern")
1025       return
1026      endtry
1027      let s:netrw_curdir       = b:netrw_curdir
1028      let w:netrw_explore_list = getqflist()
1029      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
1030      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1031
1032     elseif starpat == 3
1033      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
1034"      call Decho("..case starpat=".starpat.": build */filepat list  (curdir-only srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1035      let filepat= substitute(dirname,'^\*/','','')
1036      let filepat= substitute(filepat,'^[%#<]','\\&','')
1037"      call Decho("....b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
1038"      call Decho("....filepat<".filepat.">",'~'.expand("<slnum>"))
1039      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
1040      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
1041
1042     elseif starpat == 4
1043      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
1044"      call Decho("..case starpat=".starpat.": build **/filepat list  (recursive descent srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1045      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
1046      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
1047     endif " switch on starpat to build w:netrw_explore_list
1048
1049     let w:netrw_explore_listlen = len(w:netrw_explore_list)
1050"     call Decho("....w:netrw_explore_list<".string(w:netrw_explore_list).">",'~'.expand("<slnum>"))
1051"     call Decho("....w:netrw_explore_listlen=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1052
1053     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1054      keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1055      if has("clipboard") && g:netrw_clipboard
1056"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1057        if @* != keepregstar | sil! let @* = keepregstar | endif
1058        if @+ != keepregplus | sil! let @+ = keepregplus | endif
1059      endif
1060      sil! let @/ = keepregslash
1061"      call Dret("netrw#Explore : no files matched")
1062      return
1063     endif
1064    endif  " if indx ... endif
1065
1066    " NetrwStatusLine support - for exploring support
1067    let w:netrw_explore_indx= indx
1068"    call Decho("....w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1069
1070    " wrap the indx around, but issue a note
1071    if indx >= w:netrw_explore_listlen || indx < 0
1072"     call Decho("....wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")",'~'.expand("<slnum>"))
1073     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1074     let w:netrw_explore_indx= indx
1075     keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
1076    endif
1077
1078    exe "let dirfile= w:netrw_explore_list[".indx."]"
1079"    call Decho("....dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">",'~'.expand("<slnum>"))
1080    let newdir= substitute(dirfile,'/[^/]*$','','e')
1081"    call Decho("....newdir<".newdir.">",'~'.expand("<slnum>"))
1082
1083"    call Decho("....calling LocalBrowseCheck(newdir<".newdir.">)",'~'.expand("<slnum>"))
1084    call netrw#LocalBrowseCheck(newdir)
1085    if !exists("w:netrw_liststyle")
1086     let w:netrw_liststyle= g:netrw_liststyle
1087    endif
1088    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1089     keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1090    else
1091     keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1092    endif
1093    let w:netrw_explore_mtchcnt = indx + 1
1094    let w:netrw_explore_bufnr   = bufnr("%")
1095    let w:netrw_explore_line    = line(".")
1096    keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
1097"    call Decho("....explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line,'~'.expand("<slnum>"))
1098
1099   else
1100"    call Decho("..your vim does not have +path_extra",'~'.expand("<slnum>"))
1101    if !exists("g:netrw_quiet")
1102     keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1103    endif
1104    if has("clipboard") && g:netrw_clipboard
1105"     call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1106      if @* != keepregstar | sil! let @* = keepregstar | endif
1107      if @+ != keepregplus | sil! let @+ = keepregplus | endif
1108    endif
1109    sil! let @/ = keepregslash
1110"    call Dret("netrw#Explore : missing +path_extra")
1111    return
1112   endif
1113
1114  else
1115"   call Decho("..default case: Explore newdir<".dirname.">",'~'.expand("<slnum>"))
1116   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1117    sil! unlet w:netrw_treedict
1118    sil! unlet w:netrw_treetop
1119   endif
1120   let newdir= dirname
1121   if !exists("b:netrw_curdir")
1122    NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1123   else
1124    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
1125   endif
1126  endif
1127
1128  " visual display of **/ **// */ Exploration files
1129"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"),'~'.expand("<slnum>"))
1130"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">",'~'.expand("<slnum>"))
1131  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
1132"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"),'~'.expand("<slnum>"))
1133   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1134    " only update match list when current directory isn't the same as before
1135"    call Decho("only update match list when current directory not the same as before",'~'.expand("<slnum>"))
1136    let s:explore_prvdir = b:netrw_curdir
1137    let s:explore_match  = ""
1138    let dirlen           = strlen(b:netrw_curdir)
1139    if b:netrw_curdir !~ '/$'
1140     let dirlen= dirlen + 1
1141    endif
1142    let prvfname= ""
1143    for fname in w:netrw_explore_list
1144"     call Decho("fname<".fname.">",'~'.expand("<slnum>"))
1145     if fname =~ '^'.b:netrw_curdir
1146      if s:explore_match == ""
1147       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1148      else
1149       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1150      endif
1151     elseif fname !~ '^/' && fname != prvfname
1152      if s:explore_match == ""
1153       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1154      else
1155       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1156      endif
1157     endif
1158     let prvfname= fname
1159    endfor
1160"    call Decho("explore_match<".s:explore_match.">",'~'.expand("<slnum>"))
1161    if has("syntax") && exists("g:syntax_on") && g:syntax_on
1162     exe "2match netrwMarkFile /".s:explore_match."/"
1163    endif
1164   endif
1165   echo "<s-up>==Pexplore  <s-down>==Nexplore"
1166  else
1167   2match none
1168   if exists("s:explore_match")  | unlet s:explore_match  | endif
1169   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
1170   echo " "
1171"   call Decho("cleared explore match list",'~'.expand("<slnum>"))
1172  endif
1173
1174  " since Explore may be used to initialize netrw's browser,
1175  " there's no danger of a late FocusGained event on initialization.
1176  " Consequently, set s:netrw_events to 2.
1177  let s:netrw_events= 2
1178  if has("clipboard") && g:netrw_clipboard
1179"   call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1180   if @* != keepregstar | sil! let @* = keepregstar | endif
1181   if @+ != keepregplus | sil! let @+ = keepregplus | endif
1182  endif
1183  sil! let @/ = keepregslash
1184"  call Dret("netrw#Explore : @/<".@/.">")
1185endfun
1186
1187" ---------------------------------------------------------------------
1188" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
1189fun! netrw#Lexplore(count,rightside,...)
1190"  call Dfunc("netrw#Lexplore(count=".a:count." rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
1191  let curwin= winnr()
1192
1193  if a:0 > 0 && a:1 != ""
1194   " if a netrw window is already on the left-side of the tab
1195   " and a directory has been specified, explore with that
1196   " directory.
1197"   call Decho("case has input argument(s) (a:1<".a:1.">)")
1198   let a1 = expand(a:1)
1199"   call Decho("a:1<".a:1.">  curwin#".curwin,'~'.expand("<slnum>"))
1200   exe "1wincmd w"
1201   if &ft == "netrw"
1202"    call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
1203    exe "Explore ".fnameescape(a1)
1204    exe curwin."wincmd w"
1205    if exists("t:netrw_lexposn")
1206"     call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
1207     unlet t:netrw_lexposn
1208    endif
1209"    call Dret("netrw#Lexplore")
1210    return
1211   endif
1212   exe curwin."wincmd w"
1213  else
1214   let a1= ""
1215"   call Decho("no input arguments")
1216  endif
1217
1218  if exists("t:netrw_lexbufnr")
1219   " check if t:netrw_lexbufnr refers to a netrw window
1220   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1221"   call Decho("lexwinnr= bufwinnr(t:netrw_lexbufnr#".t:netrw_lexbufnr.")=".lexwinnr)
1222  else
1223   let lexwinnr= 0
1224"   call Decho("t:netrw_lexbufnr doesn't exist")
1225  endif
1226"  call Decho("lexwinnr=".lexwinnr,'~'.expand("<slnum>"))
1227
1228  if lexwinnr > 0
1229   " close down netrw explorer window
1230"   call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
1231   exe lexwinnr."wincmd w"
1232   let g:netrw_winsize = -winwidth(0)
1233   let t:netrw_lexposn = winsaveview()
1234"   call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1235"   call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
1236   close
1237   if lexwinnr < curwin
1238    let curwin= curwin - 1
1239   endif
1240   if lexwinnr != curwin
1241    exe curwin."wincmd w"
1242   endif
1243   unlet t:netrw_lexbufnr
1244"   call Decho("unlet t:netrw_lexbufnr")
1245
1246  else
1247   " open netrw explorer window
1248"   call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
1249   exe "1wincmd w"
1250   let keep_altv    = g:netrw_altv
1251   let g:netrw_altv = 0
1252   if a:count != 0
1253    let netrw_winsize   = g:netrw_winsize
1254    let g:netrw_winsize = a:count
1255   endif
1256   let curfile= expand("%")
1257"   call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
1258   exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1259"   call Decho("new buf#".bufnr("%")." win#".winnr())
1260   if a:0 > 0 && a1 != ""
1261"    call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
1262    call netrw#Explore(0,0,0,a1)
1263    exe "Explore ".fnameescape(a1)
1264   elseif curfile =~ '^\a\{3,}://'
1265"    call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
1266    call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
1267   else
1268"    call Decho("case 3: Explore .",'~'.expand("<slnum>"))
1269    call netrw#Explore(0,0,0,".")
1270   endif
1271   if a:count != 0
1272    let g:netrw_winsize = netrw_winsize
1273   endif
1274   setlocal winfixwidth
1275   let g:netrw_altv     = keep_altv
1276   let t:netrw_lexbufnr = bufnr("%")
1277   " done to prevent build-up of hidden buffers due to quitting and re-invocation of :Lexplore.
1278   " Since the intended use of :Lexplore is to have an always-present explorer window, the extra
1279   " effort to mis-use :Lex is warranted.
1280   set bh=wipe
1281"   call Decho("let t:netrw_lexbufnr=".t:netrw_lexbufnr)
1282"   call Decho("t:netrw_lexposn".(exists("t:netrw_lexposn")? string(t:netrw_lexposn) : " n/a"))
1283   if exists("t:netrw_lexposn")
1284"    call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1285"    call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1286    call winrestview(t:netrw_lexposn)
1287    unlet t:netrw_lexposn
1288   endif
1289  endif
1290
1291  " set up default window for editing via <cr>
1292  if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
1293   if a:rightside
1294    let g:netrw_chgwin= 1
1295   else
1296    let g:netrw_chgwin= 2
1297   endif
1298"   call Decho("let g:netrw_chgwin=".g:netrw_chgwin)
1299  endif
1300
1301"  call Dret("netrw#Lexplore")
1302endfun
1303
1304" ---------------------------------------------------------------------
1305" netrw#Clean: remove netrw {{{2
1306" supports :NetrwClean  -- remove netrw from first directory on runtimepath
1307"          :NetrwClean! -- remove netrw from all directories on runtimepath
1308fun! netrw#Clean(sys)
1309"  call Dfunc("netrw#Clean(sys=".a:sys.")")
1310
1311  if a:sys
1312   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
1313  else
1314   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
1315  endif
1316"  call Decho("choice=".choice,'~'.expand("<slnum>"))
1317  let diddel= 0
1318  let diddir= ""
1319
1320  if choice == 1
1321   for dir in split(&rtp,',')
1322    if filereadable(dir."/plugin/netrwPlugin.vim")
1323"     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1324     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
1325     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1326     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
1327     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
1328     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
1329     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
1330     let diddir= dir
1331     let diddel= diddel + 1
1332     if !a:sys|break|endif
1333    endif
1334   endfor
1335  endif
1336
1337   echohl WarningMsg
1338  if diddel == 0
1339   echomsg "netrw is either not installed or not removable"
1340  elseif diddel == 1
1341   echomsg "removed one copy of netrw from <".diddir.">"
1342  else
1343   echomsg "removed ".diddel." copies of netrw"
1344  endif
1345   echohl None
1346
1347"  call Dret("netrw#Clean")
1348endfun
1349
1350" ---------------------------------------------------------------------
1351" netrw#MakeTgt: make a target out of the directory name provided {{{2
1352fun! netrw#MakeTgt(dname)
1353"  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1354   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
1355  let svpos               = winsaveview()
1356"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1357  let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
1358"  call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
1359  if s:netrwmftgt_islocal
1360   let netrwmftgt= simplify(a:dname)
1361  else
1362   let netrwmftgt= a:dname
1363  endif
1364  if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
1365   " re-selected target, so just clear it
1366   unlet s:netrwmftgt s:netrwmftgt_islocal
1367  else
1368   let s:netrwmftgt= netrwmftgt
1369  endif
1370  if g:netrw_fastbrowse <= 1
1371   call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
1372  endif
1373"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
1374  call winrestview(svpos)
1375"  call Dret("netrw#MakeTgt")
1376endfun
1377
1378" ---------------------------------------------------------------------
1379" netrw#Obtain: {{{2
1380"   netrw#Obtain(islocal,fname[,tgtdirectory])
1381"     islocal=0  obtain from remote source
1382"            =1  obtain from local source
1383"     fname  :   a filename or a list of filenames
1384"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
1385fun! netrw#Obtain(islocal,fname,...)
1386"  call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
1387  " NetrwStatusLine support - for obtaining support
1388
1389  if type(a:fname) == 1
1390   let fnamelist= [ a:fname ]
1391  elseif type(a:fname) == 3
1392   let fnamelist= a:fname
1393  else
1394   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1395"   call Dret("netrw#Obtain")
1396   return
1397  endif
1398"  call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
1399  if a:0 > 0
1400   let tgtdir= a:1
1401  else
1402   let tgtdir= getcwd()
1403  endif
1404"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
1405
1406  if exists("b:netrw_islocal") && b:netrw_islocal
1407   " obtain a file from local b:netrw_curdir to (local) tgtdir
1408"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1409   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1410    let topath= s:ComposePath(tgtdir,"")
1411    if (has("win32") || has("win95") || has("win64") || has("win16"))
1412     " transfer files one at time
1413"     call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1414     for fname in fnamelist
1415"      call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1416      call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1417      if v:shell_error != 0
1418       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1419"       call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1420       return
1421      endif
1422     endfor
1423    else
1424     " transfer files with one command
1425"     call Decho("transfer files with one command",'~'.expand("<slnum>"))
1426     let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1427"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1428     call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".filelist." ".s:ShellEscape(topath))
1429     if v:shell_error != 0
1430      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1431"      call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1432      return
1433     endif
1434    endif
1435   elseif !exists("b:netrw_curdir")
1436    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
1437   else
1438    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
1439   endif
1440
1441  else
1442   " obtain files from remote b:netrw_curdir to local tgtdir
1443"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1444   if type(a:fname) == 1
1445    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
1446   endif
1447   call s:NetrwMethod(b:netrw_curdir)
1448
1449   if b:netrw_method == 4
1450    " obtain file using scp
1451"    call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1452    if exists("g:netrw_port") && g:netrw_port != ""
1453     let useport= " ".g:netrw_scpport." ".g:netrw_port
1454    else
1455     let useport= ""
1456    endif
1457    if b:netrw_fname =~ '/'
1458     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1459    else
1460     let path= ""
1461    endif
1462    let filelist= join(map(deepcopy(fnamelist),'escape(s:ShellEscape(g:netrw_machine.":".path.v:val,1)," ")'))
1463    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
1464
1465   elseif b:netrw_method == 2
1466    " obtain file using ftp + .netrc
1467"     call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1468     call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1469     let tmpbufnr= bufnr("%")
1470     setl ff=unix
1471     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1472      NetrwKeepj put =g:netrw_ftpmode
1473"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1474     endif
1475
1476     if exists("b:netrw_fname") && b:netrw_fname != ""
1477      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1478"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1479     endif
1480
1481     if exists("g:netrw_ftpextracmd")
1482      NetrwKeepj put =g:netrw_ftpextracmd
1483"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1484     endif
1485     for fname in fnamelist
1486      call setline(line("$")+1,'get "'.fname.'"')
1487"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1488     endfor
1489     if exists("g:netrw_port") && g:netrw_port != ""
1490      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1491     else
1492      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1493     endif
1494     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1495     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1496      let debugkeep= &debug
1497      setl debug=msg
1498      call netrw#ErrorMsg(s:ERROR,getline(1),4)
1499      let &debug= debugkeep
1500     endif
1501
1502   elseif b:netrw_method == 3
1503    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1504"    call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1505    call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1506    let tmpbufnr= bufnr("%")
1507    setl ff=unix
1508
1509    if exists("g:netrw_port") && g:netrw_port != ""
1510     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1511"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1512    else
1513     NetrwKeepj put ='open '.g:netrw_machine
1514"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1515    endif
1516
1517    if exists("g:netrw_uid") && g:netrw_uid != ""
1518     if exists("g:netrw_ftp") && g:netrw_ftp == 1
1519      NetrwKeepj put =g:netrw_uid
1520"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1521      if exists("s:netrw_passwd") && s:netrw_passwd != ""
1522       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1523      endif
1524"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1525     elseif exists("s:netrw_passwd")
1526      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1527"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1528     endif
1529    endif
1530
1531    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1532     NetrwKeepj put =g:netrw_ftpmode
1533"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1534    endif
1535
1536    if exists("b:netrw_fname") && b:netrw_fname != ""
1537     NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1538"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1539    endif
1540
1541    if exists("g:netrw_ftpextracmd")
1542     NetrwKeepj put =g:netrw_ftpextracmd
1543"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1544    endif
1545
1546    if exists("g:netrw_ftpextracmd")
1547     NetrwKeepj put =g:netrw_ftpextracmd
1548"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1549    endif
1550    for fname in fnamelist
1551     NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1552    endfor
1553"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1554
1555    " perform ftp:
1556    " -i       : turns off interactive prompting from ftp
1557    " -n  unix : DON'T use <.netrc>, even though it exists
1558    " -n  win32: quit being obnoxious about password
1559    "  Note: using "_dd to delete to the black hole register; avoids messing up @@
1560    NetrwKeepj norm! 1G"_dd
1561    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1562    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1563    if getline(1) !~ "^$"
1564"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1565     if !exists("g:netrw_quiet")
1566      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1567     endif
1568    endif
1569
1570   elseif b:netrw_method == 9
1571    " obtain file using sftp
1572"    call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1573    if a:fname =~ '/'
1574     let localfile= substitute(a:fname,'^.*/','','')
1575    else
1576     let localfile= a:fname
1577    endif
1578    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))
1579
1580   elseif !exists("b:netrw_method") || b:netrw_method < 0
1581    " probably a badly formed url; protocol not recognized
1582"    call Dret("netrw#Obtain : unsupported method")
1583    return
1584
1585   else
1586    " protocol recognized but not supported for Obtain (yet?)
1587    if !exists("g:netrw_quiet")
1588     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1589    endif
1590"    call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1591    return
1592   endif
1593
1594   " restore status line
1595   if type(a:fname) == 1 && exists("s:netrw_users_stl")
1596    NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
1597   endif
1598
1599  endif
1600
1601  " cleanup
1602  if exists("tmpbufnr")
1603   if bufnr("%") != tmpbufnr
1604    exe tmpbufnr."bw!"
1605   else
1606    q!
1607   endif
1608  endif
1609
1610"  call Dret("netrw#Obtain")
1611endfun
1612
1613" ---------------------------------------------------------------------
1614" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1615fun! netrw#Nread(mode,fname)
1616"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
1617  let svpos= winsaveview()
1618"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1619  call netrw#NetRead(a:mode,a:fname)
1620"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1621  call winrestview(svpos)
1622
1623  if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
1624   if exists("w:netrw_bannercnt")
1625    " start with cursor just after the banner
1626    exe w:netrw_bannercnt
1627   endif
1628  endif
1629"  call Dret("netrw#Nread")
1630endfun
1631
1632" ------------------------------------------------------------------------
1633" s:NetrwOptionsSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1634"             Options get restored by s:NetrwOptionsRestore()
1635"
1636"             Option handling:
1637"              * save user's options                                     (s:NetrwOptionsSave)
1638"              * set netrw-safe options                                  (s:NetrwOptionsSafe)
1639"                - change an option only when user option != safe option (s:netrwSetSafeSetting)
1640"              * restore user's options                                  (s:netrwOPtionsRestore)
1641"                - restore a user option when != safe option             (s:NetrwRestoreSetting)
1642"             vt: (variable type) normally its either "w:" or "s:"
1643fun! s:NetrwOptionsSave(vt)
1644"  call Dfunc("s:NetrwOptionsSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1645"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1646"  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>"))
1647"  call Decho("(s:NetrwOptionsSave) lines=".&lines)
1648
1649  if !exists("{a:vt}netrw_optionsave")
1650   let {a:vt}netrw_optionsave= 1
1651  else
1652"   call Dret("s:NetrwOptionsSave : options already saved")
1653   return
1654  endif
1655"  call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
1656
1657  " Save current settings and current directory
1658"  call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
1659  let s:yykeep          = @@
1660  if exists("&l:acd")|let {a:vt}netrw_acdkeep  = &l:acd|endif
1661  let {a:vt}netrw_aikeep    = &l:ai
1662  let {a:vt}netrw_awkeep    = &l:aw
1663  let {a:vt}netrw_bhkeep    = &l:bh
1664  let {a:vt}netrw_blkeep    = &l:bl
1665  let {a:vt}netrw_btkeep    = &l:bt
1666  let {a:vt}netrw_bombkeep  = &l:bomb
1667  let {a:vt}netrw_cedit     = &cedit
1668  let {a:vt}netrw_cikeep    = &l:ci
1669  let {a:vt}netrw_cinkeep   = &l:cin
1670  let {a:vt}netrw_cinokeep  = &l:cino
1671  let {a:vt}netrw_comkeep   = &l:com
1672  let {a:vt}netrw_cpokeep   = &l:cpo
1673  let {a:vt}netrw_cuckeep   = &l:cuc
1674  let {a:vt}netrw_culkeep   = &l:cul
1675"  call Decho("(s:NetrwOptionsSave) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
1676  let {a:vt}netrw_diffkeep  = &l:diff
1677  let {a:vt}netrw_fenkeep   = &l:fen
1678  if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
1679   let {a:vt}netrw_ffkeep    = &l:ff
1680  endif
1681  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
1682  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
1683  let {a:vt}netrw_gokeep    = &l:go           " guioptions
1684  let {a:vt}netrw_hidkeep   = &l:hidden
1685  let {a:vt}netrw_imkeep    = &l:im
1686  let {a:vt}netrw_iskkeep   = &l:isk
1687  let {a:vt}netrw_lines     = &lines
1688  let {a:vt}netrw_lskeep    = &l:ls
1689  let {a:vt}netrw_makeep    = &l:ma
1690  let {a:vt}netrw_magickeep = &l:magic
1691  let {a:vt}netrw_modkeep   = &l:mod
1692  let {a:vt}netrw_nukeep    = &l:nu
1693  let {a:vt}netrw_rnukeep   = &l:rnu
1694  let {a:vt}netrw_repkeep   = &l:report
1695  let {a:vt}netrw_rokeep    = &l:ro
1696  let {a:vt}netrw_selkeep   = &l:sel
1697  let {a:vt}netrw_spellkeep = &l:spell
1698  if !g:netrw_use_noswf
1699   let {a:vt}netrw_swfkeep  = &l:swf
1700  endif
1701  let {a:vt}netrw_tskeep    = &l:ts
1702  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
1703  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
1704  let {a:vt}netrw_wrapkeep  = &l:wrap
1705  let {a:vt}netrw_writekeep = &l:write
1706
1707  " save a few selected netrw-related variables
1708"  call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
1709  if g:netrw_keepdir
1710   let {a:vt}netrw_dirkeep  = getcwd()
1711"   call Decho("saving to ".a:vt."netrw_dirkeep<".{a:vt}netrw_dirkeep.">",'~'.expand("<slnum>"))
1712  endif
1713  if has("clipboard") && g:netrw_clipboard
1714   sil! let {a:vt}netrw_starkeep = @*
1715   sil! let {a:vt}netrw_pluskeep = @+
1716  endif
1717  sil! let {a:vt}netrw_slashkeep= @/
1718
1719"  call Decho("(s:NetrwOptionsSave) lines=".&lines)
1720"  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>"))
1721"  call Dret("s:NetrwOptionsSave : tab#".tabpagenr()." win#".winnr())
1722endfun
1723
1724" ---------------------------------------------------------------------
1725" s:NetrwOptionsSafe: sets options to help netrw do its job {{{2
1726"                     Use  s:NetrwSaveOptions() to save user settings
1727"                     Use  s:NetrwOptionsRestore() to restore user settings
1728fun! s:NetrwOptionsSafe(islocal)
1729"  call Dfunc("s:NetrwOptionsSafe(islocal=".a:islocal.") win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1730"  call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1731"  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>"))
1732  if exists("+acd") | call s:NetrwSetSafeSetting("&l:acd",0)|endif
1733  call s:NetrwSetSafeSetting("&l:ai",0)
1734  call s:NetrwSetSafeSetting("&l:aw",0)
1735  call s:NetrwSetSafeSetting("&l:bl",0)
1736  call s:NetrwSetSafeSetting("&l:bomb",0)
1737  if a:islocal
1738   call s:NetrwSetSafeSetting("&l:bt","nofile")
1739  else
1740   call s:NetrwSetSafeSetting("&l:bt","acwrite")
1741  endif
1742  call s:NetrwSetSafeSetting("&l:ci",0)
1743  call s:NetrwSetSafeSetting("&l:cin",0)
1744  if g:netrw_fastbrowse > a:islocal
1745   call s:NetrwSetSafeSetting("&l:bh","hide")
1746  else
1747   call s:NetrwSetSafeSetting("&l:bh","delete")
1748  endif
1749  call s:NetrwSetSafeSetting("&l:cino","")
1750  call s:NetrwSetSafeSetting("&l:com","")
1751  if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif
1752  if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif
1753  setl fo=nroql2
1754  " call s:NetrwSetSafeSetting("&go","begmr")
1755  if &go =~ '\ca' | call s:NetrwSetSafeSetting("&go",substitute(&go,'\ca','','g')) | endif
1756  call s:NetrwSetSafeSetting("&l:hid",0)
1757  call s:NetrwSetSafeSetting("&l:im",0)
1758  setl isk+=@ isk+=* isk+=/
1759  call s:NetrwSetSafeSetting("&l:magic",1)
1760  if g:netrw_use_noswf
1761   call s:NetrwSetSafeSetting("swf",0)
1762  endif
1763  call s:NetrwSetSafeSetting("&l:report",10000)
1764  call s:NetrwSetSafeSetting("&l:sel","inclusive")
1765  call s:NetrwSetSafeSetting("&l:spell",0)
1766  call s:NetrwSetSafeSetting("&l:tw",0)
1767  call s:NetrwSetSafeSetting("&l:wig","")
1768  setl cedit&
1769
1770  " set up cuc and cul based on g:netrw_cursor and listing style
1771  " COMBAK -- cuc cul related
1772  call s:NetrwCursor(0)
1773
1774  " allow the user to override safe options
1775"  call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
1776  if &ft == "netrw"
1777"   call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1778   keepalt NetrwKeepj doau FileType netrw
1779  endif
1780
1781"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1782"  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>"))
1783"  call Dret("s:NetrwOptionsSafe")
1784endfun
1785
1786" ---------------------------------------------------------------------
1787" s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2
1788fun! s:NetrwOptionsRestore(vt)
1789"  call Dfunc("s:NetrwOptionsRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
1790"  call Decho("(s:NetrwOptionsRestore) lines=".&lines)
1791"  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>"))
1792  if !exists("{a:vt}netrw_optionsave")
1793"   call Decho("case ".a:vt."netrw_optionsave : doesn't exist",'~'.expand("<slnum>"))
1794"   call Decho("..doing filetype detect anyway")
1795   filetype detect
1796"   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>"))
1797"   call Decho("..ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1798"   call Dret("s:NetrwOptionsRestore : ".a:vt."netrw_optionsave doesn't exist")
1799   return
1800  endif
1801  unlet {a:vt}netrw_optionsave
1802
1803  if exists("+acd")
1804   if exists("{a:vt}netrw_acdkeep")
1805"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1806    let curdir = getcwd()
1807    let &l:acd = {a:vt}netrw_acdkeep
1808    unlet {a:vt}netrw_acdkeep
1809    if &l:acd
1810     call s:NetrwLcd(curdir)
1811    endif
1812   endif
1813  endif
1814"  call Decho("(s:NetrwOptionsRestore) #1 lines=".&lines)
1815  call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai")
1816  call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw")
1817  call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl")
1818  call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt")
1819  call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb")
1820"  call Decho("(s:NetrwOptionsRestore) #2 lines=".&lines)
1821  call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit")
1822  call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci")
1823  call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin")
1824  call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino")
1825  call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com")
1826"  call Decho("(s:NetrwOptionsRestore) #3 lines=".&lines)
1827  call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo")
1828  call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff")
1829  call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen")
1830  if exists("g:netrw_ffkeep") && g:netrw_ffkeep
1831   call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff")
1832  endif
1833"  call Decho("(s:NetrwOptionsRestore) #4 lines=".&lines)
1834  call s:NetrwRestoreSetting(a:vt."netrw_fokeep"   ,"&l:fo")
1835  call s:NetrwRestoreSetting(a:vt."netrw_gdkeep"   ,"&l:gd")
1836  call s:NetrwRestoreSetting(a:vt."netrw_gokeep"   ,"&l:go")
1837  call s:NetrwRestoreSetting(a:vt."netrw_hidkeep"  ,"&l:hidden")
1838"  call Decho("(s:NetrwOptionsRestore) #5 lines=".&lines)
1839  call s:NetrwRestoreSetting(a:vt."netrw_imkeep"   ,"&l:im")
1840  call s:NetrwRestoreSetting(a:vt."netrw_iskkeep"  ,"&l:isk")
1841"  call Decho("(s:NetrwOptionsRestore) #6 lines=".&lines)
1842  call s:NetrwRestoreSetting(a:vt."netrw_lines"    ,"&lines")
1843"  call Decho("(s:NetrwOptionsRestore) #7 lines=".&lines)
1844  call s:NetrwRestoreSetting(a:vt."netrw_lskeep"   ,"&l:ls")
1845  call s:NetrwRestoreSetting(a:vt."netrw_makeep"   ,"&l:ma")
1846  call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic")
1847  call s:NetrwRestoreSetting(a:vt."netrw_modkeep"  ,"&l:mod")
1848  call s:NetrwRestoreSetting(a:vt."netrw_nukeep"   ,"&l:nu")
1849"  call Decho("(s:NetrwOptionsRestore) #8 lines=".&lines)
1850  call s:NetrwRestoreSetting(a:vt."netrw_rnukeep"  ,"&l:rnu")
1851  call s:NetrwRestoreSetting(a:vt."netrw_repkeep"  ,"&l:report")
1852  call s:NetrwRestoreSetting(a:vt."netrw_rokeep"   ,"&l:ro")
1853  call s:NetrwRestoreSetting(a:vt."netrw_selkeep"  ,"&l:sel")
1854"  call Decho("(s:NetrwOptionsRestore) #9 lines=".&lines)
1855  call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell")
1856  call s:NetrwRestoreSetting(a:vt."netrw_twkeep"   ,"&l:tw")
1857  call s:NetrwRestoreSetting(a:vt."netrw_wigkeep"  ,"&l:wig")
1858  call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep" ,"&l:wrap")
1859  call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write")
1860"  call Decho("(s:NetrwOptionsRestore) #10 lines=".&lines)
1861  call s:NetrwRestoreSetting("s:yykeep","@@")
1862  " former problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1863  " Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces
1864  "        rather than by appending a tab which previously was using "&ts" to set the desired spacing.  (Sep 28, 2018)
1865  call s:NetrwRestoreSetting(a:vt."netrw_tskeep","&l:ts")
1866
1867  if exists("{a:vt}netrw_swfkeep")
1868   if &directory == ""
1869    " user hasn't specified a swapfile directory;
1870    " netrw will temporarily set the swapfile directory
1871    " to the current directory as returned by getcwd().
1872    let &l:directory= getcwd()
1873    sil! let &l:swf = {a:vt}netrw_swfkeep
1874    setl directory=
1875    unlet {a:vt}netrw_swfkeep
1876   elseif &l:swf != {a:vt}netrw_swfkeep
1877    if !g:netrw_use_noswf
1878     " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1879     sil! let &l:swf= {a:vt}netrw_swfkeep
1880    endif
1881    unlet {a:vt}netrw_swfkeep
1882   endif
1883  endif
1884  if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
1885   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1886   if exists("{a:vt}netrw_dirkeep")
1887    call s:NetrwLcd(dirkeep)
1888    unlet {a:vt}netrw_dirkeep
1889   endif
1890  endif
1891  if has("clipboard") && g:netrw_clipboard
1892"   call Decho("has clipboard",'~'.expand("<slnum>"))
1893   call s:NetrwRestoreSetting(a:vt."netrw_starkeep","@*")
1894   call s:NetrwRestoreSetting(a:vt."netrw_pluskeep","@+")
1895  endif
1896  call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/")
1897
1898"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1899"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
1900"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1901"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
1902"  call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
1903  " Moved the filetype detect here from NetrwGetFile() because remote files
1904  " were having their filetype detect-generated settings overwritten by
1905  " NetrwOptionRestore.
1906  if &ft != "netrw"
1907"   call Decho("before: filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1908   filetype detect
1909"   call Decho("after : filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1910  endif
1911"  call Decho("(s:NetrwOptionsRestore) lines=".&lines)
1912"  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>"))
1913"  call Dret("s:NetrwOptionsRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
1914endfun
1915
1916" ---------------------------------------------------------------------
1917" s:NetrwSetSafeSetting: sets an option to a safe setting {{{2
1918"                        but only when the options' value and the safe setting differ
1919"                        Doing this means that netrw will not come up as having changed a
1920"                        setting last when it really didn't actually change it.
1921"
1922"                        Called from s:NetrwOptionsSafe
1923"                          ex. call s:NetrwSetSafeSetting("&l:sel","inclusive")
1924fun! s:NetrwSetSafeSetting(setting,safesetting)
1925"  call Dfunc("s:NetrwSetSafeSetting(setting<".a:setting."> safesetting<".a:safesetting.">)")
1926
1927  if a:setting =~ '^&'
1928"   call Decho("fyi: a:setting starts with &")
1929   exe "let settingval= ".a:setting
1930"   call Decho("fyi: settingval<".settingval.">")
1931
1932   if settingval != a:safesetting
1933"    call Decho("set setting<".a:setting."> to option value<".a:safesetting.">")
1934    if type(a:safesetting) == 0
1935     exe "let ".a:setting."=".a:safesetting
1936    elseif type(a:safesetting) == 1
1937     exe "let ".a:setting."= '".a:safesetting."'"
1938    else
1939     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:setting." with a safesetting of type#".type(a:safesetting),105)
1940    endif
1941   endif
1942  endif
1943
1944"  call Dret("s:NetrwSetSafeSetting")
1945endfun
1946
1947" ------------------------------------------------------------------------
1948" s:NetrwRestoreSetting: restores specified setting using associated keepvar, {{{2
1949"                        but only if the setting value differs from the associated keepvar.
1950"                        Doing this means that netrw will not come up as having changed a
1951"                        setting last when it really didn't actually change it.
1952"
1953"                        Used by s:NetrwOptionsRestore() to restore each netrw-senstive setting
1954"                        keepvars are set up by s:NetrwOptionsSave
1955fun! s:NetrwRestoreSetting(keepvar,setting)
1956"""  call Dfunc("s:NetrwRestoreSetting(a:keepvar<".a:keepvar."> a:setting<".a:setting.">)")
1957
1958  " typically called from s:NetrwOptionsRestore
1959  "   call s:NetrwRestoreSettings(keep-option-variable-name,'associated-option')
1960  "   ex. call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
1961  "  Restores option (but only if different) from a:keepvar
1962  if exists(a:keepvar)
1963   exe "let keepvarval= ".a:keepvar
1964   exe "let setting= ".a:setting
1965
1966""   call Decho("fyi: a:keepvar<".a:keepvar."> exists")
1967""   call Decho("fyi: keepvarval=".keepvarval)
1968""   call Decho("fyi: a:setting<".a:setting."> setting<".setting.">")
1969
1970   if setting != keepvarval
1971""    call Decho("restore setting<".a:setting."> (currently=".setting.") to keepvarval<".keepvarval.">")
1972    if type(a:setting) == 0
1973     exe "let ".a:setting."= ".keepvarval
1974    elseif type(a:setting) == 1
1975     exe "let ".a:setting."= '".substitute(keepvarval,"'","''","g")."'"
1976    else
1977     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105)
1978    endif
1979   endif
1980
1981   exe "unlet ".a:keepvar
1982  endif
1983
1984""  call Dret("s:NetrwRestoreSetting")
1985endfun
1986
1987" ---------------------------------------------------------------------
1988" NetrwStatusLine: {{{2
1989fun! NetrwStatusLine()
1990
1991" vvv NetrwStatusLine() debugging vvv
1992"  let g:stlmsg=""
1993"  if !exists("w:netrw_explore_bufnr")
1994"   let g:stlmsg="!X<explore_bufnr>"
1995"  elseif w:netrw_explore_bufnr != bufnr("%")
1996"   let g:stlmsg="explore_bufnr!=".bufnr("%")
1997"  endif
1998"  if !exists("w:netrw_explore_line")
1999"   let g:stlmsg=" !X<explore_line>"
2000"  elseif w:netrw_explore_line != line(".")
2001"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
2002"  endif
2003"  if !exists("w:netrw_explore_list")
2004"   let g:stlmsg=" !X<explore_list>"
2005"  endif
2006" ^^^ NetrwStatusLine() debugging ^^^
2007
2008  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")
2009   " restore user's status line
2010   let &stl        = s:netrw_users_stl
2011   let &laststatus = s:netrw_users_ls
2012   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
2013   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
2014   return ""
2015  else
2016   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
2017  endif
2018endfun
2019
2020" ===============================
2021"  Netrw Transfer Functions: {{{1
2022" ===============================
2023
2024" ------------------------------------------------------------------------
2025" netrw#NetRead: responsible for reading a file over the net {{{2
2026"   mode: =0 read remote file and insert before current line
2027"         =1 read remote file and insert after current line
2028"         =2 replace with remote file
2029"         =3 obtain file, but leave in temporary format
2030fun! netrw#NetRead(mode,...)
2031"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
2032
2033  " NetRead: save options {{{3
2034  call s:NetrwOptionsSave("w:")
2035  call s:NetrwOptionsSafe(0)
2036  call s:RestoreCursorline()
2037  " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
2038  " However, this setting is not wanted for a remote editing session.  The buffer should be "nofile", still.
2039  setl bl
2040"  call Decho("buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
2041
2042  " NetRead: interpret mode into a readcmd {{{3
2043  if     a:mode == 0 " read remote file before current line
2044   let readcmd = "0r"
2045  elseif a:mode == 1 " read file after current line
2046   let readcmd = "r"
2047  elseif a:mode == 2 " replace with remote file
2048   let readcmd = "%r"
2049  elseif a:mode == 3 " skip read of file (leave as temporary)
2050   let readcmd = "t"
2051  else
2052   exe a:mode
2053   let readcmd = "r"
2054  endif
2055  let ichoice = (a:0 == 0)? 0 : 1
2056"  call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
2057
2058  " NetRead: get temporary filename {{{3
2059  let tmpfile= s:GetTempfile("")
2060  if tmpfile == ""
2061"   call Dret("netrw#NetRead : unable to get a tempfile!")
2062   return
2063  endif
2064
2065  while ichoice <= a:0
2066
2067   " attempt to repeat with previous host-file-etc
2068   if exists("b:netrw_lastfile") && a:0 == 0
2069"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2070    let choice = b:netrw_lastfile
2071    let ichoice= ichoice + 1
2072
2073   else
2074    exe "let choice= a:" . ichoice
2075"    call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
2076
2077    if match(choice,"?") == 0
2078     " give help
2079     echomsg 'NetRead Usage:'
2080     echomsg ':Nread machine:path                         uses rcp'
2081     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
2082     echomsg ':Nread "machine id password path"           uses ftp'
2083     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
2084     echomsg ':Nread fetch://machine/path                 uses fetch'
2085     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2086     echomsg ':Nread http://[user@]machine/path           uses http  wget'
2087     echomsg ':Nread file:///path           		  uses elinks'
2088     echomsg ':Nread https://[user@]machine/path          uses http  wget'
2089     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
2090     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
2091     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
2092     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
2093     sleep 4
2094     break
2095
2096    elseif match(choice,'^"') != -1
2097     " Reconstruct Choice if choice starts with '"'
2098"     call Decho("reconstructing choice",'~'.expand("<slnum>"))
2099     if match(choice,'"$') != -1
2100      " case "..."
2101      let choice= strpart(choice,1,strlen(choice)-2)
2102     else
2103       "  case "... ... ..."
2104      let choice      = strpart(choice,1,strlen(choice)-1)
2105      let wholechoice = ""
2106
2107      while match(choice,'"$') == -1
2108       let wholechoice = wholechoice . " " . choice
2109       let ichoice     = ichoice + 1
2110       if ichoice > a:0
2111       	if !exists("g:netrw_quiet")
2112	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
2113	endif
2114"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
2115        return
2116       endif
2117       let choice= a:{ichoice}
2118      endwhile
2119      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2120     endif
2121    endif
2122   endif
2123
2124"   call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
2125   let ichoice= ichoice + 1
2126
2127   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
2128   call s:NetrwMethod(choice)
2129   if !exists("b:netrw_method") || b:netrw_method < 0
2130"    call Dret("netrw#NetRead : unsupported method")
2131    return
2132   endif
2133   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
2134
2135   " Check whether or not NetrwBrowse() should be handling this request
2136"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
2137   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
2138"    call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
2139    NetrwKeepj call s:NetrwBrowse(0,choice)
2140"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
2141    return
2142   endif
2143
2144   " ============
2145   " NetRead: Perform Protocol-Based Read {{{3
2146   " ===========================
2147   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2148    echo "(netrw) Processing your read request..."
2149   endif
2150
2151   ".........................................
2152   " NetRead: (rcp)  NetRead Method #1 {{{3
2153   if  b:netrw_method == 1 " read with rcp
2154"    call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
2155   " ER: nothing done with g:netrw_uid yet?
2156   " ER: on Win2K" rcp machine[.user]:file tmpfile
2157   " ER: when machine contains '.' adding .user is required (use $USERNAME)
2158   " ER: the tmpfile is full path: rcp sees C:\... as host C
2159   if s:netrw_has_nt_rcp == 1
2160    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2161     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2162    else
2163     " Any way needed it machine contains a '.'
2164     let uid_machine = g:netrw_machine .'.'. $USERNAME
2165    endif
2166   else
2167    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2168     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2169    else
2170     let uid_machine = g:netrw_machine
2171    endif
2172   endif
2173   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))
2174   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2175   let b:netrw_lastfile = choice
2176
2177   ".........................................
2178   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
2179   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
2180"     call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2181     let netrw_fname= b:netrw_fname
2182     NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2183     let filtbuf= bufnr("%")
2184     setl ff=unix
2185     NetrwKeepj put =g:netrw_ftpmode
2186"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2187     if exists("g:netrw_ftpextracmd")
2188      NetrwKeepj put =g:netrw_ftpextracmd
2189"      call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2190     endif
2191     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2192"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2193     if exists("g:netrw_port") && g:netrw_port != ""
2194      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2195     else
2196      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2197     endif
2198     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2199     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2200      let debugkeep = &debug
2201      setl debug=msg
2202      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2203      let &debug    = debugkeep
2204     endif
2205     call s:SaveBufVars()
2206     keepj bd!
2207     if bufname("%") == "" && getline("$") == "" && line('$') == 1
2208      " needed when one sources a file in a nolbl setting window via ftp
2209      q!
2210     endif
2211     call s:RestoreBufVars()
2212     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2213     let b:netrw_lastfile = choice
2214
2215   ".........................................
2216   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
2217   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
2218    " Construct execution string (four lines) which will be passed through filter
2219"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2220    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2221    NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2222    let filtbuf= bufnr("%")
2223    setl ff=unix
2224    if exists("g:netrw_port") && g:netrw_port != ""
2225     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2226"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2227    else
2228     NetrwKeepj put ='open '.g:netrw_machine
2229"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2230    endif
2231
2232    if exists("g:netrw_uid") && g:netrw_uid != ""
2233     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2234      NetrwKeepj put =g:netrw_uid
2235"       call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2236      if exists("s:netrw_passwd")
2237       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2238      endif
2239"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2240     elseif exists("s:netrw_passwd")
2241      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2242"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2243     endif
2244    endif
2245
2246    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2247     NetrwKeepj put =g:netrw_ftpmode
2248"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2249    endif
2250    if exists("g:netrw_ftpextracmd")
2251     NetrwKeepj put =g:netrw_ftpextracmd
2252"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2253    endif
2254    NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2255"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2256
2257    " perform ftp:
2258    " -i       : turns off interactive prompting from ftp
2259    " -n  unix : DON'T use <.netrc>, even though it exists
2260    " -n  win32: quit being obnoxious about password
2261    NetrwKeepj norm! 1G"_dd
2262    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2263    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2264    if getline(1) !~ "^$"
2265"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2266     if !exists("g:netrw_quiet")
2267      call netrw#ErrorMsg(s:ERROR,getline(1),5)
2268     endif
2269    endif
2270    call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2271    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2272    let b:netrw_lastfile = choice
2273
2274   ".........................................
2275   " NetRead: (scp) NetRead Method #4 {{{3
2276   elseif     b:netrw_method  == 4	" read with scp
2277"    call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2278    if exists("g:netrw_port") && g:netrw_port != ""
2279     let useport= " ".g:netrw_scpport." ".g:netrw_port
2280    else
2281     let useport= ""
2282    endif
2283    " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2284    " This is workaround to avoid mis-handle windows local-path:
2285    if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
2286      let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2287    else
2288      let tmpfile_get = tmpfile
2289    endif
2290    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))
2291    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2292    let b:netrw_lastfile = choice
2293
2294   ".........................................
2295   " NetRead: (http) NetRead Method #5 (wget) {{{3
2296   elseif     b:netrw_method  == 5
2297"    call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2298    if g:netrw_http_cmd == ""
2299     if !exists("g:netrw_quiet")
2300      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2301     endif
2302"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2303     return
2304    endif
2305
2306    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2307     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2308"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2309     if exists("g:netrw_http_xcmd")
2310      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))
2311     else
2312      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))
2313     endif
2314     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2315
2316    else
2317     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2318"     call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2319     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2320     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2321"     call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2322"     call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2323     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))
2324     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2325"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2326     exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2327    endif
2328    let b:netrw_lastfile = choice
2329"    call Decho("setl ro",'~'.expand("<slnum>"))
2330    setl ro nomod
2331
2332   ".........................................
2333   " NetRead: (dav) NetRead Method #6 {{{3
2334   elseif     b:netrw_method  == 6
2335"    call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2336
2337    if !executable(g:netrw_dav_cmd)
2338     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2339"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2340     return
2341    endif
2342    if g:netrw_dav_cmd =~ "curl"
2343     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2344    else
2345     " Construct execution string (four lines) which will be passed through filter
2346     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2347     new
2348     setl ff=unix
2349     if exists("g:netrw_port") && g:netrw_port != ""
2350      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2351     else
2352      NetrwKeepj put ='open '.g:netrw_machine
2353     endif
2354     if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2355      NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2356     endif
2357     NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2358     NetrwKeepj put ='quit'
2359
2360     " perform cadaver operation:
2361     NetrwKeepj norm! 1G"_dd
2362     call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2363     keepj bd!
2364    endif
2365    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2366    let b:netrw_lastfile = choice
2367
2368   ".........................................
2369   " NetRead: (rsync) NetRead Method #7 {{{3
2370   elseif     b:netrw_method  == 7
2371"    call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2372    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))
2373    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2374    let b:netrw_lastfile = choice
2375
2376   ".........................................
2377   " NetRead: (fetch) NetRead Method #8 {{{3
2378   "    fetch://[user@]host[:http]/path
2379   elseif     b:netrw_method  == 8
2380"    call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2381    if g:netrw_fetch_cmd == ""
2382     if !exists("g:netrw_quiet")
2383      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2384     endif
2385"     call Dret("NetRead")
2386     return
2387    endif
2388    if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2389     let netrw_option= "http"
2390    else
2391     let netrw_option= "ftp"
2392    endif
2393"    call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2394
2395    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2396     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))
2397    else
2398     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))
2399    endif
2400
2401    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2402    let b:netrw_lastfile = choice
2403"    call Decho("setl ro",'~'.expand("<slnum>"))
2404    setl ro nomod
2405
2406   ".........................................
2407   " NetRead: (sftp) NetRead Method #9 {{{3
2408   elseif     b:netrw_method  == 9
2409"    call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2410    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2411    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2412    let b:netrw_lastfile = choice
2413
2414   ".........................................
2415   " NetRead: (file) NetRead Method #10 {{{3
2416  elseif      b:netrw_method == 10 && exists("g:netrw_file_cmd")
2417"   "    call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2418   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2419   let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2420   let b:netrw_lastfile = choice
2421
2422   ".........................................
2423   " NetRead: Complain {{{3
2424   else
2425    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
2426   endif
2427  endwhile
2428
2429  " NetRead: cleanup {{{3
2430  if exists("b:netrw_method")
2431"   call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2432   unlet b:netrw_method
2433   unlet b:netrw_fname
2434  endif
2435  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
2436"   call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2437   NetrwKeepj call s:NetrwDelete(tmpfile)
2438  endif
2439  NetrwKeepj call s:NetrwOptionsRestore("w:")
2440
2441"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
2442endfun
2443
2444" ------------------------------------------------------------------------
2445" netrw#NetWrite: responsible for writing a file over the net {{{2
2446fun! netrw#NetWrite(...) range
2447"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
2448
2449  " NetWrite: option handling {{{3
2450  let mod= 0
2451  call s:NetrwOptionsSave("w:")
2452  call s:NetrwOptionsSafe(0)
2453
2454  " NetWrite: Get Temporary Filename {{{3
2455  let tmpfile= s:GetTempfile("")
2456  if tmpfile == ""
2457"   call Dret("netrw#NetWrite : unable to get a tempfile!")
2458   return
2459  endif
2460
2461  if a:0 == 0
2462   let ichoice = 0
2463  else
2464   let ichoice = 1
2465  endif
2466
2467  let curbufname= expand("%")
2468"  call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
2469  if &binary
2470   " For binary writes, always write entire file.
2471   " (line numbers don't really make sense for that).
2472   " Also supports the writing of tar and zip files.
2473"   call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2474   exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2475  elseif g:netrw_cygwin
2476   " write (selected portion of) file to temporary
2477   let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2478"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2479   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
2480  else
2481   " write (selected portion of) file to temporary
2482"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2483   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2484  endif
2485
2486  if curbufname == ""
2487   " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2488   " on the temporary file's name.  Deletion of the temporary file during
2489   " cleanup then causes an error message.
2490   0file!
2491  endif
2492
2493  " NetWrite: while choice loop: {{{3
2494  while ichoice <= a:0
2495
2496   " Process arguments: {{{4
2497   " attempt to repeat with previous host-file-etc
2498   if exists("b:netrw_lastfile") && a:0 == 0
2499"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2500    let choice = b:netrw_lastfile
2501    let ichoice= ichoice + 1
2502   else
2503    exe "let choice= a:" . ichoice
2504
2505    " Reconstruct Choice when choice starts with '"'
2506    if match(choice,"?") == 0
2507     echomsg 'NetWrite Usage:"'
2508     echomsg ':Nwrite machine:path                        uses rcp'
2509     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
2510     echomsg ':Nwrite "machine id password path"          uses ftp'
2511     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
2512     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
2513     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
2514     echomsg ':Nwrite rcp://machine/path                  uses rcp'
2515     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
2516     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2517     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
2518     sleep 4
2519     break
2520
2521    elseif match(choice,"^\"") != -1
2522     if match(choice,"\"$") != -1
2523       " case "..."
2524      let choice=strpart(choice,1,strlen(choice)-2)
2525     else
2526      "  case "... ... ..."
2527      let choice      = strpart(choice,1,strlen(choice)-1)
2528      let wholechoice = ""
2529
2530      while match(choice,"\"$") == -1
2531       let wholechoice= wholechoice . " " . choice
2532       let ichoice    = ichoice + 1
2533       if choice > a:0
2534       	if !exists("g:netrw_quiet")
2535	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2536	endif
2537"        call Dret("netrw#NetWrite")
2538        return
2539       endif
2540       let choice= a:{ichoice}
2541      endwhile
2542      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2543     endif
2544    endif
2545   endif
2546   let ichoice= ichoice + 1
2547"   call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
2548
2549   " Determine method of write (ftp, rcp, etc) {{{4
2550   NetrwKeepj call s:NetrwMethod(choice)
2551   if !exists("b:netrw_method") || b:netrw_method < 0
2552"    call Dfunc("netrw#NetWrite : unsupported method")
2553    return
2554   endif
2555
2556   " =============
2557   " NetWrite: Perform Protocol-Based Write {{{3
2558   " ============================
2559   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2560    echo "(netrw) Processing your write request..."
2561"    call Decho("Processing your write request...",'~'.expand("<slnum>"))
2562   endif
2563
2564   ".........................................
2565   " NetWrite: (rcp) NetWrite Method #1 {{{3
2566   if  b:netrw_method == 1
2567"    call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2568    if s:netrw_has_nt_rcp == 1
2569     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2570      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2571     else
2572      let uid_machine = g:netrw_machine .'.'. $USERNAME
2573     endif
2574    else
2575     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2576      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2577     else
2578      let uid_machine = g:netrw_machine
2579     endif
2580    endif
2581    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))
2582    let b:netrw_lastfile = choice
2583
2584   ".........................................
2585   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2586   elseif b:netrw_method == 2
2587"    call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2588    let netrw_fname = b:netrw_fname
2589
2590    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2591    let bhkeep      = &l:bh
2592    let curbuf      = bufnr("%")
2593    setl bh=hide
2594    keepj keepalt enew
2595
2596"    call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2597    setl ff=unix
2598    NetrwKeepj put =g:netrw_ftpmode
2599"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2600    if exists("g:netrw_ftpextracmd")
2601     NetrwKeepj put =g:netrw_ftpextracmd
2602"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2603    endif
2604    NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2605"    call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2606    if exists("g:netrw_port") && g:netrw_port != ""
2607     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2608    else
2609"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2610     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2611    endif
2612    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2613    if getline(1) !~ "^$"
2614     if !exists("g:netrw_quiet")
2615      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2616     endif
2617     let mod=1
2618    endif
2619
2620    " remove enew buffer (quietly)
2621    let filtbuf= bufnr("%")
2622    exe curbuf."b!"
2623    let &l:bh            = bhkeep
2624    exe filtbuf."bw!"
2625
2626    let b:netrw_lastfile = choice
2627
2628   ".........................................
2629   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2630   elseif b:netrw_method == 3
2631    " Construct execution string (three or more lines) which will be passed through filter
2632"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2633    let netrw_fname = b:netrw_fname
2634    let bhkeep      = &l:bh
2635
2636    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2637    let curbuf      = bufnr("%")
2638    setl bh=hide
2639    keepj keepalt enew
2640    setl ff=unix
2641
2642    if exists("g:netrw_port") && g:netrw_port != ""
2643     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2644"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2645    else
2646     NetrwKeepj put ='open '.g:netrw_machine
2647"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2648    endif
2649    if exists("g:netrw_uid") && g:netrw_uid != ""
2650     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2651      NetrwKeepj put =g:netrw_uid
2652"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2653      if exists("s:netrw_passwd") && s:netrw_passwd != ""
2654       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2655      endif
2656"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2657     elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2658      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2659"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2660     endif
2661    endif
2662    NetrwKeepj put =g:netrw_ftpmode
2663"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2664    if exists("g:netrw_ftpextracmd")
2665     NetrwKeepj put =g:netrw_ftpextracmd
2666"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2667    endif
2668    NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2669"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2670    " save choice/id/password for future use
2671    let b:netrw_lastfile = choice
2672
2673    " perform ftp:
2674    " -i       : turns off interactive prompting from ftp
2675    " -n  unix : DON'T use <.netrc>, even though it exists
2676    " -n  win32: quit being obnoxious about password
2677    NetrwKeepj norm! 1G"_dd
2678    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2679    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2680    if getline(1) !~ "^$"
2681     if  !exists("g:netrw_quiet")
2682      call netrw#ErrorMsg(s:ERROR,getline(1),15)
2683     endif
2684     let mod=1
2685    endif
2686
2687    " remove enew buffer (quietly)
2688    let filtbuf= bufnr("%")
2689    exe curbuf."b!"
2690    let &l:bh= bhkeep
2691    exe filtbuf."bw!"
2692
2693   ".........................................
2694   " NetWrite: (scp) NetWrite Method #4 {{{3
2695   elseif     b:netrw_method == 4
2696"    call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2697    if exists("g:netrw_port") && g:netrw_port != ""
2698     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2699    else
2700     let useport= ""
2701    endif
2702    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2703    let b:netrw_lastfile = choice
2704
2705   ".........................................
2706   " NetWrite: (http) NetWrite Method #5 {{{3
2707   elseif     b:netrw_method == 5
2708"    call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2709    let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2710    if executable(curl)
2711     let url= g:netrw_choice
2712     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2713    elseif !exists("g:netrw_quiet")
2714     call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd.">".",16)
2715    endif
2716
2717   ".........................................
2718   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2719   elseif     b:netrw_method == 6
2720"    call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2721
2722    " Construct execution string (four lines) which will be passed through filter
2723    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2724    let bhkeep      = &l:bh
2725
2726    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2727    let curbuf      = bufnr("%")
2728    setl bh=hide
2729    keepj keepalt enew
2730
2731    setl ff=unix
2732    if exists("g:netrw_port") && g:netrw_port != ""
2733     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2734    else
2735     NetrwKeepj put ='open '.g:netrw_machine
2736    endif
2737    if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2738     NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2739    endif
2740    NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2741
2742    " perform cadaver operation:
2743    NetrwKeepj norm! 1G"_dd
2744    call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2745
2746    " remove enew buffer (quietly)
2747    let filtbuf= bufnr("%")
2748    exe curbuf."b!"
2749    let &l:bh            = bhkeep
2750    exe filtbuf."bw!"
2751
2752    let b:netrw_lastfile = choice
2753
2754   ".........................................
2755   " NetWrite: (rsync) NetWrite Method #7 {{{3
2756   elseif     b:netrw_method == 7
2757"    call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2758    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))
2759    let b:netrw_lastfile = choice
2760
2761   ".........................................
2762   " NetWrite: (sftp) NetWrite Method #9 {{{3
2763   elseif     b:netrw_method == 9
2764"    call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2765    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2766    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2767     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2768    else
2769     let uid_machine = g:netrw_machine
2770    endif
2771
2772    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2773    let bhkeep = &l:bh
2774    let curbuf = bufnr("%")
2775    setl bh=hide
2776    keepj keepalt enew
2777
2778    setl ff=unix
2779    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2780"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2781    let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2782    call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2783    let filtbuf= bufnr("%")
2784    exe curbuf."b!"
2785    let &l:bh            = bhkeep
2786    exe filtbuf."bw!"
2787    let b:netrw_lastfile = choice
2788
2789   ".........................................
2790   " NetWrite: Complain {{{3
2791   else
2792    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2793    let leavemod= 1
2794   endif
2795  endwhile
2796
2797  " NetWrite: Cleanup: {{{3
2798"  call Decho("cleanup",'~'.expand("<slnum>"))
2799  if s:FileReadable(tmpfile)
2800"   call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2801   call s:NetrwDelete(tmpfile)
2802  endif
2803  call s:NetrwOptionsRestore("w:")
2804
2805  if a:firstline == 1 && a:lastline == line("$")
2806   " restore modifiability; usually equivalent to set nomod
2807   let &mod= mod
2808"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2809  elseif !exists("leavemod")
2810   " indicate that the buffer has not been modified since last written
2811"   call Decho("set nomod",'~'.expand("<slnum>"))
2812   setl nomod
2813"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2814  endif
2815
2816"  call Dret("netrw#NetWrite")
2817endfun
2818
2819" ---------------------------------------------------------------------
2820" netrw#NetSource: source a remotely hosted vim script {{{2
2821" uses NetRead to get a copy of the file into a temporarily file,
2822"              then sources that file,
2823"              then removes that file.
2824fun! netrw#NetSource(...)
2825"  call Dfunc("netrw#NetSource() a:0=".a:0)
2826  if a:0 > 0 && a:1 == '?'
2827   " give help
2828   echomsg 'NetSource Usage:'
2829   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
2830   echomsg ':Nsource fetch://machine/path                 uses fetch'
2831   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2832   echomsg ':Nsource http[s]://[user@]machine/path        uses http  wget'
2833   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
2834   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
2835   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
2836   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2837   sleep 4
2838  else
2839   let i= 1
2840   while i <= a:0
2841    call netrw#NetRead(3,a:{i})
2842"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2843    if s:FileReadable(s:netrw_tmpfile)
2844"     call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2845     exe "so ".fnameescape(s:netrw_tmpfile)
2846"     call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2847     if delete(s:netrw_tmpfile)
2848      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2849     endif
2850     unlet s:netrw_tmpfile
2851    else
2852     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2853    endif
2854    let i= i + 1
2855   endwhile
2856  endif
2857"  call Dret("netrw#NetSource")
2858endfun
2859
2860" ---------------------------------------------------------------------
2861" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2862"                   (implements the :Ntree command)
2863fun! netrw#SetTreetop(iscmd,...)
2864"  call Dfunc("netrw#SetTreetop(iscmd=".a:iscmd." ".((a:0 > 0)? a:1 : "").") a:0=".a:0)
2865"  call Decho("w:netrw_treetop<".w:netrw_treetop.">")
2866
2867  " iscmd==0: netrw#SetTreetop called using gn mapping
2868  " iscmd==1: netrw#SetTreetop called using :Ntree from the command line
2869"  call Decho("(iscmd=".a:iscmd.": called using :Ntree from command line",'~'.expand("<slnum>"))
2870  " clear out the current tree
2871  if exists("w:netrw_treetop")
2872"   call Decho("clearing out current tree",'~'.expand("<slnum>"))
2873   let inittreetop= w:netrw_treetop
2874   unlet w:netrw_treetop
2875  endif
2876  if exists("w:netrw_treedict")
2877"   call Decho("freeing w:netrw_treedict",'~'.expand("<slnum>"))
2878   unlet w:netrw_treedict
2879  endif
2880"  call Decho("inittreetop<".(exists("inittreetop")? inittreetop : "n/a").">")
2881
2882  if (a:iscmd == 0 || a:1 == "") && exists("inittreetop")
2883   let treedir         = s:NetrwTreePath(inittreetop)
2884"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2885  else
2886   if isdirectory(s:NetrwFile(a:1))
2887"    call Decho("a:1<".a:1."> is a directory",'~'.expand("<slnum>"))
2888    let treedir         = a:1
2889    let s:netrw_treetop = treedir
2890   elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2891    let treedir         = b:netrw_curdir."/".a:1
2892    let s:netrw_treetop = treedir
2893"    call Decho("a:1<".a:1."> is NOT a directory, using treedir<".treedir.">",'~'.expand("<slnum>"))
2894   else
2895    " normally the cursor is left in the message window.
2896    " However, here this results in the directory being listed in the message window, which is not wanted.
2897    let netrwbuf= bufnr("%")
2898    call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2899    exe bufwinnr(netrwbuf)."wincmd w"
2900    let treedir         = "."
2901    let s:netrw_treetop = getcwd()
2902   endif
2903  endif
2904"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2905
2906  " determine if treedir is remote or local
2907  let islocal= expand("%") !~ '^\a\{3,}://'
2908"  call Decho("islocal=".islocal,'~'.expand("<slnum>"))
2909
2910  " browse the resulting directory
2911  if islocal
2912   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir))
2913  else
2914   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir))
2915  endif
2916
2917"  call Dret("netrw#SetTreetop")
2918endfun
2919
2920" ===========================================
2921" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
2922"    readcmd == %r : replace buffer with newly read file
2923"            == 0r : read file at top of buffer
2924"            == r  : read file after current line
2925"            == t  : leave file in temporary form (ie. don't read into buffer)
2926fun! s:NetrwGetFile(readcmd, tfile, method)
2927"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
2928
2929  " readcmd=='t': simply do nothing
2930  if a:readcmd == 't'
2931"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2932"   call Dret("NetrwGetFile : skip read of tfile<".a:tfile.">")
2933   return
2934  endif
2935
2936  " get name of remote filename (ie. url and all)
2937  let rfile= bufname("%")
2938"  call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
2939
2940  if exists("*NetReadFixup")
2941   " for the use of NetReadFixup (not otherwise used internally)
2942   let line2= line("$")
2943  endif
2944
2945  if a:readcmd[0] == '%'
2946  " get file into buffer
2947"   call Decho("get file into buffer",'~'.expand("<slnum>"))
2948
2949   " rename the current buffer to the temp file (ie. tfile)
2950   if g:netrw_cygwin
2951    let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2952   else
2953    let tfile= a:tfile
2954   endif
2955   call s:NetrwBufRename(tfile)
2956
2957   " edit temporary file (ie. read the temporary file in)
2958   if     rfile =~ '\.zip$'
2959"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2960    call zip#Browse(tfile)
2961   elseif rfile =~ '\.tar$'
2962"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2963    call tar#Browse(tfile)
2964   elseif rfile =~ '\.tar\.gz$'
2965"    call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2966    call tar#Browse(tfile)
2967   elseif rfile =~ '\.tar\.bz2$'
2968"    call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2969    call tar#Browse(tfile)
2970   elseif rfile =~ '\.tar\.xz$'
2971"    call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2972    call tar#Browse(tfile)
2973   elseif rfile =~ '\.txz$'
2974"    call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2975    call tar#Browse(tfile)
2976   else
2977"    call Decho("edit temporary file",'~'.expand("<slnum>"))
2978    NetrwKeepj e!
2979   endif
2980
2981   " rename buffer back to remote filename
2982   call s:NetrwBufRename(rfile)
2983
2984   " Detect filetype of local version of remote file.
2985   " Note that isk must not include a "/" for scripts.vim
2986   " to process this detection correctly.
2987"   call Decho("detect filetype of local version of remote file",'~'.expand("<slnum>"))
2988   let iskkeep= &l:isk
2989   setl isk-=/
2990   let &l:isk= iskkeep
2991"   call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
2992   let line1 = 1
2993   let line2 = line("$")
2994
2995  elseif !&ma
2996   " attempting to read a file after the current line in the file, but the buffer is not modifiable
2997   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2998"   call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2999   return
3000
3001  elseif s:FileReadable(a:tfile)
3002   " read file after current line
3003"   call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
3004   let curline = line(".")
3005   let lastline= line("$")
3006"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline,'~'.expand("<slnum>"))
3007   exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
3008   let line1= curline + 1
3009   let line2= line("$") - lastline + 1
3010
3011  else
3012   " not readable
3013"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3014"   call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
3015   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
3016"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
3017   return
3018  endif
3019
3020  " User-provided (ie. optional) fix-it-up command
3021  if exists("*NetReadFixup")
3022"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
3023   NetrwKeepj call NetReadFixup(a:method, line1, line2)
3024"  else " Decho
3025"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
3026  endif
3027
3028  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
3029   " update the Buffers menu
3030   NetrwKeepj call s:UpdateBuffersMenu()
3031  endif
3032
3033"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
3034
3035 " make sure file is being displayed
3036"  redraw!
3037
3038"  call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3039"  call Dret("NetrwGetFile")
3040endfun
3041
3042" ------------------------------------------------------------------------
3043" s:NetrwMethod:  determine method of transfer {{{2
3044" Input:
3045"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
3046" Output:
3047"  b:netrw_method= 1: rcp
3048"                  2: ftp + <.netrc>
3049"	           3: ftp + machine, id, password, and [path]filename
3050"	           4: scp
3051"	           5: http[s] (wget)
3052"	           6: dav
3053"	           7: rsync
3054"	           8: fetch
3055"	           9: sftp
3056"	          10: file
3057"  g:netrw_machine= hostname
3058"  b:netrw_fname  = filename
3059"  g:netrw_port   = optional port number (for ftp)
3060"  g:netrw_choice = copy of input url (choice)
3061fun! s:NetrwMethod(choice)
3062"   call Dfunc("s:NetrwMethod(a:choice<".a:choice.">)")
3063
3064   " sanity check: choice should have at least three slashes in it
3065   if strlen(substitute(a:choice,'[^/]','','g')) < 3
3066    call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
3067    let b:netrw_method = -1
3068"    call Dret("s:NetrwMethod : incorrect url format<".a:choice.">")
3069    return
3070   endif
3071
3072   " record current g:netrw_machine, if any
3073   " curmachine used if protocol == ftp and no .netrc
3074   if exists("g:netrw_machine")
3075    let curmachine= g:netrw_machine
3076"    call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
3077   else
3078    let curmachine= "N O T A HOST"
3079   endif
3080   if exists("g:netrw_port")
3081    let netrw_port= g:netrw_port
3082   endif
3083
3084   " insure that netrw_ftp_cmd starts off every method determination
3085   " with the current g:netrw_ftp_cmd
3086   let s:netrw_ftp_cmd= g:netrw_ftp_cmd
3087
3088  " initialization
3089  let b:netrw_method  = 0
3090  let g:netrw_machine = ""
3091  let b:netrw_fname   = ""
3092  let g:netrw_port    = ""
3093  let g:netrw_choice  = a:choice
3094
3095  " Patterns:
3096  " mipf     : a:machine a:id password filename	     Use ftp
3097  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
3098  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
3099  " rcpurm   : rcp://[user@]host/filename	     Use rcp
3100  " rcphf    : [user@]host:filename		     Use rcp
3101  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
3102  " httpurm  : http[s]://[user@]host/filename	     Use wget
3103  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
3104  " rsyncurm : rsync://host[:port]/path              Use rsync
3105  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
3106  " sftpurm  : sftp://[user@]host/filename  Use scp
3107  " fileurm  : file://[user@]host/filename	     Use elinks or links
3108  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
3109  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
3110  let ftpurm   = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
3111  let rcpurm   = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
3112  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
3113  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
3114  let httpurm  = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
3115  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
3116  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
3117  let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
3118  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
3119  let fileurm  = '^file\=://\(.*\)$'
3120
3121"  call Decho("determine method:",'~'.expand("<slnum>"))
3122  " Determine Method
3123  " Method#1: rcp://user@hostname/...path-to-file {{{3
3124  if match(a:choice,rcpurm) == 0
3125"   call Decho("rcp://...",'~'.expand("<slnum>"))
3126   let b:netrw_method  = 1
3127   let userid          = substitute(a:choice,rcpurm,'\1',"")
3128   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
3129   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
3130   if userid != ""
3131    let g:netrw_uid= userid
3132   endif
3133
3134  " Method#4: scp://user@hostname/...path-to-file {{{3
3135  elseif match(a:choice,scpurm) == 0
3136"   call Decho("scp://...",'~'.expand("<slnum>"))
3137   let b:netrw_method  = 4
3138   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
3139   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
3140   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
3141
3142  " Method#5: http[s]://user@hostname/...path-to-file {{{3
3143  elseif match(a:choice,httpurm) == 0
3144"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3145   let b:netrw_method = 5
3146   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
3147   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
3148   let b:netrw_http   = (a:choice =~ '^https:')? "https" : "http"
3149
3150  " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
3151  elseif match(a:choice,davurm) == 0
3152"   call Decho("dav://...",'~'.expand("<slnum>"))
3153   let b:netrw_method= 6
3154   if a:choice =~ 'davs:'
3155    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
3156   else
3157    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
3158   endif
3159   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
3160
3161   " Method#7: rsync://user@hostname/...path-to-file {{{3
3162  elseif match(a:choice,rsyncurm) == 0
3163"   call Decho("rsync://...",'~'.expand("<slnum>"))
3164   let b:netrw_method = 7
3165   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
3166   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
3167
3168   " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
3169  elseif match(a:choice,ftpurm) == 0
3170"   call Decho("ftp://...",'~'.expand("<slnum>"))
3171   let userid	      = substitute(a:choice,ftpurm,'\2',"")
3172   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
3173   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
3174   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
3175"   call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3176   if userid != ""
3177    let g:netrw_uid= userid
3178   endif
3179
3180   if curmachine != g:netrw_machine
3181    if exists("s:netrw_hup[".g:netrw_machine."]")
3182     call NetUserPass("ftp:".g:netrw_machine)
3183    elseif exists("s:netrw_passwd")
3184     " if there's a change in hostname, require password re-entry
3185     unlet s:netrw_passwd
3186    endif
3187    if exists("netrw_port")
3188     unlet netrw_port
3189    endif
3190   endif
3191
3192   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3193    let b:netrw_method = 3
3194   else
3195    let host= substitute(g:netrw_machine,'\..*$','','')
3196    if exists("s:netrw_hup[host]")
3197     call NetUserPass("ftp:".host)
3198
3199    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~# '-[sS]:'
3200"     call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3201"     call Decho("          g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3202     if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
3203      let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3204"      call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3205     endif
3206     let b:netrw_method= 2
3207    elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3208"     call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3209     let b:netrw_method= 2
3210    else
3211     if !exists("g:netrw_uid") || g:netrw_uid == ""
3212      call NetUserPass()
3213     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3214      call NetUserPass(g:netrw_uid)
3215    " else just use current g:netrw_uid and s:netrw_passwd
3216     endif
3217     let b:netrw_method= 3
3218    endif
3219   endif
3220
3221  " Method#8: fetch {{{3
3222  elseif match(a:choice,fetchurm) == 0
3223"   call Decho("fetch://...",'~'.expand("<slnum>"))
3224   let b:netrw_method = 8
3225   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3226   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3227   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3228   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
3229
3230   " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
3231  elseif match(a:choice,mipf) == 0
3232"   call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
3233   let b:netrw_method  = 3
3234   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3235   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
3236   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
3237   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
3238   call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
3239
3240  " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3241  elseif match(a:choice,mf) == 0
3242"   call Decho("(ftp) host file",'~'.expand("<slnum>"))
3243   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3244    let b:netrw_method  = 3
3245    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3246    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3247
3248   elseif s:FileReadable(expand("$HOME/.netrc"))
3249    let b:netrw_method  = 2
3250    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3251    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3252   endif
3253
3254  " Method#9: sftp://user@hostname/...path-to-file {{{3
3255  elseif match(a:choice,sftpurm) == 0
3256"   call Decho("sftp://...",'~'.expand("<slnum>"))
3257   let b:netrw_method = 9
3258   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3259   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
3260
3261  " Method#1: Issue an rcp: hostname:filename"  (this one should be last) {{{3
3262  elseif match(a:choice,rcphf) == 0
3263"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3264   let b:netrw_method  = 1
3265   let userid          = substitute(a:choice,rcphf,'\2',"")
3266   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3267   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
3268"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3269"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3270"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3271"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3272   if userid != ""
3273    let g:netrw_uid= userid
3274   endif
3275
3276   " Method#10: file://user@hostname/...path-to-file {{{3
3277  elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
3278"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3279   let b:netrw_method = 10
3280   let b:netrw_fname  = substitute(a:choice,fileurm,'\1',"")
3281"   call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
3282
3283  " Cannot Determine Method {{{3
3284  else
3285   if !exists("g:netrw_quiet")
3286    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3287   endif
3288   let b:netrw_method  = -1
3289  endif
3290  "}}}3
3291
3292  if g:netrw_port != ""
3293   " remove any leading [:#] from port number
3294   let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
3295  elseif exists("netrw_port")
3296   " retain port number as implicit for subsequent ftp operations
3297   let g:netrw_port= netrw_port
3298  endif
3299
3300"  call Decho("a:choice       <".a:choice.">",'~'.expand("<slnum>"))
3301"  call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3302"  call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3303"  call Decho("g:netrw_port   <".g:netrw_port.">",'~'.expand("<slnum>"))
3304"  if exists("g:netrw_uid")		"Decho
3305"   call Decho("g:netrw_uid    <".g:netrw_uid.">",'~'.expand("<slnum>"))
3306"  endif					"Decho
3307"  if exists("s:netrw_passwd")		"Decho
3308"   call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3309"  endif					"Decho
3310"  call Decho("b:netrw_fname  <".b:netrw_fname.">",'~'.expand("<slnum>"))
3311"  call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
3312endfun
3313
3314" ------------------------------------------------------------------------
3315" NetReadFixup: this sort of function is typically written by the user {{{2
3316"               to handle extra junk that their system's ftp dumps
3317"               into the transfer.  This function is provided as an
3318"               example and as a fix for a Windows 95 problem: in my
3319"               experience, win95's ftp always dumped four blank lines
3320"               at the end of the transfer.
3321if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
3322 fun! NetReadFixup(method, line1, line2)
3323"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
3324
3325   " sanity checks -- attempt to convert inputs to integers
3326   let method = a:method + 0
3327   let line1  = a:line1 + 0
3328   let line2  = a:line2 + 0
3329   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
3330"    call Dret("NetReadFixup")
3331    return
3332   endif
3333
3334   if method == 3   " ftp (no <.netrc>)
3335    let fourblanklines= line2 - 3
3336    if fourblanklines >= line1
3337     exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
3338     call histdel("/",-1)
3339    endif
3340   endif
3341
3342"   call Dret("NetReadFixup")
3343 endfun
3344endif
3345
3346" ---------------------------------------------------------------------
3347" NetUserPass: set username and password for subsequent ftp transfer {{{2
3348"   Usage:  :call NetUserPass()		               -- will prompt for userid and password
3349"	    :call NetUserPass("uid")	               -- will prompt for password
3350"	    :call NetUserPass("uid","password")        -- sets global userid and password
3351"	    :call NetUserPass("ftp:host")              -- looks up userid and password using hup dictionary
3352"	    :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
3353fun! NetUserPass(...)
3354
3355" call Dfunc("NetUserPass() a:0=".a:0)
3356
3357 if !exists('s:netrw_hup')
3358  let s:netrw_hup= {}
3359 endif
3360
3361 if a:0 == 0
3362  " case: no input arguments
3363
3364  " change host and username if not previously entered; get new password
3365  if !exists("g:netrw_machine")
3366   let g:netrw_machine= input('Enter hostname: ')
3367  endif
3368  if !exists("g:netrw_uid") || g:netrw_uid == ""
3369   " get username (user-id) via prompt
3370   let g:netrw_uid= input('Enter username: ')
3371  endif
3372  " get password via prompting
3373  let s:netrw_passwd= inputsecret("Enter Password: ")
3374
3375  " set up hup database
3376  let host = substitute(g:netrw_machine,'\..*$','','')
3377  if !exists('s:netrw_hup[host]')
3378   let s:netrw_hup[host]= {}
3379  endif
3380  let s:netrw_hup[host].uid    = g:netrw_uid
3381  let s:netrw_hup[host].passwd = s:netrw_passwd
3382
3383 elseif a:0 == 1
3384  " case: one input argument
3385
3386  if a:1 =~ '^ftp:'
3387   " get host from ftp:... url
3388   " access userid and password from hup (host-user-passwd) dictionary
3389"   call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3390   let host = substitute(a:1,'^ftp:','','')
3391   let host = substitute(host,'\..*','','')
3392   if exists("s:netrw_hup[host]")
3393    let g:netrw_uid    = s:netrw_hup[host].uid
3394    let s:netrw_passwd = s:netrw_hup[host].passwd
3395"    call Decho("get s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3396"    call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3397   else
3398    let g:netrw_uid    = input("Enter UserId: ")
3399    let s:netrw_passwd = inputsecret("Enter Password: ")
3400   endif
3401
3402  else
3403   " case: one input argument, not an url.  Using it as a new user-id.
3404"   call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3405   if exists("g:netrw_machine")
3406    if g:netrw_machine =~ '[0-9.]\+'
3407     let host= g:netrw_machine
3408    else
3409     let host= substitute(g:netrw_machine,'\..*$','','')
3410    endif
3411   else
3412    let g:netrw_machine= input('Enter hostname: ')
3413   endif
3414   let g:netrw_uid = a:1
3415"   call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3416   if exists("g:netrw_passwd")
3417    " ask for password if one not previously entered
3418    let s:netrw_passwd= g:netrw_passwd
3419   else
3420    let s:netrw_passwd = inputsecret("Enter Password: ")
3421   endif
3422  endif
3423
3424"  call Decho("host<".host.">",'~'.expand("<slnum>"))
3425  if exists("host")
3426   if !exists('s:netrw_hup[host]')
3427    let s:netrw_hup[host]= {}
3428   endif
3429   let s:netrw_hup[host].uid    = g:netrw_uid
3430   let s:netrw_hup[host].passwd = s:netrw_passwd
3431  endif
3432
3433 elseif a:0 == 2
3434  let g:netrw_uid    = a:1
3435  let s:netrw_passwd = a:2
3436
3437 elseif a:0 == 3
3438  " enter hostname, user-id, and password into the hup dictionary
3439  let host = substitute(a:1,'^\a\+:','','')
3440  let host = substitute(host,'\..*$','','')
3441  if !exists('s:netrw_hup[host]')
3442   let s:netrw_hup[host]= {}
3443  endif
3444  let s:netrw_hup[host].uid    = a:2
3445  let s:netrw_hup[host].passwd = a:3
3446  let g:netrw_uid              = s:netrw_hup[host].uid
3447  let s:netrw_passwd           = s:netrw_hup[host].passwd
3448"  call Decho("set s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3449"  call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3450 endif
3451
3452" call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
3453endfun
3454
3455" =================================
3456"  Shared Browsing Support:    {{{1
3457" =================================
3458
3459" ---------------------------------------------------------------------
3460" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3461fun! s:ExplorePatHls(pattern)
3462"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
3463  let repat= substitute(a:pattern,'^**/\{1,2}','','')
3464"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3465  let repat= escape(repat,'][.\')
3466"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3467  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
3468"  call Dret("s:ExplorePatHls repat<".repat.">")
3469  return repat
3470endfun
3471
3472" ---------------------------------------------------------------------
3473"  s:NetrwBookHistHandler: {{{2
3474"    0: (user: <mb>)   bookmark current directory
3475"    1: (user: <gb>)   change to the bookmarked directory
3476"    2: (user: <qb>)   list bookmarks
3477"    3: (browsing)     records current directory history
3478"    4: (user: <u>)    go up   (previous) directory, using history
3479"    5: (user: <U>)    go down (next)     directory, using history
3480"    6: (user: <mB>)   delete bookmark
3481fun! s:NetrwBookHistHandler(chg,curdir)
3482"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhistcnt." histmax=".g:netrw_dirhistmax)
3483  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3484"   "  call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3485   return
3486  endif
3487
3488  let ykeep    = @@
3489  let curbufnr = bufnr("%")
3490
3491  if a:chg == 0
3492   " bookmark the current directory
3493"   call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3494   if exists("s:netrwmarkfilelist_{curbufnr}")
3495    call s:NetrwBookmark(0)
3496    echo "bookmarked marked files"
3497   else
3498    call s:MakeBookmark(a:curdir)
3499    echo "bookmarked the current directory"
3500   endif
3501
3502  elseif a:chg == 1
3503   " change to the bookmarked directory
3504"   call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3505   if exists("g:netrw_bookmarklist[v:count-1]")
3506"    call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3507    exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3508   else
3509    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3510   endif
3511
3512  elseif a:chg == 2
3513"   redraw!
3514   let didwork= 0
3515   " list user's bookmarks
3516"   call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3517   if exists("g:netrw_bookmarklist")
3518"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3519    let cnt= 1
3520    for bmd in g:netrw_bookmarklist
3521"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3522     echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3523     let didwork = 1
3524     let cnt     = cnt + 1
3525    endfor
3526   endif
3527
3528   " list directory history
3529   " Note: history is saved only when PerformListing is done;
3530   "       ie. when netrw can re-use a netrw buffer, the current directory is not saved in the history.
3531   let cnt     = g:netrw_dirhistcnt
3532   let first   = 1
3533   let histcnt = 0
3534   if g:netrw_dirhistmax > 0
3535    while ( first || cnt != g:netrw_dirhistcnt )
3536"    call Decho("first=".first." cnt=".cnt." dirhistcnt=".g:netrw_dirhistcnt,'~'.expand("<slnum>"))
3537     if exists("g:netrw_dirhist_{cnt}")
3538"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3539      echo printf("Netrw  History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3540      let didwork= 1
3541     endif
3542     let histcnt = histcnt + 1
3543     let first   = 0
3544     let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3545     if cnt < 0
3546      let cnt= cnt + g:netrw_dirhistmax
3547     endif
3548    endwhile
3549   else
3550    let g:netrw_dirhistcnt= 0
3551   endif
3552   if didwork
3553    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3554   endif
3555
3556  elseif a:chg == 3
3557   " saves most recently visited directories (when they differ)
3558"   call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3559   if !exists("g:netrw_dirhistcnt") || !exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") || g:netrw_dirhist_{g:netrw_dirhistcnt} != a:curdir
3560    if g:netrw_dirhistmax > 0
3561     let g:netrw_dirhistcnt                   = ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3562     let g:netrw_dirhist_{g:netrw_dirhistcnt} = a:curdir
3563    endif
3564"    call Decho("save dirhist#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3565   endif
3566
3567  elseif a:chg == 4
3568   " u: change to the previous directory stored on the history list
3569"   call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
3570   if g:netrw_dirhistmax > 0
3571    let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - v:count1 ) % g:netrw_dirhistmax
3572    if g:netrw_dirhistcnt < 0
3573     let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3574    endif
3575   else
3576    let g:netrw_dirhistcnt= 0
3577   endif
3578   if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3579"    call Decho("changedir u#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3580    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3581     setl ma noro
3582"     call Decho("setl ma noro",'~'.expand("<slnum>"))
3583     sil! NetrwKeepj %d _
3584     setl nomod
3585"     call Decho("setl nomod",'~'.expand("<slnum>"))
3586"     call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3587    endif
3588"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3589    exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3590   else
3591    if g:netrw_dirhistmax > 0
3592     let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + v:count1 ) % g:netrw_dirhistmax
3593    else
3594     let g:netrw_dirhistcnt= 0
3595    endif
3596    echo "Sorry, no predecessor directory exists yet"
3597   endif
3598
3599  elseif a:chg == 5
3600   " U: change to the subsequent directory stored on the history list
3601"   call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3602   if g:netrw_dirhistmax > 0
3603    let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3604    if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3605"    call Decho("changedir U#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3606     if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3607"      call Decho("setl ma noro",'~'.expand("<slnum>"))
3608      setl ma noro
3609      sil! NetrwKeepj %d _
3610"      call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3611"      call Decho("setl nomod",'~'.expand("<slnum>"))
3612      setl nomod
3613"      call Decho("(set nomod)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3614     endif
3615"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3616     exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3617    else
3618     let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - 1 ) % g:netrw_dirhistmax
3619     if g:netrw_dirhistcnt < 0
3620      let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3621     endif
3622     echo "Sorry, no successor directory exists yet"
3623    endif
3624   else
3625    let g:netrw_dirhistcnt= 0
3626    echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
3627   endif
3628
3629  elseif a:chg == 6
3630"   call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3631   if exists("s:netrwmarkfilelist_{curbufnr}")
3632    call s:NetrwBookmark(1)
3633    echo "removed marked files from bookmarks"
3634   else
3635    " delete the v:count'th bookmark
3636    let iremove = v:count
3637    let dremove = g:netrw_bookmarklist[iremove - 1]
3638"    call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3639    call s:MergeBookmarks()
3640"    call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3641    NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3642    echo "removed ".dremove." from g:netrw_bookmarklist"
3643"    call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3644   endif
3645"   call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3646  endif
3647  call s:NetrwBookmarkMenu()
3648  call s:NetrwTgtMenu()
3649  let @@= ykeep
3650"  call Dret("s:NetrwBookHistHandler")
3651endfun
3652
3653" ---------------------------------------------------------------------
3654" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
3655"  Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
3656"                      Sister function: s:NetrwBookHistSave()
3657fun! s:NetrwBookHistRead()
3658"  call Dfunc("s:NetrwBookHistRead()")
3659  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3660"   call Dret("s:NetrwBookHistRead - nothing read (suppressed due to dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a").")")
3661   return
3662  endif
3663  let ykeep= @@
3664
3665  " read bookmarks
3666  if !exists("s:netrw_initbookhist")
3667   let home    = s:NetrwHome()
3668   let savefile= home."/.netrwbook"
3669   if filereadable(s:NetrwFile(savefile))
3670"    call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3671    exe "keepalt NetrwKeepj so ".savefile
3672   endif
3673
3674   " read history
3675   if g:netrw_dirhistmax > 0
3676    let savefile= home."/.netrwhist"
3677    if filereadable(s:NetrwFile(savefile))
3678"    call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3679     exe "keepalt NetrwKeepj so ".savefile
3680    endif
3681    let s:netrw_initbookhist= 1
3682    au VimLeave * call s:NetrwBookHistSave()
3683   endif
3684  endif
3685
3686  let @@= ykeep
3687"  call Decho("dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a"),'~'.expand("<slnum>"))
3688"  call Decho("dirhistcnt=".(exists("g:netrw_dirhistcnt")? g:netrw_dirhistcnt : "n/a"),'~'.expand("<slnum>"))
3689"  call Dret("s:NetrwBookHistRead")
3690endfun
3691
3692" ---------------------------------------------------------------------
3693" s:NetrwBookHistSave: this function saves bookmarks and history to files {{{2
3694"                      Sister function: s:NetrwBookHistRead()
3695"                      I used to do this via viminfo but that appears to
3696"                      be unreliable for long-term storage
3697"                      If g:netrw_dirhistmax is <= 0, no history or bookmarks
3698"                      will be saved.
3699"                      (s:NetrwBookHistHandler(3,...) used to record history)
3700fun! s:NetrwBookHistSave()
3701"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt)
3702  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3703"   call Dret("s:NetrwBookHistSave : nothing saved (dirhistmax=".g:netrw_dirhistmax.")")
3704   return
3705  endif
3706
3707  let savefile= s:NetrwHome()."/.netrwhist"
3708"  call Decho("savefile<".savefile.">",'~'.expand("<slnum>"))
3709  1split
3710
3711  " setting up a new buffer which will become .netrwhist
3712  call s:NetrwEnew()
3713"  call Decho("case g:netrw_use_noswf=".g:netrw_use_noswf.(exists("+acd")? " +acd" : " -acd"),'~'.expand("<slnum>"))
3714  if g:netrw_use_noswf
3715   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
3716  else
3717   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
3718  endif
3719  setl nocin noai noci magic nospell nohid wig= noaw
3720  setl ma noro write
3721  if exists("+acd") | setl noacd | endif
3722  sil! NetrwKeepj keepalt %d _
3723
3724  " rename enew'd file: .netrwhist -- no attempt to merge
3725  " record dirhistmax and current dirhistcnt
3726  " save history
3727"  call Decho("saving history: dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt." lastline=".line("$"),'~'.expand("<slnum>"))
3728  sil! keepalt file .netrwhist
3729  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
3730  call setline(2,"let g:netrw_dirhistcnt =".g:netrw_dirhistcnt)
3731  if g:netrw_dirhistmax > 0
3732   let lastline = line("$")
3733   let cnt      = g:netrw_dirhistcnt
3734   let first    = 1
3735   while ( first || cnt != g:netrw_dirhistcnt )
3736    let lastline= lastline + 1
3737    if exists("g:netrw_dirhist_{cnt}")
3738     call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3739"     call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("<slnum>"))
3740    endif
3741    let first   = 0
3742    let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3743    if cnt < 0
3744     let cnt= cnt + g:netrw_dirhistmax
3745    endif
3746   endwhile
3747   exe "sil! w! ".savefile
3748"   call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
3749  endif
3750
3751  " save bookmarks
3752  sil NetrwKeepj %d _
3753  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
3754"   call Decho("saving bookmarks",'~'.expand("<slnum>"))
3755   " merge and write .netrwbook
3756   let savefile= s:NetrwHome()."/.netrwbook"
3757
3758   if filereadable(s:NetrwFile(savefile))
3759    let booklist= deepcopy(g:netrw_bookmarklist)
3760    exe "sil NetrwKeepj keepalt so ".savefile
3761    for bdm in booklist
3762     if index(g:netrw_bookmarklist,bdm) == -1
3763      call add(g:netrw_bookmarklist,bdm)
3764     endif
3765    endfor
3766    call sort(g:netrw_bookmarklist)
3767   endif
3768
3769   " construct and save .netrwbook
3770   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3771   exe "sil! w! ".savefile
3772"   call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
3773  endif
3774
3775  " cleanup -- remove buffer used to construct history
3776  let bgone= bufnr("%")
3777  q!
3778  exe "keepalt ".bgone."bwipe!"
3779
3780"  call Dret("s:NetrwBookHistSave")
3781endfun
3782
3783" ---------------------------------------------------------------------
3784" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3785"  list of the contents of a local or remote directory.  It is assumed that the
3786"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3787"  with the requested remote hostname first.
3788"    Often called via:  Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
3789fun! s:NetrwBrowse(islocal,dirname)
3790  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
3791"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
3792"  call Decho("fyi: modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
3793"  call Decho("fyi: tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3794"  call Dredir("ls!","s:NetrwBrowse")
3795
3796  " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3797  " This is useful when one edits a local file, then :e ., then :Rex
3798  if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
3799   let w:netrw_rexfile= bufname("#")
3800"   call Decho("setting w:netrw_rexfile<".w:netrw_rexfile."> win#".winnr(),'~'.expand("<slnum>"))
3801  endif
3802
3803  " s:NetrwBrowse : initialize history {{{3
3804  if !exists("s:netrw_initbookhist")
3805   NetrwKeepj call s:NetrwBookHistRead()
3806  endif
3807
3808  " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
3809  if a:dirname !~ '^\a\{3,}://'
3810   let dirname= simplify(a:dirname)
3811"   call Decho("simplified dirname<".dirname.">")
3812  else
3813   let dirname= a:dirname
3814  endif
3815
3816  " repoint t:netrw_lexbufnr if appropriate
3817  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
3818"   call Decho("set repointlexbufnr to true!")
3819   let repointlexbufnr= 1
3820  endif
3821
3822  " s:NetrwBrowse : sanity checks: {{{3
3823  if exists("s:netrw_skipbrowse")
3824   unlet s:netrw_skipbrowse
3825"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("<slnum>"))
3826"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed")
3827   return
3828  endif
3829  if !exists("*shellescape")
3830   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3831"   call Dret("s:NetrwBrowse : missing shellescape()")
3832   return
3833  endif
3834  if !exists("*fnameescape")
3835   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3836"   call Dret("s:NetrwBrowse : missing fnameescape()")
3837   return
3838  endif
3839
3840  " s:NetrwBrowse : save options: {{{3
3841  call s:NetrwOptionsSave("w:")
3842
3843  " s:NetrwBrowse : re-instate any marked files {{{3
3844  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3845   if exists("s:netrwmarkfilelist_{bufnr('%')}")
3846"    call Decho("clearing marked files",'~'.expand("<slnum>"))
3847    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3848   endif
3849  endif
3850
3851  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
3852   " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3853"   call Decho("handle w:netrw_acdkeep:",'~'.expand("<slnum>"))
3854"   call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("<slnum>"))
3855   if s:NetrwLcd(dirname)
3856"    call Dret("s:NetrwBrowse : lcd failure")
3857    return
3858   endif
3859   "   call s:NetrwOptionsSafe() " tst952 failed with this enabled.
3860"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
3861
3862  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
3863   " s:NetrwBrowse :  remote regular file handler {{{3
3864"   call Decho("handle remote regular file: dirname<".dirname.">",'~'.expand("<slnum>"))
3865   if bufname(dirname) != ""
3866"    call Decho("edit buf#".bufname(dirname)." in win#".winnr(),'~'.expand("<slnum>"))
3867    exe "NetrwKeepj b ".bufname(dirname)
3868   else
3869    " attempt transfer of remote regular file
3870"    call Decho("attempt transfer as regular file<".dirname.">",'~'.expand("<slnum>"))
3871
3872    " remove any filetype indicator from end of dirname, except for the
3873    " "this is a directory" indicator (/).
3874    " There shouldn't be one of those here, anyway.
3875    let path= substitute(dirname,'[*=@|]\r\=$','','e')
3876"    call Decho("new path<".path.">",'~'.expand("<slnum>"))
3877    call s:RemotePathAnalysis(dirname)
3878
3879    " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3880    call s:NetrwEnew(dirname)
3881    call s:NetrwOptionsSafe(a:islocal)
3882    setl ma noro
3883"    call Decho("setl ma noro",'~'.expand("<slnum>"))
3884    let b:netrw_curdir = dirname
3885    let url            = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3886    call s:NetrwBufRename(url)
3887    exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3888    sil call netrw#NetRead(2,url)
3889    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3890"    call Decho("url<".url.">",'~'.expand("<slnum>"))
3891"    call Decho("s:path<".s:path.">",'~'.expand("<slnum>"))
3892"    call Decho("s:fname<".s:fname.">",'~'.expand("<slnum>"))
3893    if s:path =~ '.bz2'
3894     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3895    elseif s:path =~ '.gz'
3896     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3897    elseif s:path =~ '.gz'
3898     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3899    else
3900     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3901    endif
3902   endif
3903
3904   " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3905   call s:SetBufWinVars()
3906   call s:NetrwOptionsRestore("w:")
3907"   call Decho("setl ma nomod",'~'.expand("<slnum>"))
3908   setl ma nomod noro
3909"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3910
3911"   call Dret("s:NetrwBrowse : file<".s:fname.">")
3912   return
3913  endif
3914
3915  " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
3916  call s:UseBufWinVars()
3917
3918  " set up some variables {{{3
3919  let b:netrw_browser_active = 1
3920  let dirname                = dirname
3921  let s:last_sort_by         = g:netrw_sort_by
3922
3923  " set up menu {{{3
3924  NetrwKeepj call s:NetrwMenu(1)
3925
3926  " get/set-up buffer {{{3
3927"  call Decho("saving position across a buffer refresh",'~'.expand("<slnum>"))
3928  let svpos  = winsaveview()
3929"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3930  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
3931
3932  " maintain markfile highlighting
3933  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3934   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3935" "   call Decho("bufnr(%)=".bufnr('%'),'~'.expand("<slnum>"))
3936" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
3937    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3938   else
3939" "   call Decho("2match none",'~'.expand("<slnum>"))
3940    2match none
3941   endif
3942  endif
3943  if reusing && line("$") > 1
3944   call s:NetrwOptionsRestore("w:")
3945"   call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3946   setl noma nomod nowrap
3947"   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>"))
3948"   call Dret("s:NetrwBrowse : re-using not-cleared buffer")
3949   return
3950  endif
3951
3952  " set b:netrw_curdir to the new directory name {{{3
3953"  call Decho("set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")",'~'.expand("<slnum>"))
3954  let b:netrw_curdir= dirname
3955  if b:netrw_curdir =~ '[/\\]$'
3956   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
3957  endif
3958  if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
3959   let b:netrw_curdir= b:netrw_curdir."/"
3960  endif
3961  if b:netrw_curdir == ''
3962   if has("amiga")
3963    " On the Amiga, the empty string connotes the current directory
3964    let b:netrw_curdir= getcwd()
3965   else
3966    " under unix, when the root directory is encountered, the result
3967    " from the preceding substitute is an empty string.
3968    let b:netrw_curdir= '/'
3969   endif
3970  endif
3971  if !a:islocal && b:netrw_curdir !~ '/$'
3972   let b:netrw_curdir= b:netrw_curdir.'/'
3973  endif
3974"  call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
3975
3976  " ------------
3977  " (local only) {{{3
3978  " ------------
3979  if a:islocal
3980"   call Decho("local only:",'~'.expand("<slnum>"))
3981
3982   " Set up ShellCmdPost handling.  Append current buffer to browselist
3983   call s:LocalFastBrowser()
3984
3985  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3986   if !g:netrw_keepdir
3987"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
3988"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("<slnum>"))
3989    if !exists("&l:acd") || !&l:acd
3990     if s:NetrwLcd(b:netrw_curdir)
3991"      call Dret("s:NetrwBrowse : lcd failure")
3992      return
3993     endif
3994    endif
3995   endif
3996
3997  " --------------------------------
3998  " remote handling: {{{3
3999  " --------------------------------
4000  else
4001"   call Decho("remote only:",'~'.expand("<slnum>"))
4002
4003   " analyze dirname and g:netrw_list_cmd {{{3
4004"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>"))
4005   if dirname =~# "^NetrwTreeListing\>"
4006    let dirname= b:netrw_curdir
4007"    call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>"))
4008   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
4009    let dirname= substitute(b:netrw_curdir,'\\','/','g')
4010    if dirname !~ '/$'
4011     let dirname= dirname.'/'
4012    endif
4013    let b:netrw_curdir = dirname
4014"    call Decho("(liststyle is TREELIST) dirname<".dirname.">",'~'.expand("<slnum>"))
4015   else
4016    let dirname = substitute(dirname,'\\','/','g')
4017"    call Decho("(normal) dirname<".dirname.">",'~'.expand("<slnum>"))
4018   endif
4019
4020   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
4021   if dirname !~ dirpat
4022    if !exists("g:netrw_quiet")
4023     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
4024    endif
4025    NetrwKeepj call s:NetrwOptionsRestore("w:")
4026"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
4027    setl noma nomod nowrap
4028"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4029"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
4030    return
4031   endif
4032   let b:netrw_curdir= dirname
4033"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("<slnum>"))
4034  endif  " (additional remote handling)
4035
4036  " -------------------------------
4037  " Perform Directory Listing: {{{3
4038  " -------------------------------
4039  NetrwKeepj call s:NetrwMaps(a:islocal)
4040  NetrwKeepj call s:NetrwCommands(a:islocal)
4041  NetrwKeepj call s:PerformListing(a:islocal)
4042
4043  " restore option(s)
4044  call s:NetrwOptionsRestore("w:")
4045"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4046
4047  " If there is a rexposn: restore position with rexposn
4048  " Otherwise            : set rexposn
4049  if exists("s:rexposn_".bufnr("%"))
4050"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
4051   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
4052   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4053    NetrwKeepj exe w:netrw_bannercnt
4054   endif
4055  else
4056   NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
4057  endif
4058  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
4059   let &l:bexpr= "netrw#BalloonHelp()"
4060"   call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>"))
4061   setl beval
4062  endif
4063
4064  " repoint t:netrw_lexbufnr if appropriate
4065  if exists("repointlexbufnr")
4066   let t:netrw_lexbufnr= bufnr("%")
4067"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
4068  endif
4069
4070  " restore position
4071  if reusing
4072"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4073   call winrestview(svpos)
4074  endif
4075
4076  " The s:LocalBrowseRefresh() function is called by an autocmd
4077  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow or medium speed).
4078  " However, s:NetrwBrowse() causes the FocusGained event to fire the first time.
4079"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4080"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4081"  call Dret("s:NetrwBrowse : did PerformListing  ft<".&ft.">")
4082  return
4083endfun
4084
4085" ---------------------------------------------------------------------
4086" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
4087" may not apply correctly; ie. netrw's idea of the current directory may
4088" differ from vim's.  This function insures that netrw's idea of the current
4089" directory is used.
4090" Returns a path to the file specified by a:fname
4091fun! s:NetrwFile(fname)
4092"  "" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
4093"  "" call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
4094"  "" call Decho("g:netrw_cygwin   =".(exists("g:netrw_cygwin")?    g:netrw_cygwin    : 'n/a'),'~'.expand("<slnum>"))
4095"  "" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
4096"  "" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
4097
4098  " clean up any leading treedepthstring
4099  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4100   let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
4101"   "" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>"))
4102  else
4103   let fname= a:fname
4104  endif
4105
4106  if g:netrw_keepdir
4107   " vim's idea of the current directory possibly may differ from netrw's
4108   if !exists("b:netrw_curdir")
4109    let b:netrw_curdir= getcwd()
4110   endif
4111
4112   if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
4113    if fname =~ '^\' || fname =~ '^\a:\'
4114     " windows, but full path given
4115     let ret= fname
4116"     "" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4117    else
4118     " windows, relative path given
4119     let ret= s:ComposePath(b:netrw_curdir,fname)
4120"     "" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4121    endif
4122
4123   elseif fname =~ '^/'
4124    " not windows, full path given
4125    let ret= fname
4126"    "" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4127   else
4128    " not windows, relative path given
4129    let ret= s:ComposePath(b:netrw_curdir,fname)
4130"    "" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4131   endif
4132  else
4133   " vim and netrw agree on the current directory
4134   let ret= fname
4135"   "" call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
4136"   "" call Decho("vim   directory: ".getcwd(),'~'.expand("<slnum>"))
4137"   "" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>"))
4138  endif
4139
4140"  "" call Dret("s:NetrwFile ".ret)
4141  return ret
4142endfun
4143
4144" ---------------------------------------------------------------------
4145" s:NetrwFileInfo: supports qf (query for file information) {{{2
4146fun! s:NetrwFileInfo(islocal,fname)
4147"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
4148  let ykeep= @@
4149  if a:islocal
4150   let lsopt= "-lsad"
4151   if g:netrw_sizestyle =~# 'H'
4152    let lsopt= "-lsadh"
4153   elseif g:netrw_sizestyle =~# 'h'
4154    let lsopt= "-lsadh --si"
4155   endif
4156"   call Decho("(s:NetrwFileInfo) lsopt<".lsopt.">")
4157   if (has("unix") || has("macunix")) && executable("/bin/ls")
4158
4159    if getline(".") == "../"
4160     echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
4161"     call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
4162
4163    elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
4164     echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
4165"     call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
4166
4167    elseif exists("b:netrw_curdir")
4168      echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
4169"      call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
4170
4171    else
4172"     call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
4173     echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
4174"     call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
4175    endif
4176   else
4177    " use vim functions to return information about file below cursor
4178"    call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
4179    if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
4180     let fname= substitute(a:fname,".$","","")
4181    else
4182     let fname= a:fname
4183    endif
4184    let t  = getftime(s:NetrwFile(fname))
4185    let sz = getfsize(s:NetrwFile(fname))
4186    if g:netrw_sizestyle =~# "[hH]"
4187     let sz= s:NetrwHumanReadable(sz)
4188    endif
4189    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
4190"    call Decho("fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
4191   endif
4192  else
4193   echo "sorry, \"qf\" not supported yet for remote files"
4194  endif
4195  let @@= ykeep
4196"  call Dret("s:NetrwFileInfo")
4197endfun
4198
4199" ---------------------------------------------------------------------
4200" s:NetrwFullPath: returns the full path to a directory and/or file {{{2
4201fun! s:NetrwFullPath(filename)
4202"  " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)")
4203  let filename= a:filename
4204  if filename !~ '^/'
4205   let filename= resolve(getcwd().'/'.filename)
4206  endif
4207  if filename != "/" && filename =~ '/$'
4208   let filename= substitute(filename,'/$','','')
4209  endif
4210"  " call Dret("s:NetrwFullPath <".filename.">")
4211  return filename
4212endfun
4213
4214" ---------------------------------------------------------------------
4215" s:NetrwGetBuffer: [get a new|find an old netrw] buffer for a netrw listing {{{2
4216"   returns 0=cleared buffer
4217"           1=re-used buffer (buffer not cleared)
4218"  Nov 09, 2020: tst952 shows that when user does :set hidden that NetrwGetBuffer will come up with a [No Name] buffer (hid fix)
4219fun! s:NetrwGetBuffer(islocal,dirname)
4220"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
4221"  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>"))
4222"  call Decho("netrwbuf dictionary=".(exists("s:netrwbuf")? string(s:netrwbuf) : 'n/a'),'~'.expand("<slnum>"))
4223"  call Dredir("ls!","s:NetrwGetBuffer")
4224  let dirname= a:dirname
4225
4226  " re-use buffer if possible {{{3
4227"  call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
4228  if !exists("s:netrwbuf")
4229"   call Decho("  s:netrwbuf initialized to {}",'~'.expand("<slnum>"))
4230   let s:netrwbuf= {}
4231  endif
4232"  call Decho("  s:netrwbuf         =".string(s:netrwbuf),'~'.expand("<slnum>"))
4233"  call Decho("  w:netrw_liststyle  =".(exists("w:netrw_liststyle")? w:netrw_liststyle : "n/a"),'~'.expand("<slnum>"))
4234
4235  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4236   let bufnum = -1
4237
4238   if !empty(s:netrwbuf) && has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4239    if has_key(s:netrwbuf,"NetrwTreeListing")
4240     let bufnum= s:netrwbuf["NetrwTreeListing"]
4241    else
4242     let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4243    endif
4244"    call Decho("  NetrwTreeListing: bufnum#".bufnum,'~'.expand("<slnum>"))
4245    if !bufexists(bufnum)
4246     call remove(s:netrwbuf,"NetrwTreeListing"])
4247     let bufnum= -1
4248    endif
4249   elseif bufnr("NetrwTreeListing") != -1
4250    let bufnum= bufnr("NetrwTreeListing")
4251"    call Decho("  NetrwTreeListing".": bufnum#".bufnum,'~'.expand("<slnum>"))
4252   else
4253"    call Decho("  did not find a NetrwTreeListing buffer",'~'.expand("<slnum>"))
4254     let bufnum= -1
4255   endif
4256
4257  elseif has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4258   let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4259"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum,'~'.expand("<slnum>"))
4260   if !bufexists(bufnum)
4261    call remove(s:netrwbuf,s:NetrwFullPath(dirname))
4262    let bufnum= -1
4263   endif
4264
4265  else
4266"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key",'~'.expand("<slnum>"))
4267   let bufnum= -1
4268  endif
4269"  call Decho("  bufnum#".bufnum,'~'.expand("<slnum>"))
4270
4271  " hijack the current buffer
4272  "   IF the buffer already has the desired name
4273  "   AND it is empty
4274  let curbuf = bufname("%")
4275  if curbuf == '.'
4276   let curbuf = getcwd()
4277  endif
4278"  call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
4279"  call Decho("deciding if netrw may hijack the current buffer#".bufnr("%")."<".curbuf.">",'~'.expand("<slnum>"))
4280"  call Decho("..dirname<".dirname.">  IF dirname == bufname",'~'.expand("<slnum>"))
4281"  call Decho("..curbuf<".curbuf.">",'~'.expand("<slnum>"))
4282"  call Decho("..line($)=".line("$")." AND this is 1",'~'.expand("<slnum>"))
4283"  call Decho("..getline(%)<".getline("%").">  AND this line is empty",'~'.expand("<slnum>"))
4284  if dirname == curbuf && line("$") == 1 && getline("%") == ""
4285"   call Dret("s:NetrwGetBuffer 0<cleared buffer> : highjacking buffer#".bufnr("%"))
4286   return 0
4287  else  " DEBUG
4288"   call Decho("..did NOT hijack buffer",'~'.expand("<slnum>"))
4289  endif
4290  " Aug 14, 2021: was thinking about looking for a [No Name] buffer here and using it, but that might cause problems
4291
4292  " get enew buffer and name it -or- re-use buffer {{{3
4293  if bufnum < 0      " get enew buffer and name it
4294"   call Decho("--get enew buffer and name it  (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4295   call s:NetrwEnew(dirname)
4296"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4297   " name the buffer
4298   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4299    " Got enew buffer; transform into a NetrwTreeListing
4300"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4301    let w:netrw_treebufnr = bufnr("%")
4302    call s:NetrwBufRename("NetrwTreeListing")
4303    if g:netrw_use_noswf
4304     setl nobl bt=nofile noswf
4305    else
4306     setl nobl bt=nofile
4307    endif
4308    nnoremap <silent> <buffer> [[       :sil call <SID>TreeListMove('[[')<cr>
4309    nnoremap <silent> <buffer> ]]       :sil call <SID>TreeListMove(']]')<cr>
4310    nnoremap <silent> <buffer> []       :sil call <SID>TreeListMove('[]')<cr>
4311    nnoremap <silent> <buffer> ][       :sil call <SID>TreeListMove('][')<cr>
4312"    call Decho("  tree listing bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
4313   else
4314    call s:NetrwBufRename(dirname)
4315    " enter the new buffer into the s:netrwbuf dictionary
4316    let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%")
4317"    call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>"))
4318"    call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
4319   endif
4320"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4321
4322  else " Re-use the buffer
4323"   call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4324   let eikeep= &ei
4325   setl ei=all
4326   if getline(2) =~# '^" Netrw Directory Listing'
4327"    call Decho("  getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>"))
4328    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4329   else
4330"    call Decho("  getline(2)<".getline(2).'> does not match "Netrw Directory Listing" : using b '.bufnum,'~'.expand("<slnum>"))
4331    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4332   endif
4333"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
4334   if bufname("%") == '.'
4335    call s:NetrwBufRename(getcwd())
4336   endif
4337   let &ei= eikeep
4338
4339   if line("$") <= 1 && getline(1) == ""
4340    " empty buffer
4341    NetrwKeepj call s:NetrwListSettings(a:islocal)
4342"    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>"))
4343"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4344"    call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4345    return 0
4346
4347   elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4348"    call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4349    NetrwKeepj call s:NetrwListSettings(a:islocal)
4350    sil NetrwKeepj %d _
4351"    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>"))
4352"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4353"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4354    return 0
4355
4356   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4357"    call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4358"    call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4359    setl ma
4360    sil NetrwKeepj %d _
4361    NetrwKeepj call s:NetrwListSettings(a:islocal)
4362"    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>"))
4363"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4364"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4365    return 0
4366
4367   else
4368"    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>"))
4369"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4370"    call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4371    return 1
4372   endif
4373  endif
4374
4375  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4376  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
4377  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
4378  "  med    1         D      H
4379  "  fast   2         H      H
4380"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
4381  let fname= expand("%")
4382  NetrwKeepj call s:NetrwListSettings(a:islocal)
4383  call s:NetrwBufRename(fname)
4384
4385  " delete all lines from buffer {{{3
4386"  call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4387"  call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4388  sil! keepalt NetrwKeepj %d _
4389
4390"  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>"))
4391"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4392"  call Dret("s:NetrwGetBuffer 0<cleared buffer>")
4393  return 0
4394endfun
4395
4396" ---------------------------------------------------------------------
4397" s:NetrwGetcwd: get the current directory. {{{2
4398"   Change backslashes to forward slashes, if any.
4399"   If doesc is true, escape certain troublesome characters
4400fun! s:NetrwGetcwd(doesc)
4401"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
4402  let curdir= substitute(getcwd(),'\\','/','ge')
4403  if curdir !~ '[\/]$'
4404   let curdir= curdir.'/'
4405  endif
4406  if a:doesc
4407   let curdir= fnameescape(curdir)
4408  endif
4409"  call Dret("NetrwGetcwd <".curdir.">")
4410  return curdir
4411endfun
4412
4413" ---------------------------------------------------------------------
4414"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4415fun! s:NetrwGetWord()
4416"  call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4417"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4418  let keepsol= &l:sol
4419  setl nosol
4420
4421  call s:UseBufWinVars()
4422
4423  " insure that w:netrw_liststyle is set up
4424  if !exists("w:netrw_liststyle")
4425   if exists("g:netrw_liststyle")
4426    let w:netrw_liststyle= g:netrw_liststyle
4427   else
4428    let w:netrw_liststyle= s:THINLIST
4429   endif
4430"   call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
4431  endif
4432
4433  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4434   " Active Banner support
4435"   call Decho("active banner handling",'~'.expand("<slnum>"))
4436   NetrwKeepj norm! 0
4437   let dirname= "./"
4438   let curline= getline('.')
4439
4440   if curline =~# '"\s*Sorted by\s'
4441    NetrwKeepj norm! "_s
4442    let s:netrw_skipbrowse= 1
4443    echo 'Pressing "s" also works'
4444
4445   elseif curline =~# '"\s*Sort sequence:'
4446    let s:netrw_skipbrowse= 1
4447    echo 'Press "S" to edit sorting sequence'
4448
4449   elseif curline =~# '"\s*Quick Help:'
4450    NetrwKeepj norm! ?
4451    let s:netrw_skipbrowse= 1
4452
4453   elseif curline =~# '"\s*\%(Hiding\|Showing\):'
4454    NetrwKeepj norm! a
4455    let s:netrw_skipbrowse= 1
4456    echo 'Pressing "a" also works'
4457
4458   elseif line("$") > w:netrw_bannercnt
4459    exe 'sil NetrwKeepj '.w:netrw_bannercnt
4460   endif
4461
4462  elseif w:netrw_liststyle == s:THINLIST
4463"   call Decho("thin column handling",'~'.expand("<slnum>"))
4464   NetrwKeepj norm! 0
4465   let dirname= substitute(getline('.'),'\t -->.*$','','')
4466
4467  elseif w:netrw_liststyle == s:LONGLIST
4468"   call Decho("long column handling",'~'.expand("<slnum>"))
4469   NetrwKeepj norm! 0
4470   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
4471
4472  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4473"   call Decho("treelist handling",'~'.expand("<slnum>"))
4474   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4475   let dirname= substitute(dirname,'\t -->.*$','','')
4476
4477  else
4478"   call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4479   let dirname= getline('.')
4480
4481   if !exists("b:netrw_cpf")
4482    let b:netrw_cpf= 0
4483    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
4484    call histdel("/",-1)
4485"   "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4486   endif
4487
4488"   call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4489   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4490"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4491"   call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4492   if filestart == 0
4493    NetrwKeepj norm! 0ma
4494   else
4495    call cursor(line("."),filestart+1)
4496    NetrwKeepj norm! ma
4497   endif
4498   let rega= @a
4499   let eofname= filestart + b:netrw_cpf + 1
4500   if eofname <= col("$")
4501    call cursor(line("."),filestart+b:netrw_cpf+1)
4502    NetrwKeepj norm! "ay`a
4503   else
4504    NetrwKeepj norm! "ay$
4505   endif
4506   let dirname = @a
4507   let @a      = rega
4508"   call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4509   let dirname= substitute(dirname,'\s\+$','','e')
4510"   call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4511  endif
4512
4513  " symlinks are indicated by a trailing "@".  Remove it before further processing.
4514  let dirname= substitute(dirname,"@$","","")
4515
4516  " executables are indicated by a trailing "*".  Remove it before further processing.
4517  let dirname= substitute(dirname,"\*$","","")
4518
4519  let &l:sol= keepsol
4520
4521"  call Dret("s:NetrwGetWord <".dirname.">")
4522  return dirname
4523endfun
4524
4525" ---------------------------------------------------------------------
4526" s:NetrwListSettings: make standard settings for making a netrw listing {{{2
4527"                      g:netrw_bufsettings will be used after the listing is produced.
4528"                      Called by s:NetrwGetBuffer()
4529fun! s:NetrwListSettings(islocal)
4530"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4531"  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>"))
4532  let fname= bufname("%")
4533"  "  call Decho("setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
4534  "              nobl noma nomod nonu noma nowrap ro   nornu  (std g:netrw_bufsettings)
4535  setl bt=nofile nobl ma         nonu      nowrap noro nornu
4536  call s:NetrwBufRename(fname)
4537  if g:netrw_use_noswf
4538   setl noswf
4539  endif
4540"  call Dredir("ls!","s:NetrwListSettings")
4541"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
4542  exe "setl ts=".(g:netrw_maxfilenamelen+1)
4543  setl isk+=.,~,-
4544  if g:netrw_fastbrowse > a:islocal
4545   setl bh=hide
4546  else
4547   setl bh=delete
4548  endif
4549"  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>"))
4550"  call Dret("s:NetrwListSettings")
4551endfun
4552
4553" ---------------------------------------------------------------------
4554"  s:NetrwListStyle: change list style (thin - long - wide - tree) {{{2
4555"  islocal=0: remote browsing
4556"         =1: local browsing
4557fun! s:NetrwListStyle(islocal)
4558"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
4559
4560  let ykeep             = @@
4561  let fname             = s:NetrwGetWord()
4562  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
4563  let svpos            = winsaveview()
4564"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4565  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
4566"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
4567"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>"))
4568"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
4569
4570  " repoint t:netrw_lexbufnr if appropriate
4571  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
4572"   call Decho("set repointlexbufnr to true!")
4573   let repointlexbufnr= 1
4574  endif
4575
4576  if w:netrw_liststyle == s:THINLIST
4577   " use one column listing
4578"   call Decho("use one column list",'~'.expand("<slnum>"))
4579   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4580
4581  elseif w:netrw_liststyle == s:LONGLIST
4582   " use long list
4583"   call Decho("use long list",'~'.expand("<slnum>"))
4584   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
4585
4586  elseif w:netrw_liststyle == s:WIDELIST
4587   " give wide list
4588"   call Decho("use wide list",'~'.expand("<slnum>"))
4589   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4590
4591  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4592"   call Decho("use tree list",'~'.expand("<slnum>"))
4593   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4594
4595  else
4596   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4597   let g:netrw_liststyle = s:THINLIST
4598   let w:netrw_liststyle = g:netrw_liststyle
4599   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
4600  endif
4601  setl ma noro
4602"  call Decho("setl ma noro",'~'.expand("<slnum>"))
4603
4604  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
4605"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4606  sil! NetrwKeepj %d _
4607  " following prevents tree listing buffer from being marked "modified"
4608"  call Decho("setl nomod",'~'.expand("<slnum>"))
4609  setl nomod
4610"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4611
4612  " refresh the listing
4613"  call Decho("refresh the listing",'~'.expand("<slnum>"))
4614  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4615  NetrwKeepj call s:NetrwCursor(0)
4616
4617  " repoint t:netrw_lexbufnr if appropriate
4618  if exists("repointlexbufnr")
4619   let t:netrw_lexbufnr= bufnr("%")
4620"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
4621  endif
4622
4623  " restore position; keep cursor on the filename
4624"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4625  NetrwKeepj call winrestview(svpos)
4626  let @@= ykeep
4627
4628"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
4629endfun
4630
4631" ---------------------------------------------------------------------
4632" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4633fun! s:NetrwBannerCtrl(islocal)
4634"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
4635
4636  let ykeep= @@
4637  " toggle the banner (enable/suppress)
4638  let g:netrw_banner= !g:netrw_banner
4639
4640  " refresh the listing
4641  let svpos= winsaveview()
4642"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4643  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4644
4645  " keep cursor on the filename
4646  if g:netrw_banner && exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt
4647   let fname= s:NetrwGetWord()
4648   sil NetrwKeepj $
4649   let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4650" "  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4651   if result <= 0 && exists("w:netrw_bannercnt")
4652    exe "NetrwKeepj ".w:netrw_bannercnt
4653   endif
4654  endif
4655  let @@= ykeep
4656"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
4657endfun
4658
4659" ---------------------------------------------------------------------
4660" s:NetrwBookmark: supports :NetrwMB[!] [file]s                 {{{2
4661"
4662"  No bang: enters files/directories into Netrw's bookmark system
4663"   No argument and in netrw buffer:
4664"     if there are marked files: bookmark marked files
4665"     otherwise                : bookmark file/directory under cursor
4666"   No argument and not in netrw buffer: bookmarks current open file
4667"   Has arguments: globs them individually and bookmarks them
4668"
4669"  With bang: deletes files/directories from Netrw's bookmark system
4670fun! s:NetrwBookmark(del,...)
4671"  call Dfunc("s:NetrwBookmark(del=".a:del.",...) a:0=".a:0)
4672  if a:0 == 0
4673   if &ft == "netrw"
4674    let curbufnr = bufnr("%")
4675
4676    if exists("s:netrwmarkfilelist_{curbufnr}")
4677     " for every filename in the marked list
4678"     call Decho("bookmark every filename in marked list",'~'.expand("<slnum>"))
4679     let svpos  = winsaveview()
4680"     call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4681     let islocal= expand("%") !~ '^\a\{3,}://'
4682     for fname in s:netrwmarkfilelist_{curbufnr}
4683      if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4684     endfor
4685     let curdir  = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4686     call s:NetrwUnmarkList(curbufnr,curdir)
4687     NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./'))
4688"     call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4689     NetrwKeepj call winrestview(svpos)
4690    else
4691     let fname= s:NetrwGetWord()
4692     if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4693    endif
4694
4695   else
4696    " bookmark currently open file
4697"    call Decho("bookmark currently open file",'~'.expand("<slnum>"))
4698    let fname= expand("%")
4699    if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4700   endif
4701
4702  else
4703   " bookmark specified files
4704   "  attempts to infer if working remote or local
4705   "  by deciding if the current file begins with an url
4706   "  Globbing cannot be done remotely.
4707   let islocal= expand("%") !~ '^\a\{3,}://'
4708"   call Decho("bookmark specified file".((a:0>1)? "s" : ""),'~'.expand("<slnum>"))
4709   let i = 1
4710   while i <= a:0
4711    if islocal
4712     if v:version > 704 || (v:version == 704 && has("patch656"))
4713      let mbfiles= glob(fnameescape(a:{i}),0,1,1)
4714     else
4715      let mbfiles= glob(fnameescape(a:{i}),0,1)
4716     endif
4717    else
4718     let mbfiles= [a:{i}]
4719    endif
4720"    call Decho("mbfiles".string(mbfiles),'~'.expand("<slnum>"))
4721    for mbfile in mbfiles
4722"     call Decho("mbfile<".mbfile.">",'~'.expand("<slnum>"))
4723     if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4724    endfor
4725    let i= i + 1
4726   endwhile
4727  endif
4728
4729  " update the menu
4730  call s:NetrwBookmarkMenu()
4731
4732"  call Dret("s:NetrwBookmark")
4733endfun
4734
4735" ---------------------------------------------------------------------
4736" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4737"                      .2.[cnt] for bookmarks, and
4738"                      .3.[cnt] for history
4739"                      (see s:NetrwMenu())
4740fun! s:NetrwBookmarkMenu()
4741  if !exists("s:netrw_menucnt")
4742   return
4743  endif
4744"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhistcnt." menucnt=".s:netrw_menucnt)
4745
4746  " the following test assures that gvim is running, has menus available, and has menus enabled.
4747  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
4748   if exists("g:NetrwTopLvlMenu")
4749"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4750    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4751    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4752   endif
4753   if !exists("s:netrw_initbookhist")
4754    call s:NetrwBookHistRead()
4755   endif
4756
4757   " show bookmarked places
4758   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4759    let cnt= 1
4760    for bmd in g:netrw_bookmarklist
4761"     call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd,'~'.expand("<slnum>"))
4762     let bmd= escape(bmd,g:netrw_menu_escape)
4763
4764     " show bookmarks for goto menu
4765     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
4766
4767     " show bookmarks for deletion menu
4768     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
4769     let cnt= cnt + 1
4770    endfor
4771
4772   endif
4773
4774   " show directory browsing history
4775   if g:netrw_dirhistmax > 0
4776    let cnt     = g:netrw_dirhistcnt
4777    let first   = 1
4778    let histcnt = 0
4779    while ( first || cnt != g:netrw_dirhistcnt )
4780     let histcnt  = histcnt + 1
4781     let priority = g:netrw_dirhistcnt + histcnt
4782     if exists("g:netrw_dirhist_{cnt}")
4783      let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4784"     call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir,'~'.expand("<slnum>"))
4785      exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
4786     endif
4787     let first = 0
4788     let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
4789     if cnt < 0
4790      let cnt= cnt + g:netrw_dirhistmax
4791     endif
4792    endwhile
4793   endif
4794
4795  endif
4796"  call Dret("NetrwBookmarkMenu")
4797endfun
4798
4799" ---------------------------------------------------------------------
4800"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4801"                       directory and a new directory name.  Also, if the
4802"                       "new directory name" is actually a file,
4803"                       NetrwBrowseChgDir() edits the file.
4804fun! s:NetrwBrowseChgDir(islocal,newdir,...)
4805"  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 : "").">")
4806"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4807
4808  let ykeep= @@
4809  if !exists("b:netrw_curdir")
4810   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4811   " and the current window is the NetrwMessage window.
4812   let @@= ykeep
4813"   call Decho("b:netrw_curdir doesn't exist!",'~'.expand("<slnum>"))
4814"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
4815"   call Dredir("ls!","s:NetrwBrowseChgDir")
4816"   call Dret("s:NetrwBrowseChgDir")
4817   return
4818  endif
4819"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
4820
4821  " NetrwBrowseChgDir; save options and initialize {{{3
4822"  call Decho("saving options",'~'.expand("<slnum>"))
4823  call s:SavePosn(s:netrw_posn)
4824  NetrwKeepj call s:NetrwOptionsSave("s:")
4825  NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
4826  if (has("win32") || has("win95") || has("win64") || has("win16"))
4827   let dirname = substitute(b:netrw_curdir,'\\','/','ge')
4828  else
4829   let dirname = b:netrw_curdir
4830  endif
4831  let newdir    = a:newdir
4832  let dolockout = 0
4833  let dorestore = 1
4834"  call Decho("win#".winnr(),'~'.expand("<slnum>"))
4835"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
4836"  call Decho("newdir<".newdir.">",'~'.expand("<slnum>"))
4837
4838  " ignore <cr>s when done in the banner
4839"  call Decho('(s:NetrwBrowseChgDir) ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("<slnum>"))
4840  if g:netrw_banner
4841"   call Decho("win#".winnr()." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>"))
4842   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4843    if getline(".") =~# 'Quick Help'
4844"     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>"))
4845     let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4846"     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>"))
4847     setl ma noro nowrap
4848     NetrwKeepj call setline(line('.'),'"   Quick Help: <F1>:help  '.s:QuickHelp[g:netrw_quickhelp])
4849     setl noma nomod nowrap
4850     NetrwKeepj call s:NetrwOptionsRestore("s:")
4851"     call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4852    endif
4853   endif
4854"  else " Decho
4855"   call Decho("g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("<slnum>"))
4856  endif
4857
4858  " set up o/s-dependent directory recognition pattern
4859  if has("amiga")
4860   let dirpat= '[\/:]$'
4861  else
4862   let dirpat= '[\/]$'
4863  endif
4864"  call Decho("set up o/s-dependent directory recognition pattern: dirname<".dirname.">  dirpat<".dirpat.">",'~'.expand("<slnum>"))
4865
4866  if dirname !~ dirpat
4867   " apparently vim is "recognizing" that it is in a directory and
4868   " is removing the trailing "/".  Bad idea, so let's put it back.
4869   let dirname= dirname.'/'
4870"   call Decho("adjusting dirname<".dirname.'>  (put trailing "/" back)','~'.expand("<slnum>"))
4871  endif
4872
4873"  call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>"))
4874  if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
4875   " ------------------------------
4876   " NetrwBrowseChgDir: edit a file {{{3
4877   " ------------------------------
4878"   call Decho('edit-a-file: case "handling a file": win#'.winnr().' newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>"))
4879
4880   " save position for benefit of Rexplore
4881   let s:rexposn_{bufnr("%")}= winsaveview()
4882"   call Decho("edit-a-file: saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
4883"   call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
4884"   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>"))
4885
4886   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4887"    call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("<slnum>"))
4888"    call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("<slnum>"))
4889"    let newdir = s:NetrwTreePath(s:netrw_treetop)
4890"    call Decho("edit-a-file: COMBAK why doesn't this recognize file1's directory???")
4891    let dirname= s:NetrwTreeDir(a:islocal)
4892    "COMBAK : not working for a symlink -- but what about a regular file? a directory?
4893"    call Decho("COMBAK : not working for a symlink -- but what about a regular file? a directory?")
4894    " Feb 17, 2019: following if-else-endif restored -- wasn't editing a file in tree mode
4895    if dirname =~ '/$'
4896     let dirname= dirname.newdir
4897    else
4898     let dirname= dirname."/".newdir
4899    endif
4900"    call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>"))
4901"    call Decho("edit-a-file: tree listing",'~'.expand("<slnum>"))
4902   elseif newdir =~ '^\(/\|\a:\)'
4903"    call Decho("edit-a-file: handle an url or path starting with /: <".newdir.">",'~'.expand("<slnum>"))
4904    let dirname= newdir
4905   else
4906    let dirname= s:ComposePath(dirname,newdir)
4907   endif
4908"   call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>"))
4909   " this lets netrw#BrowseX avoid the edit
4910   if a:0 < 1
4911"    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>"))
4912    NetrwKeepj call s:NetrwOptionsRestore("s:")
4913    let curdir= b:netrw_curdir
4914    if !exists("s:didsplit")
4915"     "     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>"))
4916     if type(g:netrw_browse_split) == 3
4917      " open file in server
4918      " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4919"      call Decho("edit-a-file: open file in server",'~'.expand("<slnum>"))
4920      call s:NetrwServerEdit(a:islocal,dirname)
4921"      call Dret("s:NetrwBrowseChgDir")
4922      return
4923
4924     elseif g:netrw_browse_split == 1
4925      " horizontally splitting the window first
4926"      call Decho("edit-a-file: horizontally splitting window prior to edit",'~'.expand("<slnum>"))
4927      let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
4928      exe "keepalt ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
4929      if !&ea
4930       keepalt wincmd _
4931      endif
4932      call s:SetRexDir(a:islocal,curdir)
4933
4934     elseif g:netrw_browse_split == 2
4935      " vertically splitting the window first
4936"      call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>"))
4937      let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
4938      exe "keepalt ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
4939      if !&ea
4940       keepalt wincmd |
4941      endif
4942      call s:SetRexDir(a:islocal,curdir)
4943
4944     elseif g:netrw_browse_split == 3
4945      " open file in new tab
4946"      call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>"))
4947      keepalt tabnew
4948      if !exists("b:netrw_curdir")
4949       let b:netrw_curdir= getcwd()
4950      endif
4951      call s:SetRexDir(a:islocal,curdir)
4952
4953     elseif g:netrw_browse_split == 4
4954      " act like "P" (ie. open previous window)
4955"      call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>"))
4956      if s:NetrwPrevWinOpen(2) == 3
4957       let @@= ykeep
4958"       call Dret("s:NetrwBrowseChgDir")
4959       return
4960      endif
4961      call s:SetRexDir(a:islocal,curdir)
4962
4963     else
4964      " handling a file, didn't split, so remove menu
4965"      call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>"))
4966      call s:NetrwMenu(0)
4967      " optional change to window
4968      if g:netrw_chgwin >= 1
4969"       call Decho("edit-a-file: changing window to #".g:netrw_chgwin.": (due to g:netrw_chgwin)",'~'.expand("<slnum>"))
4970       if winnr("$")+1 == g:netrw_chgwin
4971	" if g:netrw_chgwin is set to one more than the last window, then
4972	" vertically split the last window to make that window available.
4973	let curwin= winnr()
4974	exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4975	vs
4976	exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4977       endif
4978       exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4979      endif
4980      call s:SetRexDir(a:islocal,curdir)
4981     endif
4982
4983    endif
4984
4985    " the point where netrw actually edits the (local) file
4986    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4987    " no keepalt to support  :e #  to return to a directory listing
4988    if !&mod
4989     " if e the new file would fail due to &mod, then don't change any of the flags
4990     let dolockout= 1
4991    endif
4992    if a:islocal
4993"     call Decho("edit-a-file: edit local file: exe e! ".fnameescape(dirname),'~'.expand("<slnum>"))
4994     " some like c-^ to return to the last edited file
4995     " others like c-^ to return to the netrw buffer
4996     " Apr 30, 2020: used to have e! here.  That can cause loss of a modified file,
4997     " so emit error E37 instead.
4998     if exists("g:netrw_altfile") && g:netrw_altfile
4999      exe "NetrwKeepj keepalt e ".fnameescape(dirname)
5000     else
5001      exe "NetrwKeepj e ".fnameescape(dirname)
5002     endif
5003"     call Decho("edit-a-file: after e! ".dirname.": hidden=".&hidden." bufhidden<".&bufhidden."> mod=".&mod,'~'.expand("<slnum>"))
5004     " COMBAK -- cuc cul related
5005     call s:NetrwCursor(1)
5006     if &hidden || &bufhidden == "hide"
5007      " file came from vim's hidden storage.  Don't "restore" options with it.
5008      let dorestore= 0
5009     endif
5010    else
5011"     call Decho("edit-a-file: remote file: NetrwBrowse will edit it",'~'.expand("<slnum>"))
5012    endif
5013
5014    " handle g:Netrw_funcref -- call external-to-netrw functions
5015    "   This code will handle g:Netrw_funcref as an individual function reference
5016    "   or as a list of function references.  It will ignore anything that's not
5017    "   a function reference.  See  :help Funcref  for information about function references.
5018    if exists("g:Netrw_funcref")
5019"     call Decho("edit-a-file: handle optional Funcrefs",'~'.expand("<slnum>"))
5020     if type(g:Netrw_funcref) == 2
5021"      call Decho("edit-a-file: handling a g:Netrw_funcref",'~'.expand("<slnum>"))
5022      NetrwKeepj call g:Netrw_funcref()
5023     elseif type(g:Netrw_funcref) == 3
5024"      call Decho("edit-a-file: handling a list of g:Netrw_funcrefs",'~'.expand("<slnum>"))
5025      for Fncref in g:Netrw_funcref
5026       if type(Fncref) == 2
5027        NetrwKeepj call Fncref()
5028       endif
5029      endfor
5030     endif
5031    endif
5032   endif
5033
5034  elseif newdir =~ '^/'
5035   " ----------------------------------------------------
5036   " NetrwBrowseChgDir: just go to the new directory spec {{{3
5037   " ----------------------------------------------------
5038"   call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("<slnum>"))
5039   let dirname = newdir
5040   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5041   NetrwKeepj call s:NetrwOptionsRestore("s:")
5042   norm! m`
5043
5044  elseif newdir == './'
5045   " ---------------------------------------------
5046   " NetrwBrowseChgDir: refresh the directory list {{{3
5047   " ---------------------------------------------
5048"   call Decho('(s:NetrwBrowseChgDir)refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("<slnum>"))
5049   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5050   norm! m`
5051
5052  elseif newdir == '../'
5053   " --------------------------------------
5054   " NetrwBrowseChgDir: go up one directory {{{3
5055   " --------------------------------------
5056"   call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../"','~'.expand("<slnum>"))
5057
5058   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5059    " force a refresh
5060"    call Decho("go-up: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
5061"    call Decho("go-up: setl noro ma",'~'.expand("<slnum>"))
5062    setl noro ma
5063    NetrwKeepj %d _
5064   endif
5065
5066   if has("amiga")
5067    " amiga
5068"    call Decho('go-up: case "go up one directory": newdir == "../" and amiga','~'.expand("<slnum>"))
5069    if a:islocal
5070     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
5071     let dirname= substitute(dirname,'/$','','')
5072    else
5073     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
5074    endif
5075"    call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5076
5077   elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
5078    " windows
5079    if a:islocal
5080     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
5081     if dirname == ""
5082      let dirname= '/'
5083     endif
5084    else
5085     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
5086    endif
5087    if dirname =~ '^\a:$'
5088     let dirname= dirname.'/'
5089    endif
5090"    call Decho("go-up: windows: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5091
5092   else
5093    " unix or cygwin
5094"    call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("<slnum>"))
5095    if a:islocal
5096     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
5097     if dirname == ""
5098      let dirname= '/'
5099     endif
5100    else
5101     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
5102    endif
5103"    call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5104   endif
5105   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5106   norm! m`
5107
5108  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5109   " --------------------------------------
5110   " NetrwBrowseChgDir: Handle Tree Listing {{{3
5111   " --------------------------------------
5112"   call Decho('(s:NetrwBrowseChgDir)tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("<slnum>"))
5113   " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
5114"   call Decho("tree-list: setl noro ma",'~'.expand("<slnum>"))
5115   setl noro ma
5116   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
5117"    call Decho("tree-list: clear buffer<".expand("%")."> with :%d  (force refresh)",'~'.expand("<slnum>"))
5118    NetrwKeepj %d _
5119   endif
5120   let treedir      = s:NetrwTreeDir(a:islocal)
5121"   call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>"))
5122   let s:treecurpos = winsaveview()
5123   let haskey       = 0
5124"   call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
5125
5126   " search treedict for tree dir as-is
5127"   call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("<slnum>"))
5128   if has_key(w:netrw_treedict,treedir)
5129"    call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>"))
5130    let haskey= 1
5131   else
5132"    call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
5133   endif
5134
5135   " search treedict for treedir with a [/@] appended
5136"   call Decho("tree-list: search treedict for treedir with a [/@] appended",'~'.expand("<slnum>"))
5137   if !haskey && treedir !~ '[/@]$'
5138    if has_key(w:netrw_treedict,treedir."/")
5139     let treedir= treedir."/"
5140"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
5141     let haskey = 1
5142    else
5143"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("<slnum>"))
5144    endif
5145   endif
5146
5147   " search treedict for treedir with any trailing / elided
5148"   call Decho("tree-list: search treedict for treedir with any trailing / elided",'~'.expand("<slnum>"))
5149   if !haskey && treedir =~ '/$'
5150    let treedir= substitute(treedir,'/$','','')
5151    if has_key(w:netrw_treedict,treedir)
5152"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
5153     let haskey = 1
5154    else
5155"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
5156    endif
5157   endif
5158
5159"   call Decho("haskey=".haskey,'~'.expand("<slnum>"))
5160   if haskey
5161    " close tree listing for selected subdirectory
5162"    call Decho("tree-list: closing selected subdirectory<".dirname.">",'~'.expand("<slnum>"))
5163    call remove(w:netrw_treedict,treedir)
5164"    call Decho("tree-list: removed     entry<".treedir."> from treedict",'~'.expand("<slnum>"))
5165"    call Decho("tree-list: yielding treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
5166    let dirname= w:netrw_treetop
5167   else
5168    " go down one directory
5169    let dirname= substitute(treedir,'/*$','/','')
5170"    call Decho("tree-list: go down one dir: treedir<".treedir.">",'~'.expand("<slnum>"))
5171"    call Decho("tree-list: ...            : dirname<".dirname.">",'~'.expand("<slnum>"))
5172   endif
5173   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5174"   call Decho("setting s:treeforceredraw to true",'~'.expand("<slnum>"))
5175   let s:treeforceredraw = 1
5176
5177  else
5178   " ----------------------------------------
5179   " NetrwBrowseChgDir: Go down one directory {{{3
5180   " ----------------------------------------
5181   let dirname    = s:ComposePath(dirname,newdir)
5182"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("<slnum>"))
5183   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5184   norm! m`
5185  endif
5186
5187 " --------------------------------------
5188 " NetrwBrowseChgDir: Restore and Cleanup {{{3
5189 " --------------------------------------
5190  if dorestore
5191   " dorestore is zero'd when a local file was hidden or bufhidden;
5192   " in such a case, we want to keep whatever settings it may have.
5193"   call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("<slnum>"))
5194   NetrwKeepj call s:NetrwOptionsRestore("s:")
5195"  else " Decho
5196"   call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>"))
5197  endif
5198  if dolockout && dorestore
5199"   call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>"))
5200   if filewritable(dirname)
5201"    call Decho("restore: doing modification lockout settings: ma nomod noro",'~'.expand("<slnum>"))
5202"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5203    setl ma noro nomod
5204"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5205   else
5206"    call Decho("restore: doing modification lockout settings: ma nomod ro",'~'.expand("<slnum>"))
5207"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5208    setl ma ro nomod
5209"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5210   endif
5211  endif
5212  call s:RestorePosn(s:netrw_posn)
5213  let @@= ykeep
5214
5215"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
5216  return dirname
5217endfun
5218
5219" ---------------------------------------------------------------------
5220" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
5221"    for thin, long, and wide: cursor placed just after banner
5222"    for tree, keeps cursor on current filename
5223fun! s:NetrwBrowseUpDir(islocal)
5224"  call Dfunc("s:NetrwBrowseUpDir(islocal=".a:islocal.")")
5225  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
5226   " this test needed because occasionally this function seems to be incorrectly called
5227   " when multiple leftmouse clicks are taken when atop the one line help in the banner.
5228   " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
5229   " directories.
5230"   call Dret("s:NetrwBrowseUpDir : cursor not in file area")
5231   return
5232  endif
5233
5234  norm! 0
5235  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5236"   call Decho("case: treestyle",'~'.expand("<slnum>"))
5237   let curline= getline(".")
5238   let swwline= winline() - 1
5239   if exists("w:netrw_treetop")
5240    let b:netrw_curdir= w:netrw_treetop
5241   elseif exists("b:netrw_curdir")
5242    let w:netrw_treetop= b:netrw_curdir
5243   else
5244    let w:netrw_treetop= getcwd()
5245    let b:netrw_curdir = w:netrw_treetop
5246   endif
5247   let curfile = getline(".")
5248   let curpath = s:NetrwTreePath(w:netrw_treetop)
5249   if a:islocal
5250    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5251   else
5252    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5253   endif
5254"   call Decho("looking for curfile<^".s:treedepthstring.curfile.">",'~'.expand("<slnum>"))
5255"   call Decho("having      curpath<".curpath.">",'~'.expand("<slnum>"))
5256   if w:netrw_treetop == '/'
5257     keepj call search('^\M'.curfile,"w")
5258   elseif curfile == '../'
5259     keepj call search('^\M'.curfile,"wb")
5260   else
5261"    call Decho("search(^\\M".s:treedepthstring.curfile.") backwards"))
5262    while 1
5263     keepj call search('^\M'.s:treedepthstring.curfile,"wb")
5264     let treepath= s:NetrwTreePath(w:netrw_treetop)
5265"     call Decho("..current treepath<".treepath.">",'~'.expand("<slnum>"))
5266     if treepath == curpath
5267      break
5268     endif
5269    endwhile
5270   endif
5271
5272  else
5273"   call Decho("case: not treestyle",'~'.expand("<slnum>"))
5274   call s:SavePosn(s:netrw_posn)
5275   if exists("b:netrw_curdir")
5276    let curdir= b:netrw_curdir
5277   else
5278    let curdir= expand(getcwd())
5279   endif
5280   if a:islocal
5281    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5282   else
5283    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5284   endif
5285   call s:RestorePosn(s:netrw_posn)
5286   let curdir= substitute(curdir,'^.*[\/]','','')
5287   call search('\<'.curdir.'/','wc')
5288  endif
5289"  call Dret("s:NetrwBrowseUpDir")
5290endfun
5291
5292" ---------------------------------------------------------------------
5293" netrw#BrowseX:  (implements "x" and "gx") executes a special "viewer" script or program for the {{{2
5294"              given filename; typically this means given their extension.
5295"              0=local, 1=remote
5296fun! netrw#BrowseX(fname,remote)
5297  let use_ctrlo= 1
5298"  call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")  implements x and gx maps")
5299
5300  if a:remote == 0 && isdirectory(a:fname)
5301   " if its really just a local directory, then do a "gf" instead
5302"   call Decho("remote≡0 and a:fname<".a:fname."> ".(isdirectory(a:fname)? "is a directory" : "is not a directory"),'~'.expand("<slnum>"))
5303"   call Decho("..appears to be a local directory; using e ".a:fname." instead",'~'.expand("<slnum>"))
5304   exe "e ".a:fname
5305"   call Dret("netrw#BrowseX")
5306   return
5307  elseif a:remote == 1 && a:fname !~ '^https\=:' && a:fname =~ '/$'
5308   " remote directory, not a webpage access, looks like an attempt to do a directory listing
5309"   call Decho("remote≡1 and a:fname<".a:fname.">",'~'.expand("<slnum>"))
5310"   call Decho("..and fname ".((a:fname =~ '^https\=:')? 'matches' : 'does not match').'^https\=:','~'.expand("<slnum>"))
5311"   call Decho("..and fname ".((a:fname =~ '/$')?        'matches' : 'does not match').' /$','~'.expand("<slnum>"))
5312"   call Decho("..appears to be a remote directory listing request; using gf instead",'~'.expand("<slnum>"))
5313   norm! gf
5314"   call Dret("netrw#BrowseX")
5315   return
5316  endif
5317"  call Decho("not a local file nor a webpage request",'~'.expand("<slnum>"))
5318
5319  if exists("g:netrw_browsex_viewer") && exists("g:netrw_browsex_support_remote") && !g:netrw_browsex_support_remote
5320    let remote = a:remote
5321  else
5322    let remote = 0
5323  endif
5324
5325  let ykeep      = @@
5326  let screenposn = winsaveview()
5327"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5328
5329  " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
5330  let awkeep     = &aw
5331  set noaw
5332
5333  " special core dump handler
5334  if a:fname =~ '/core\(\.\d\+\)\=$'
5335   if exists("g:Netrw_corehandler")
5336    if type(g:Netrw_corehandler) == 2
5337     " g:Netrw_corehandler is a function reference (see :help Funcref)
5338"     call Decho("g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
5339     call g:Netrw_corehandler(s:NetrwFile(a:fname))
5340    elseif type(g:Netrw_corehandler) == 3
5341     " g:Netrw_corehandler is a List of function references (see :help Funcref)
5342"     call Decho("g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
5343     for Fncref in g:Netrw_corehandler
5344      if type(FncRef) == 2
5345       call FncRef(a:fname)
5346      endif
5347     endfor
5348    endif
5349"    call Decho("restoring posn: screenposn<".string(screenposn).">,'~'.expand("<slnum>"))"
5350    call winrestview(screenposn)
5351    let @@= ykeep
5352    let &aw= awkeep
5353"    call Dret("netrw#BrowseX : coredump handler invoked")
5354    return
5355   endif
5356  endif
5357
5358  " set up the filename
5359  " (lower case the extension, make a local copy of a remote file)
5360  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5361  if has("win32") || has("win95") || has("win64") || has("win16")
5362   let exten= substitute(exten,'^.*$','\L&\E','')
5363  endif
5364  if exten =~ "[\\/]"
5365   let exten= ""
5366  endif
5367"  call Decho("exten<".exten.">",'~'.expand("<slnum>"))
5368
5369  if remote == 1
5370   " create a local copy
5371"   call Decho("remote: remote=".remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
5372   setl bh=delete
5373   call netrw#NetRead(3,a:fname)
5374   " attempt to rename tempfile
5375   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5376   let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5377"   call Decho("basename<".basename.">",'~'.expand("<slnum>"))
5378"   call Decho("newname <".newname.">",'~'.expand("<slnum>"))
5379   if s:netrw_tmpfile != newname && newname != ""
5380    if rename(s:netrw_tmpfile,newname) == 0
5381     " renaming succeeded
5382"     call Decho("renaming succeeded (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5383     let fname= newname
5384    else
5385     " renaming failed
5386"     call Decho("renaming failed (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5387     let fname= s:netrw_tmpfile
5388    endif
5389   else
5390    let fname= s:netrw_tmpfile
5391   endif
5392  else
5393"   call Decho("local: remote=".remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
5394   let fname= a:fname
5395   " special ~ handler for local
5396   if fname =~ '^\~' && expand("$HOME") != ""
5397"    call Decho('invoking special ~ handler','~'.expand("<slnum>"))
5398    let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5399   endif
5400  endif
5401"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
5402"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
5403
5404  " set up redirection (avoids browser messages)
5405  " by default, g:netrw_suppress_gx_mesg is true
5406  if g:netrw_suppress_gx_mesg
5407   if &srr =~ "%s"
5408    if (has("win32") || has("win95") || has("win64") || has("win16"))
5409     let redir= substitute(&srr,"%s","nul","")
5410    else
5411     let redir= substitute(&srr,"%s","/dev/null","")
5412    endif
5413   elseif (has("win32") || has("win95") || has("win64") || has("win16"))
5414    let redir= &srr . "nul"
5415   else
5416    let redir= &srr . "/dev/null"
5417   endif
5418  endif
5419"  call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
5420
5421  " extract any viewing options.  Assumes that they're set apart by spaces.
5422  if exists("g:netrw_browsex_viewer")
5423"   call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5424   if g:netrw_browsex_viewer =~ '\s'
5425    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5426    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5427    let oviewer = ''
5428    let cnt     = 1
5429    while !executable(viewer) && viewer != oviewer
5430     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5431     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5432     let cnt     = cnt + 1
5433     let oviewer = viewer
5434"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5435    endwhile
5436   else
5437    let viewer  = g:netrw_browsex_viewer
5438    let viewopt = ""
5439   endif
5440"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5441  endif
5442
5443  " execute the file handler
5444"  call Decho("execute the file handler (if any)",'~'.expand("<slnum>"))
5445  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
5446"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5447   let ret= netrwFileHandlers#Invoke(exten,fname)
5448
5449  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
5450"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5451   call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
5452   let ret= v:shell_error
5453
5454  elseif has("win32") || has("win64")
5455"   call Decho("(netrw#BrowseX) win".(has("win32")? "32" : "64"),'~'.expand("<slnum>"))
5456   if executable("start")
5457    call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5458   elseif executable("rundll32")
5459    call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5460   else
5461    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5462   endif
5463   let ret= v:shell_error
5464
5465  elseif has("win32unix")
5466   let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
5467"   call Decho("(netrw#BrowseX) cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
5468   if executable("start")
5469"    call Decho("(netrw#BrowseX) win32unix+start",'~'.expand("<slnum>"))
5470    call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5471   elseif executable("rundll32")
5472"    call Decho("(netrw#BrowseX) win32unix+rundll32",'~'.expand("<slnum>"))
5473    call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5474   elseif executable("cygstart")
5475"    call Decho("(netrw#BrowseX) win32unix+cygstart",'~'.expand("<slnum>"))
5476    call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
5477   else
5478    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5479   endif
5480   let ret= v:shell_error
5481
5482  elseif has("unix") && $DESKTOP_SESSION == "mate" && executable("atril")
5483"   call Decho("(netrw#BrowseX) unix and atril",'~'.expand("<slnum>"))
5484   if a:fname =~ '^https\=://'
5485    " atril does not appear to understand how to handle html -- so use gvim to edit the document
5486    let use_ctrlo= 0
5487"    call Decho("fname<".fname.">")
5488"    call Decho("a:fname<".a:fname.">")
5489    call s:NetrwExe("sil! !gvim ".fname.' -c "keepj keepalt file '.fnameescape(a:fname).'"')
5490
5491   else
5492    call s:NetrwExe("sil !atril ".s:ShellEscape(fname,1).redir)
5493   endif
5494   let ret= v:shell_error
5495
5496  elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
5497"   call Decho("(netrw#BrowseX) unix and kfmclient",'~'.expand("<slnum>"))
5498   call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
5499   let ret= v:shell_error
5500
5501  elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
5502"   call Decho("(netrw#BrowseX) unix, exo-open, xdg-open",'~'.expand("<slnum>"))
5503   call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir.'&')
5504   let ret= v:shell_error
5505
5506  elseif has("unix") && executable("xdg-open")
5507"   call Decho("(netrw#BrowseX) unix and xdg-open",'~'.expand("<slnum>"))
5508   call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir.'&')
5509   let ret= v:shell_error
5510
5511  elseif has("macunix") && executable("open")
5512"   call Decho("(netrw#BrowseX) macunix and open",'~'.expand("<slnum>"))
5513   call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
5514   let ret= v:shell_error
5515
5516  else
5517   " netrwFileHandlers#Invoke() always returns 0
5518"   call Decho("(netrw#BrowseX) use netrwFileHandlers",'~'.expand("<slnum>"))
5519   let ret= netrwFileHandlers#Invoke(exten,fname)
5520  endif
5521
5522  " if unsuccessful, attempt netrwFileHandlers#Invoke()
5523  if ret
5524"   call Decho("(netrw#BrowseX) ret=".ret," indicates unsuccessful thus far",'~'.expand("<slnum>"))
5525   let ret= netrwFileHandlers#Invoke(exten,fname)
5526  endif
5527
5528  " restoring redraw! after external file handlers
5529  redraw!
5530
5531  " cleanup: remove temporary file,
5532  "          delete current buffer if success with handler,
5533  "          return to prior buffer (directory listing)
5534  "          Feb 12, 2008: had to de-activiate removal of
5535  "          temporary file because it wasn't getting seen.
5536"  if remote == 1 && fname != a:fname
5537""   call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
5538"   call s:NetrwDelete(fname)
5539"  endif
5540
5541  if remote == 1
5542   setl bh=delete bt=nofile
5543   if g:netrw_use_noswf
5544    setl noswf
5545   endif
5546   if use_ctrlo
5547    exe "sil! NetrwKeepj norm! \<c-o>"
5548   endif
5549  endif
5550"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5551  call winrestview(screenposn)
5552  let @@ = ykeep
5553  let &aw= awkeep
5554
5555"  call Dret("netrw#BrowseX")
5556endfun
5557
5558" ---------------------------------------------------------------------
5559" netrw#GX: gets word under cursor for gx support {{{2
5560"           See also: netrw#BrowseXVis
5561"                     netrw#BrowseX
5562fun! netrw#GX()
5563"  call Dfunc("netrw#GX()")
5564  if &ft == "netrw"
5565   let fname= s:NetrwGetWord()
5566  else
5567   let fname= expand((exists("g:netrw_gx")? g:netrw_gx : '<cfile>'))
5568  endif
5569"  call Dret("netrw#GX <".fname.">")
5570  return fname
5571endfun
5572
5573" ---------------------------------------------------------------------
5574" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5575fun! netrw#BrowseXVis()
5576"  call Dfunc("netrw#BrowseXVis()")
5577  let akeep = @a
5578  norm! gv"ay
5579  let gxfile= @a
5580  let @a    = akeep
5581  call netrw#BrowseX(gxfile,netrw#CheckIfRemote(gxfile))
5582"  call Dret("netrw#BrowseXVis")
5583endfun
5584
5585" ---------------------------------------------------------------------
5586" s:NetrwBufRename: renames a buffer without the side effect of retaining an unlisted buffer having the old name {{{2
5587"                   Using the file command on a "[No Name]" buffer does not seem to cause the old "[No Name]" buffer
5588"                   to become an unlisted buffer, so in that case don't bwipe it.
5589fun! s:NetrwBufRename(newname)
5590"  call Dfunc("s:NetrwBufRename(newname<".a:newname.">) buf(%)#".bufnr("%")."<".bufname(bufnr("%")).">")
5591"  call Dredir("ls!","s:NetrwBufRename (before rename)")
5592  let oldbufname= bufname(bufnr("%"))
5593"  call Decho("buf#".bufnr("%").": oldbufname<".oldbufname.">",'~'.expand("<slnum>"))
5594
5595  if oldbufname != a:newname
5596"   call Decho("do buffer rename: oldbufname<".oldbufname."> ≠ a:newname<".a:newname.">",'~'.expand("<slnum>"))
5597   let b:junk= 1
5598"   call Decho("rename buffer: sil! keepj keepalt file ".fnameescape(a:newname),'~'.expand("<slnum>"))
5599   exe 'sil! keepj keepalt file '.fnameescape(a:newname)
5600"   call Dredir("ls!","s:NetrwBufRename (before bwipe)~".expand("<slnum>"))
5601   let oldbufnr= bufnr(oldbufname)
5602"   call Decho("oldbufname<".oldbufname."> oldbufnr#".oldbufnr,'~'.expand("<slnum>"))
5603"   call Decho("bufnr(%)=".bufnr("%"),'~'.expand("<slnum>"))
5604   if oldbufname != "" && oldbufnr != -1 && oldbufnr != bufnr("%")
5605"    call Decho("bwipe ".oldbufnr,'~'.expand("<slnum>"))
5606    exe "bwipe! ".oldbufnr
5607"   else " Decho
5608"    call Decho("did *not* bwipe buf#".oldbufnr,'~'.expand("<slnum>"))
5609"    call Decho("..reason: if oldbufname<".oldbufname."> is empty",'~'.expand("<slnum>"))"
5610"    call Decho("..reason: if oldbufnr#".oldbufnr." is -1",'~'.expand("<slnum>"))"
5611"    call Decho("..reason: if oldbufnr#".oldbufnr." != bufnr(%)#".bufnr("%"),'~'.expand("<slnum>"))"
5612   endif
5613"   call Dredir("ls!","s:NetrwBufRename (after rename)")
5614"  else " Decho
5615"   call Decho("oldbufname<".oldbufname."> == a:newname: did *not* rename",'~'.expand("<slnum>"))
5616  endif
5617
5618"  call Dret("s:NetrwBufRename : buf#".bufnr("%").": oldname<".oldbufname."> newname<".a:newname."> expand(%)<".expand("%").">")
5619endfun
5620
5621" ---------------------------------------------------------------------
5622" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5623fun! netrw#CheckIfRemote(...)
5624"  call Dfunc("netrw#CheckIfRemote() a:0=".a:0)
5625  if a:0 > 0
5626   let curfile= a:1
5627  else
5628   let curfile= expand("%")
5629  endif
5630"  call Decho("curfile<".curfile.">")
5631  if curfile =~ '^\a\{3,}://'
5632"   call Dret("netrw#CheckIfRemote 1")
5633   return 1
5634  else
5635"   call Dret("netrw#CheckIfRemote 0")
5636   return 0
5637  endif
5638endfun
5639
5640" ---------------------------------------------------------------------
5641" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5642fun! s:NetrwChgPerm(islocal,curdir)
5643"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
5644  let ykeep  = @@
5645  call inputsave()
5646  let newperm= input("Enter new permission: ")
5647  call inputrestore()
5648  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5649  let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5650"  call Decho("chgperm<".chgperm.">",'~'.expand("<slnum>"))
5651  call system(chgperm)
5652  if v:shell_error != 0
5653   NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5654  endif
5655  if a:islocal
5656   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5657  endif
5658  let @@= ykeep
5659"  call Dret("s:NetrwChgPerm")
5660endfun
5661
5662" ---------------------------------------------------------------------
5663" s:CheckIfKde: checks if kdeinit is running {{{2
5664"    Returns 0: kdeinit not running
5665"            1: kdeinit is  running
5666fun! s:CheckIfKde()
5667"  call Dfunc("s:CheckIfKde()")
5668  " seems kde systems often have gnome-open due to dependencies, even though
5669  " gnome-open's subsidiary display tools are largely absent.  Kde systems
5670  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
5671  if !exists("s:haskdeinit")
5672   if has("unix") && executable("ps") && !has("win32unix")
5673    let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5674    if v:shell_error
5675     let s:haskdeinit = 0
5676    endif
5677   else
5678    let s:haskdeinit= 0
5679   endif
5680"   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5681  endif
5682
5683"  call Dret("s:CheckIfKde ".s:haskdeinit)
5684  return s:haskdeinit
5685endfun
5686
5687" ---------------------------------------------------------------------
5688" s:NetrwClearExplore: clear explore variables (if any) {{{2
5689fun! s:NetrwClearExplore()
5690"  call Dfunc("s:NetrwClearExplore()")
5691  2match none
5692  if exists("s:explore_match")        |unlet s:explore_match        |endif
5693  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
5694  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5695  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
5696  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
5697  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
5698  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5699  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
5700  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
5701"   redraw!
5702  echo " "
5703  echo " "
5704"  call Dret("s:NetrwClearExplore")
5705endfun
5706
5707" ---------------------------------------------------------------------
5708" s:NetrwExploreListUniq: {{{2
5709fun! s:NetrwExploreListUniq(explist)
5710"  call Dfunc("s:NetrwExploreListUniq(explist<".string(a:explist).">)")
5711
5712  " this assumes that the list is already sorted
5713  let newexplist= []
5714  for member in a:explist
5715   if !exists("uniqmember") || member != uniqmember
5716    let uniqmember = member
5717    let newexplist = newexplist + [ member ]
5718   endif
5719  endfor
5720
5721"  call Dret("s:NetrwExploreListUniq newexplist<".string(newexplist).">")
5722  return newexplist
5723endfun
5724
5725" ---------------------------------------------------------------------
5726" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5727fun! s:NetrwForceChgDir(islocal,newdir)
5728"  call Dfunc("s:NetrwForceChgDir(islocal=".a:islocal." newdir<".a:newdir.">)")
5729  let ykeep= @@
5730  if a:newdir !~ '/$'
5731   " ok, looks like force is needed to get directory-style treatment
5732   if a:newdir =~ '@$'
5733    let newdir= substitute(a:newdir,'@$','/','')
5734   elseif a:newdir =~ '[*=|\\]$'
5735    let newdir= substitute(a:newdir,'.$','/','')
5736   else
5737    let newdir= a:newdir.'/'
5738   endif
5739"   call Decho("adjusting newdir<".newdir."> due to gd",'~'.expand("<slnum>"))
5740  else
5741   " should already be getting treatment as a directory
5742   let newdir= a:newdir
5743  endif
5744  let newdir= s:NetrwBrowseChgDir(a:islocal,newdir)
5745  call s:NetrwBrowse(a:islocal,newdir)
5746  let @@= ykeep
5747"  call Dret("s:NetrwForceChgDir")
5748endfun
5749
5750" ---------------------------------------------------------------------
5751" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5752"     direntry: this is the name of the directory.  Will be fnameescape'd to prevent wildcard handling by glob()
5753"     expr    : this is the expression to follow the directory.  Will use s:ComposePath()
5754"     pare    =1: remove the current directory from the resulting glob() filelist
5755"             =0: leave  the current directory   in the resulting glob() filelist
5756fun! s:NetrwGlob(direntry,expr,pare)
5757"  call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")")
5758  if netrw#CheckIfRemote()
5759   keepalt 1sp
5760   keepalt enew
5761   let keep_liststyle    = w:netrw_liststyle
5762   let w:netrw_liststyle = s:THINLIST
5763   if s:NetrwRemoteListing() == 0
5764    keepj keepalt %s@/@@
5765    let filelist= getline(1,$)
5766    q!
5767   else
5768    " remote listing error -- leave treedict unchanged
5769    let filelist= w:netrw_treedict[a:direntry]
5770   endif
5771   let w:netrw_liststyle= keep_liststyle
5772  elseif v:version > 704 || (v:version == 704 && has("patch656"))
5773   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1)
5774   if a:pare
5775    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5776   endif
5777  else
5778   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1)
5779   if a:pare
5780    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5781   endif
5782  endif
5783"  call Dret("s:NetrwGlob ".string(filelist))
5784  return filelist
5785endfun
5786
5787" ---------------------------------------------------------------------
5788" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5789fun! s:NetrwForceFile(islocal,newfile)
5790"  call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)")
5791  if a:newfile =~ '[/@*=|\\]$'
5792   let newfile= substitute(a:newfile,'.$','','')
5793  else
5794   let newfile= a:newfile
5795  endif
5796  if a:islocal
5797   call s:NetrwBrowseChgDir(a:islocal,newfile)
5798  else
5799   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile))
5800  endif
5801"  call Dret("s:NetrwForceFile")
5802endfun
5803
5804" ---------------------------------------------------------------------
5805" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5806"          and switches the hiding mode.  The actual hiding is done by
5807"          s:NetrwListHide().
5808"             g:netrw_hide= 0: show all
5809"                           1: show not-hidden files
5810"                           2: show hidden files only
5811fun! s:NetrwHide(islocal)
5812"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
5813  let ykeep= @@
5814  let svpos= winsaveview()
5815"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5816
5817  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5818"   call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>"))
5819"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5820
5821   " hide the files in the markfile list
5822   for fname in s:netrwmarkfilelist_{bufnr("%")}
5823"    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>"))
5824    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5825     " remove fname from hiding list
5826     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5827     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5828     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5829"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5830    else
5831     " append fname to hiding list
5832     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5833      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5834     else
5835      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5836     endif
5837"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5838    endif
5839   endfor
5840   NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5841   let g:netrw_hide= 1
5842
5843  else
5844
5845   " switch between show-all/show-not-hidden/show-hidden
5846   let g:netrw_hide=(g:netrw_hide+1)%3
5847   exe "NetrwKeepj norm! 0"
5848   if g:netrw_hide && g:netrw_list_hide == ""
5849    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5850    let @@= ykeep
5851"    call Dret("NetrwHide")
5852    return
5853   endif
5854  endif
5855
5856  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5857"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5858  NetrwKeepj call winrestview(svpos)
5859  let @@= ykeep
5860"  call Dret("NetrwHide")
5861endfun
5862
5863" ---------------------------------------------------------------------
5864" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5865fun! s:NetrwHideEdit(islocal)
5866"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
5867
5868  let ykeep= @@
5869  " save current cursor position
5870  let svpos= winsaveview()
5871"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5872
5873  " get new hiding list from user
5874  call inputsave()
5875  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5876  call inputrestore()
5877  let g:netrw_list_hide= newhide
5878"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5879
5880  " refresh the listing
5881  sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
5882
5883  " restore cursor position
5884"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5885  call winrestview(svpos)
5886  let @@= ykeep
5887
5888"  call Dret("NetrwHideEdit")
5889endfun
5890
5891" ---------------------------------------------------------------------
5892" s:NetrwHidden: invoked by "gh" {{{2
5893fun! s:NetrwHidden(islocal)
5894"  call Dfunc("s:NetrwHidden()")
5895  let ykeep= @@
5896  "  save current position
5897  let svpos  = winsaveview()
5898"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5899
5900  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5901   " remove .file pattern from hiding list
5902"   call Decho("remove .file pattern from hiding list",'~'.expand("<slnum>"))
5903   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5904  elseif s:Strlen(g:netrw_list_hide) >= 1
5905"   call Decho("add .file pattern from hiding list",'~'.expand("<slnum>"))
5906   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5907  else
5908"   call Decho("set .file pattern as hiding list",'~'.expand("<slnum>"))
5909   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5910  endif
5911  if g:netrw_list_hide =~ '^,'
5912   let g:netrw_list_hide= strpart(g:netrw_list_hide,1)
5913  endif
5914
5915  " refresh screen and return to saved position
5916  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5917"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5918  NetrwKeepj call winrestview(svpos)
5919  let @@= ykeep
5920"  call Dret("s:NetrwHidden")
5921endfun
5922
5923" ---------------------------------------------------------------------
5924"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5925fun! s:NetrwHome()
5926  if exists("g:netrw_home")
5927   let home= expand(g:netrw_home)
5928  else
5929   " go to vim plugin home
5930   for home in split(&rtp,',') + ['']
5931    if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5932     let basehome= substitute(home,'[/\\]\.vim$','','')
5933     if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5934     let home= basehome."/.vim"
5935     break
5936    endif
5937   endfor
5938   if home == ""
5939    " just pick the first directory
5940    let home= substitute(&rtp,',.*$','','')
5941   endif
5942   if (has("win32") || has("win95") || has("win64") || has("win16"))
5943    let home= substitute(home,'/','\\','g')
5944   endif
5945  endif
5946  " insure that the home directory exists
5947  if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5948"   call Decho("insure that the home<".home."> directory exists")
5949   if exists("g:netrw_mkdir")
5950"    call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")")
5951    call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5952   else
5953"    call Decho("mkdir(".home.")")
5954    call mkdir(home)
5955   endif
5956  endif
5957  let g:netrw_home= home
5958  return home
5959endfun
5960
5961" ---------------------------------------------------------------------
5962" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5963fun! s:NetrwLeftmouse(islocal)
5964  if exists("s:netrwdrag")
5965   return
5966  endif
5967  if &ft != "netrw"
5968   return
5969  endif
5970"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
5971
5972  let ykeep= @@
5973  " check if the status bar was clicked on instead of a file/directory name
5974  while getchar(0) != 0
5975   "clear the input stream
5976  endwhile
5977  call feedkeys("\<LeftMouse>")
5978  let c          = getchar()
5979  let mouse_lnum = v:mouse_lnum
5980  let wlastline  = line('w$')
5981  let lastline   = line('$')
5982"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr(),'~'.expand("<slnum>"))
5983"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0),'~'.expand("<slnum>"))
5984  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5985   " appears to be a status bar leftmouse click
5986   let @@= ykeep
5987"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
5988   return
5989  endif
5990   " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5991   " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5992   " without this test when its disabled.
5993   " May 26, 2014: edit file, :Lex, resize window -- causes refresh.  Reinstated a modified test.  See if problems develop.
5994"   call Decho("v:mouse_col=".v:mouse_col." col#".col('.')." virtcol#".virtcol('.')." col($)#".col("$")." virtcol($)#".virtcol("$"),'~'.expand("<slnum>"))
5995   if v:mouse_col > virtcol('.')
5996    let @@= ykeep
5997"    call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
5998    return
5999   endif
6000
6001  if a:islocal
6002   if exists("b:netrw_curdir")
6003    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
6004   endif
6005  else
6006   if exists("b:netrw_curdir")
6007    NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
6008   endif
6009  endif
6010  let @@= ykeep
6011"  call Dret("s:NetrwLeftmouse")
6012endfun
6013
6014" ---------------------------------------------------------------------
6015" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
6016fun! s:NetrwCLeftmouse(islocal)
6017  if &ft != "netrw"
6018   return
6019  endif
6020"  call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")")
6021  call s:NetrwMarkFileTgt(a:islocal)
6022"  call Dret("s:NetrwCLeftmouse")
6023endfun
6024
6025" ---------------------------------------------------------------------
6026" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER  (implements <c-r>){{{2
6027"   a:islocal=0 : <c-r> not used, remote
6028"   a:islocal=1 : <c-r> not used, local
6029"   a:islocal=2 : <c-r>     used, remote
6030"   a:islocal=3 : <c-r>     used, local
6031fun! s:NetrwServerEdit(islocal,fname)
6032"  call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
6033  let islocal = a:islocal%2      " =0: remote           =1: local
6034  let ctrlr   = a:islocal >= 2   " =0: <c-r> not used   =1: <c-r> used
6035"  call Decho("islocal=".islocal." ctrlr=".ctrlr,'~'.expand("<slnum>"))
6036
6037  if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
6038   " handle directories in the local window -- not in the remote vim server
6039   " user must have closed the NETRWSERVER window.  Treat as normal editing from netrw.
6040"   call Decho("handling directory in client window",'~'.expand("<slnum>"))
6041   let g:netrw_browse_split= 0
6042   if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
6043    let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
6044    unlet s:netrw_browse_split_{winnr()}
6045   endif
6046   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
6047"   call Dret("s:NetrwServerEdit")
6048   return
6049  endif
6050
6051"  call Decho("handling file in server window",'~'.expand("<slnum>"))
6052  if has("clientserver") && executable("gvim")
6053"   call Decho("has clientserver and gvim",'~'.expand("<slnum>"))
6054
6055    if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
6056"     call Decho("g:netrw_browse_split=".string(g:netrw_browse_split),'~'.expand("<slnum>"))
6057     let srvrname = g:netrw_browse_split[0]
6058     let tabnum   = g:netrw_browse_split[1]
6059     let winnum   = g:netrw_browse_split[2]
6060
6061     if serverlist() !~ '\<'.srvrname.'\>'
6062"      call Decho("server not available; ctrlr=".ctrlr,'~'.expand("<slnum>"))
6063
6064      if !ctrlr
6065       " user must have closed the server window and the user did not use <c-r>, but
6066       " used something like <cr>.
6067"       call Decho("user must have closed server AND did not use ctrl-r",'~'.expand("<slnum>"))
6068       if exists("g:netrw_browse_split")
6069	unlet g:netrw_browse_split
6070       endif
6071       let g:netrw_browse_split= 0
6072       if exists("s:netrw_browse_split_".winnr())
6073        let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
6074       endif
6075       call s:NetrwBrowseChgDir(islocal,a:fname)
6076"       call Dret("s:NetrwServerEdit")
6077       return
6078
6079      elseif has("win32") && executable("start")
6080       " start up remote netrw server under windows
6081"       call Decho("starting up gvim server<".srvrname."> for windows",'~'.expand("<slnum>"))
6082       call system("start gvim --servername ".srvrname)
6083
6084      else
6085       " start up remote netrw server under linux
6086"       call Decho("starting up gvim server<".srvrname.">",'~'.expand("<slnum>"))
6087       call system("gvim --servername ".srvrname)
6088      endif
6089     endif
6090
6091"     call Decho("srvrname<".srvrname."> tabnum=".tabnum." winnum=".winnum." server-editing<".a:fname.">",'~'.expand("<slnum>"))
6092     call remote_send(srvrname,":tabn ".tabnum."\<cr>")
6093     call remote_send(srvrname,":".winnum."wincmd w\<cr>")
6094     call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
6095
6096    else
6097
6098     if serverlist() !~ '\<'.g:netrw_servername.'\>'
6099
6100      if !ctrlr
6101"       call Decho("server<".g:netrw_servername."> not available and ctrl-r not used",'~'.expand("<slnum>"))
6102       if exists("g:netrw_browse_split")
6103	unlet g:netrw_browse_split
6104       endif
6105       let g:netrw_browse_split= 0
6106       call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
6107"       call Dret("s:NetrwServerEdit")
6108       return
6109
6110      else
6111"       call Decho("server<".g:netrw_servername."> not available but ctrl-r used",'~'.expand("<slnum>"))
6112       if has("win32") && executable("start")
6113        " start up remote netrw server under windows
6114"        call Decho("starting up gvim server<".g:netrw_servername."> for windows",'~'.expand("<slnum>"))
6115        call system("start gvim --servername ".g:netrw_servername)
6116       else
6117        " start up remote netrw server under linux
6118"        call Decho("starting up gvim server<".g:netrw_servername.">",'~'.expand("<slnum>"))
6119        call system("gvim --servername ".g:netrw_servername)
6120       endif
6121      endif
6122     endif
6123
6124     while 1
6125      try
6126"       call Decho("remote-send: e ".a:fname,'~'.expand("<slnum>"))
6127       call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
6128       break
6129      catch /^Vim\%((\a\+)\)\=:E241/
6130       sleep 200m
6131      endtry
6132     endwhile
6133
6134     if exists("g:netrw_browse_split")
6135      if type(g:netrw_browse_split) != 3
6136        let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
6137       endif
6138      unlet g:netrw_browse_split
6139     endif
6140     let g:netrw_browse_split= [g:netrw_servername,1,1]
6141    endif
6142
6143   else
6144    call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
6145   endif
6146
6147"  call Dret("s:NetrwServerEdit")
6148endfun
6149
6150" ---------------------------------------------------------------------
6151" s:NetrwSLeftmouse: marks the file under the cursor.  May be dragged to select additional files {{{2
6152fun! s:NetrwSLeftmouse(islocal)
6153  if &ft != "netrw"
6154   return
6155  endif
6156"  call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
6157
6158  let s:ngw= s:NetrwGetWord()
6159  call s:NetrwMarkFile(a:islocal,s:ngw)
6160
6161"  call Dret("s:NetrwSLeftmouse")
6162endfun
6163
6164" ---------------------------------------------------------------------
6165" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
6166"                   Used to mark multiple files.
6167fun! s:NetrwSLeftdrag(islocal)
6168"  call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
6169  if !exists("s:netrwdrag")
6170   let s:netrwdrag = winnr()
6171   if a:islocal
6172    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
6173   else
6174    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
6175   endif
6176  endif
6177  let ngw = s:NetrwGetWord()
6178  if !exists("s:ngw") || s:ngw != ngw
6179   call s:NetrwMarkFile(a:islocal,ngw)
6180  endif
6181  let s:ngw= ngw
6182"  call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
6183endfun
6184
6185" ---------------------------------------------------------------------
6186" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
6187fun! s:NetrwSLeftrelease(islocal)
6188"  call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
6189  if exists("s:netrwdrag")
6190   nunmap <s-leftrelease>
6191   let ngw = s:NetrwGetWord()
6192   if !exists("s:ngw") || s:ngw != ngw
6193    call s:NetrwMarkFile(a:islocal,ngw)
6194   endif
6195   if exists("s:ngw")
6196    unlet s:ngw
6197   endif
6198   unlet s:netrwdrag
6199  endif
6200"  call Dret("s:NetrwSLeftrelease")
6201endfun
6202
6203" ---------------------------------------------------------------------
6204" s:NetrwListHide: uses [range]g~...~d to delete files that match       {{{2
6205"                  comma-separated patterns given in g:netrw_list_hide
6206fun! s:NetrwListHide()
6207"  call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
6208"  call Decho("initial: ".string(getline(w:netrw_bannercnt,'$')))
6209  let ykeep= @@
6210
6211  " find a character not in the "hide" string to use as a separator for :g and :v commands
6212  " How-it-works: take the hiding command, convert it into a range.
6213  " Duplicate characters don't matter.
6214  " Remove all such characters from the '/~@#...890' string.
6215  " Use the first character left as a separator character.
6216"  call Decho("find a character not in the hide string to use as a separator",'~'.expand("<slnum>"))
6217  let listhide= g:netrw_list_hide
6218  let sep     = strpart(substitute('~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
6219"  call Decho("sep<".sep.">  (sep not in hide string)",'~'.expand("<slnum>"))
6220
6221  while listhide != ""
6222   if listhide =~ ','
6223    let hide     = substitute(listhide,',.*$','','e')
6224    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
6225   else
6226    let hide     = listhide
6227    let listhide = ""
6228   endif
6229"   call Decho("..extracted pattern from listhide: hide<".hide."> g:netrw_sort_by<".g:netrw_sort_by.'>','~'.expand("<slnum>"))
6230   if g:netrw_sort_by =~ '^[ts]'
6231    if hide =~ '^\^'
6232"     call Decho("..modify hide to handle a \"^...\" pattern",'~'.expand("<slnum>"))
6233     let hide= substitute(hide,'^\^','^\(\\d\\+/\)','')
6234    elseif hide =~ '^\\(\^'
6235     let hide= substitute(hide,'^\\(\^','\\(^\\(\\d\\+/\\)','')
6236    endif
6237"    call Decho("..hide<".hide."> listhide<".listhide.'>','~'.expand("<slnum>"))
6238   endif
6239
6240   " Prune the list by hiding any files which match
6241"   call Decho("..prune the list by hiding any files which ".((g:netrw_hide == 1)? "" : "don't")."match hide<".hide.">")
6242   if g:netrw_hide == 1
6243"    call Decho("..hiding<".hide.">",'~'.expand("<slnum>"))
6244    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
6245   elseif g:netrw_hide == 2
6246"    call Decho("..showing<".hide.">",'~'.expand("<slnum>"))
6247    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
6248   endif
6249"   call Decho("..result: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6250  endwhile
6251
6252  if g:netrw_hide == 2
6253   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
6254"   call Decho("..v KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6255   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
6256"   call Decho("..g KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6257  endif
6258
6259  " remove any blank lines that have somehow remained.
6260  " This seems to happen under Windows.
6261  exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
6262
6263  let @@= ykeep
6264"  call Dret("s:NetrwListHide")
6265endfun
6266
6267" ---------------------------------------------------------------------
6268" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
6269"                 implements the "d" mapping.
6270fun! s:NetrwMakeDir(usrhost)
6271"  call Dfunc("s:NetrwMakeDir(usrhost<".a:usrhost.">)")
6272
6273  let ykeep= @@
6274  " get name of new directory from user.  A bare <CR> will skip.
6275  " if its currently a directory, also request will be skipped, but with
6276  " a message.
6277  call inputsave()
6278  let newdirname= input("Please give directory name: ")
6279  call inputrestore()
6280"  call Decho("newdirname<".newdirname.">",'~'.expand("<slnum>"))
6281
6282  if newdirname == ""
6283   let @@= ykeep
6284"   call Dret("s:NetrwMakeDir : user aborted with bare <cr>")
6285   return
6286  endif
6287
6288  if a:usrhost == ""
6289"   call Decho("local mkdir",'~'.expand("<slnum>"))
6290
6291   " Local mkdir:
6292   " sanity checks
6293   let fullnewdir= b:netrw_curdir.'/'.newdirname
6294"   call Decho("fullnewdir<".fullnewdir.">",'~'.expand("<slnum>"))
6295   if isdirectory(s:NetrwFile(fullnewdir))
6296    if !exists("g:netrw_quiet")
6297     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
6298    endif
6299    let @@= ykeep
6300"    call Dret("s:NetrwMakeDir : directory<".newdirname."> exists previously")
6301    return
6302   endif
6303   if s:FileReadable(fullnewdir)
6304    if !exists("g:netrw_quiet")
6305     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
6306    endif
6307    let @@= ykeep
6308"    call Dret("s:NetrwMakeDir : file<".newdirname."> exists previously")
6309    return
6310   endif
6311
6312   " requested new local directory is neither a pre-existing file or
6313   " directory, so make it!
6314   if exists("*mkdir")
6315    if has("unix")
6316     call mkdir(fullnewdir,"p",xor(0777, system("umask")))
6317    else
6318     call mkdir(fullnewdir,"p")
6319    endif
6320   else
6321    let netrw_origdir= s:NetrwGetcwd(1)
6322    if s:NetrwLcd(b:netrw_curdir)
6323"    call Dret("s:NetrwMakeDir : lcd failure")
6324     return
6325    endif
6326"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("<slnum>"))
6327    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(newdirname,1))
6328    if v:shell_error != 0
6329     let @@= ykeep
6330     call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6331"     call Dret("s:NetrwMakeDir : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
6332     return
6333    endif
6334    if !g:netrw_keepdir
6335"     call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
6336     if s:NetrwLcd(netrw_origdir)
6337"     call Dret("s:NetrwBrowse : lcd failure")
6338      return
6339     endif
6340    endif
6341   endif
6342
6343   if v:shell_error == 0
6344    " refresh listing
6345"    call Decho("refresh listing",'~'.expand("<slnum>"))
6346    let svpos= winsaveview()
6347"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6348    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
6349"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6350    call winrestview(svpos)
6351   elseif !exists("g:netrw_quiet")
6352    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
6353   endif
6354"   redraw!
6355
6356  elseif !exists("b:netrw_method") || b:netrw_method == 4
6357   " Remote mkdir:  using ssh
6358"   call Decho("remote mkdir",'~'.expand("<slnum>"))
6359   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
6360   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
6361   call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
6362   if v:shell_error == 0
6363    " refresh listing
6364    let svpos= winsaveview()
6365"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6366    NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6367"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6368    NetrwKeepj call winrestview(svpos)
6369   elseif !exists("g:netrw_quiet")
6370    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
6371   endif
6372"   redraw!
6373
6374  elseif b:netrw_method == 2
6375   " Remote mkdir:  using ftp+.netrc
6376   let svpos= winsaveview()
6377"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6378"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6379   if exists("b:netrw_fname")
6380"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6381    let remotepath= b:netrw_fname
6382   else
6383    let remotepath= ""
6384   endif
6385   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6386   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6387"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6388   NetrwKeepj call winrestview(svpos)
6389
6390  elseif b:netrw_method == 3
6391   " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
6392   let svpos= winsaveview()
6393"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6394"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6395   if exists("b:netrw_fname")
6396"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6397    let remotepath= b:netrw_fname
6398   else
6399    let remotepath= ""
6400   endif
6401   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6402   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6403"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6404   NetrwKeepj call winrestview(svpos)
6405  endif
6406
6407  let @@= ykeep
6408"  call Dret("s:NetrwMakeDir")
6409endfun
6410
6411" ---------------------------------------------------------------------
6412" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
6413fun! s:TreeSqueezeDir(islocal)
6414"  call Dfunc("s:TreeSqueezeDir(islocal=".a:islocal.")")
6415  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6416   " its a tree-listing style
6417   let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
6418   let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
6419   let depth    = strchars(substitute(curdepth,' ','','g'))
6420   let srch     = -1
6421"   call Decho("curdepth<".curdepth.'>','~'.expand("<slnum>"))
6422"   call Decho("depth   =".depth,'~'.expand("<slnum>"))
6423"   call Decho("stopline#".stopline,'~'.expand("<slnum>"))
6424"   call Decho("curline#".line(".")."<".getline('.').'>','~'.expand("<slnum>"))
6425   if depth >= 2
6426    NetrwKeepj norm! 0
6427    let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
6428    let srch      = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
6429"    call Decho("curdepthm1<".curdepthm1.'>','~'.expand("<slnum>"))
6430"    call Decho("case depth>=2: srch<".srch.'>','~'.expand("<slnum>"))
6431   elseif depth == 1
6432    NetrwKeepj norm! 0
6433    let treedepthchr= substitute(s:treedepthstring,' ','','')
6434    let srch        = search('^[^'.treedepthchr.']','bW',stopline)
6435"    call Decho("case depth==1: srch<".srch.'>','~'.expand("<slnum>"))
6436   endif
6437   if srch > 0
6438"    call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
6439    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord()))
6440    exe srch
6441   endif
6442  endif
6443"  call Dret("s:TreeSqueezeDir")
6444endfun
6445
6446" ---------------------------------------------------------------------
6447" s:NetrwMaps: {{{2
6448fun! s:NetrwMaps(islocal)
6449"  call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6450
6451  " mouse <Plug> maps: {{{3
6452  if g:netrw_mousemaps && g:netrw_retmap
6453"   call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
6454   if !hasmapto("<Plug>NetrwReturn")
6455    if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
6456"     call Decho("making map for 2-leftmouse",'~'.expand("<slnum>"))
6457     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
6458    elseif maparg("<c-leftmouse>","n") == ""
6459"     call Decho("making map for c-leftmouse",'~'.expand("<slnum>"))
6460     nmap <unique> <silent> <c-leftmouse>	<Plug>NetrwReturn
6461    endif
6462   endif
6463   nno <silent> <Plug>NetrwReturn	:Rexplore<cr>
6464"   call Decho("made <Plug>NetrwReturn map",'~'.expand("<slnum>"))
6465  endif
6466
6467  " generate default <Plug> maps {{{3
6468  if !hasmapto('<Plug>NetrwHide')              |nmap <buffer> <silent> <nowait> a	<Plug>NetrwHide_a|endif
6469  if !hasmapto('<Plug>NetrwBrowseUpDir')       |nmap <buffer> <silent> <nowait> -	<Plug>NetrwBrowseUpDir|endif
6470  if !hasmapto('<Plug>NetrwOpenFile')          |nmap <buffer> <silent> <nowait> %	<Plug>NetrwOpenFile|endif
6471  if !hasmapto('<Plug>NetrwBadd_cb')           |nmap <buffer> <silent> <nowait> cb	<Plug>NetrwBadd_cb|endif
6472  if !hasmapto('<Plug>NetrwBadd_cB')           |nmap <buffer> <silent> <nowait> cB	<Plug>NetrwBadd_cB|endif
6473  if !hasmapto('<Plug>NetrwLcd')               |nmap <buffer> <silent> <nowait> cd	<Plug>NetrwLcd|endif
6474  if !hasmapto('<Plug>NetrwSetChgwin')         |nmap <buffer> <silent> <nowait> C	<Plug>NetrwSetChgwin|endif
6475  if !hasmapto('<Plug>NetrwRefresh')           |nmap <buffer> <silent> <nowait> <c-l>	<Plug>NetrwRefresh|endif
6476  if !hasmapto('<Plug>NetrwLocalBrowseCheck')  |nmap <buffer> <silent> <nowait> <cr>	<Plug>NetrwLocalBrowseCheck|endif
6477  if !hasmapto('<Plug>NetrwServerEdit')        |nmap <buffer> <silent> <nowait> <c-r>	<Plug>NetrwServerEdit|endif
6478  if !hasmapto('<Plug>NetrwMakeDir')           |nmap <buffer> <silent> <nowait> d	<Plug>NetrwMakeDir|endif
6479  if !hasmapto('<Plug>NetrwBookHistHandler_gb')|nmap <buffer> <silent> <nowait> gb	<Plug>NetrwBookHistHandler_gb|endif
6480" ---------------------------------------------------------------------
6481"  if !hasmapto('<Plug>NetrwForceChgDir')       |nmap <buffer> <silent> <nowait> gd	<Plug>NetrwForceChgDir|endif
6482"  if !hasmapto('<Plug>NetrwForceFile')         |nmap <buffer> <silent> <nowait> gf	<Plug>NetrwForceFile|endif
6483"  if !hasmapto('<Plug>NetrwHidden')            |nmap <buffer> <silent> <nowait> gh	<Plug>NetrwHidden|endif
6484"  if !hasmapto('<Plug>NetrwSetTreetop')        |nmap <buffer> <silent> <nowait> gn	<Plug>NetrwSetTreetop|endif
6485"  if !hasmapto('<Plug>NetrwChgPerm')           |nmap <buffer> <silent> <nowait> gp	<Plug>NetrwChgPerm|endif
6486"  if !hasmapto('<Plug>NetrwBannerCtrl')        |nmap <buffer> <silent> <nowait> I	<Plug>NetrwBannerCtrl|endif
6487"  if !hasmapto('<Plug>NetrwListStyle')         |nmap <buffer> <silent> <nowait> i	<Plug>NetrwListStyle|endif
6488"  if !hasmapto('<Plug>NetrwMarkMoveMF2Arglist')|nmap <buffer> <silent> <nowait> ma	<Plug>NetrwMarkMoveMF2Arglist|endif
6489"  if !hasmapto('<Plug>NetrwMarkMoveArglist2MF')|nmap <buffer> <silent> <nowait> mA	<Plug>NetrwMarkMoveArglist2MF|endif
6490"  if !hasmapto('<Plug>NetrwBookHistHandler_mA')|nmap <buffer> <silent> <nowait> mb	<Plug>NetrwBookHistHandler_mA|endif
6491"  if !hasmapto('<Plug>NetrwBookHistHandler_mB')|nmap <buffer> <silent> <nowait> mB	<Plug>NetrwBookHistHandler_mB|endif
6492"  if !hasmapto('<Plug>NetrwMarkFileCopy')      |nmap <buffer> <silent> <nowait> mc	<Plug>NetrwMarkFileCopy|endif
6493"  if !hasmapto('<Plug>NetrwMarkFileDiff')      |nmap <buffer> <silent> <nowait> md	<Plug>NetrwMarkFileDiff|endif
6494"  if !hasmapto('<Plug>NetrwMarkFileEdit')      |nmap <buffer> <silent> <nowait> me	<Plug>NetrwMarkFileEdit|endif
6495"  if !hasmapto('<Plug>NetrwMarkFile')          |nmap <buffer> <silent> <nowait> mf	<Plug>NetrwMarkFile|endif
6496"  if !hasmapto('<Plug>NetrwUnmarkList')        |nmap <buffer> <silent> <nowait> mF	<Plug>NetrwUnmarkList|endif
6497"  if !hasmapto('<Plug>NetrwMarkFileGrep')      |nmap <buffer> <silent> <nowait> mg	<Plug>NetrwMarkFileGrep|endif
6498"  if !hasmapto('<Plug>NetrwMarkHideSfx')       |nmap <buffer> <silent> <nowait> mh	<Plug>NetrwMarkHideSfx|endif
6499"  if !hasmapto('<Plug>NetrwMarkFileMove')      |nmap <buffer> <silent> <nowait> mm	<Plug>NetrwMarkFileMove|endif
6500"  if !hasmapto('<Plug>NetrwMarkFilePrint')     |nmap <buffer> <silent> <nowait> mp	<Plug>NetrwMarkFilePrint|endif
6501"  if !hasmapto('<Plug>NetrwMarkFileRegexp')    |nmap <buffer> <silent> <nowait> mr	<Plug>NetrwMarkFileRegexp|endif
6502"  if !hasmapto('<Plug>NetrwMarkFileSource')    |nmap <buffer> <silent> <nowait> ms	<Plug>NetrwMarkFileSource|endif
6503"  if !hasmapto('<Plug>NetrwMarkFileTag')       |nmap <buffer> <silent> <nowait> mT	<Plug>NetrwMarkFileTag|endif
6504"  if !hasmapto('<Plug>NetrwMarkFileTgt')       |nmap <buffer> <silent> <nowait> mt	<Plug>NetrwMarkFileTgt|endif
6505"  if !hasmapto('<Plug>NetrwUnMarkFile')        |nmap <buffer> <silent> <nowait> mu	<Plug>NetrwUnMarkFile|endif
6506"  if !hasmapto('<Plug>NetrwMarkFileVimCmd')    |nmap <buffer> <silent> <nowait> mv	<Plug>NetrwMarkFileVimCmd|endif
6507"  if !hasmapto('<Plug>NetrwMarkFileExe_mx')    |nmap <buffer> <silent> <nowait> mx	<Plug>NetrwMarkFileExe_mx|endif
6508"  if !hasmapto('<Plug>NetrwMarkFileExe_mX')    |nmap <buffer> <silent> <nowait> mX	<Plug>NetrwMarkFileExe_mX|endif
6509"  if !hasmapto('<Plug>NetrwMarkFileCompress')  |nmap <buffer> <silent> <nowait> mz	<Plug>NetrwMarkFileCompress|endif
6510"  if !hasmapto('<Plug>NetrwObtain')            |nmap <buffer> <silent> <nowait> O	<Plug>NetrwObtain|endif
6511"  if !hasmapto('<Plug>NetrwSplit_o')           |nmap <buffer> <silent> <nowait> o	<Plug>NetrwSplit_o|endif
6512"  if !hasmapto('<Plug>NetrwPreview')           |nmap <buffer> <silent> <nowait> p	<Plug>NetrwPreview|endif
6513"  if !hasmapto('<Plug>NetrwPrevWinOpen')       |nmap <buffer> <silent> <nowait> P	<Plug>NetrwPrevWinOpen|endif
6514"  if !hasmapto('<Plug>NetrwBookHistHandler_qb')|nmap <buffer> <silent> <nowait> qb	<Plug>NetrwBookHistHandler_qb|endif
6515"  if !hasmapto('<Plug>NetrwFileInfo')          |nmap <buffer> <silent> <nowait> qf	<Plug>NetrwFileInfo|endif
6516"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qF')   |nmap <buffer> <silent> <nowait> qF	<Plug>NetrwMarkFileQFEL_qF|endif
6517"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qL')   |nmap <buffer> <silent> <nowait> qL	<Plug>NetrwMarkFileQFEL_qL|endif
6518"  if !hasmapto('<Plug>NetrwSortStyle')         |nmap <buffer> <silent> <nowait> s	<Plug>NetrwSortStyle|endif
6519"  if !hasmapto('<Plug>NetSortSequence')        |nmap <buffer> <silent> <nowait> S	<Plug>NetSortSequence|endif
6520"  if !hasmapto('<Plug>NetrwSetTgt_Tb')         |nmap <buffer> <silent> <nowait> Tb	<Plug>NetrwSetTgt_Tb|endif
6521"  if !hasmapto('<Plug>NetrwSetTgt_Th')         |nmap <buffer> <silent> <nowait> Th	<Plug>NetrwSetTgt_Th|endif
6522"  if !hasmapto('<Plug>NetrwSplit_t')           |nmap <buffer> <silent> <nowait> t	<Plug>NetrwSplit_t|endif
6523"  if !hasmapto('<Plug>NetrwBookHistHandler_u') |nmap <buffer> <silent> <nowait> u	<Plug>NetrwBookHistHandler_u|endif
6524"  if !hasmapto('<Plug>NetrwBookHistHandler_U') |nmap <buffer> <silent> <nowait> U	<Plug>NetrwBookHistHandler_U|endif
6525"  if !hasmapto('<Plug>NetrwSplit_v')           |nmap <buffer> <silent> <nowait> v	<Plug>NetrwSplit_v|endif
6526"  if !hasmapto('<Plug>NetrwBrowseX')           |nmap <buffer> <silent> <nowait> x	<Plug>NetrwBrowseX|endif
6527"  if !hasmapto('<Plug>NetrwLocalExecute')      |nmap <buffer> <silent> <nowait> X	<Plug>NetrwLocalExecute|endif
6528
6529  if a:islocal
6530"   call Decho("make local maps",'~'.expand("<slnum>"))
6531   " local normal-mode maps {{{3
6532   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(1)<cr>
6533   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6534   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(1)<cr>
6535   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(1,0)<cr>
6536   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(1,1)<cr>
6537   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6538   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6539   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6540   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6541   nnoremap <buffer> <silent> <Plug>NetrwMakeDir		:<c-u>call <SID>NetrwMakeDir("")<cr>
6542   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6543" ---------------------------------------------------------------------
6544   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6545   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6546   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
6547   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(0,<SID>NetrwGetWord())<cr>
6548   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6549   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6550   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(1)<cr>
6551   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6552   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6553   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6554   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6555   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6556   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6557   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6558   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6559   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6560   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6561   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6562   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6563   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6564   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6565   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6566   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6567   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6568   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6569   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6570   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6571   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6572   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6573   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(1)<cr>
6574   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(3)<cr>
6575   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6576   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6577   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6578   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6579   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6580   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6581   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(1)<cr>
6582   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(1)<cr>
6583   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6584   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(4)<cr>
6585   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6586   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6587   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6588   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(5)<cr>
6589   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6590   nnoremap <buffer> <silent> <nowait> X	:<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6591
6592   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>
6593   if !hasmapto('<Plug>NetrwHideEdit')
6594    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6595   endif
6596   nnoremap <buffer> <silent> <Plug>NetrwHideEdit		:call <SID>NetrwHideEdit(1)<cr>
6597   if !hasmapto('<Plug>NetrwRefresh')
6598    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6599   endif
6600   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>
6601   if s:didstarstar || !mapcheck("<s-down>","n")
6602    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6603   endif
6604   if s:didstarstar || !mapcheck("<s-up>","n")
6605    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6606   endif
6607   if !hasmapto('<Plug>NetrwTreeSqueeze')
6608    nmap <buffer> <silent> <nowait> <s-cr>			<Plug>NetrwTreeSqueeze
6609   endif
6610   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze		:call <SID>TreeSqueezeDir(1)<cr>
6611   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6612   if g:netrw_mousemaps == 1
6613    nmap <buffer>			<leftmouse>   		<Plug>NetrwLeftmouse
6614    nmap <buffer>			<c-leftmouse>		<Plug>NetrwCLeftmouse
6615    nmap <buffer>			<middlemouse>		<Plug>NetrwMiddlemouse
6616    nmap <buffer>			<s-leftmouse>		<Plug>NetrwSLeftmouse
6617    nmap <buffer>			<s-leftdrag>		<Plug>NetrwSLeftdrag
6618    nmap <buffer>			<2-leftmouse>		<Plug>Netrw2Leftmouse
6619    imap <buffer>			<leftmouse>		<Plug>ILeftmouse
6620    imap <buffer>			<middlemouse>		<Plug>IMiddlemouse
6621    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
6622    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(1)<cr>
6623    nno  <buffer> <silent>		<Plug>NetrwMiddlemouse	<leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
6624    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(1)<cr>
6625    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(1)<cr>
6626    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6627    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6628    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6629   endif
6630   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6631   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6632   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6633   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("")<cr>'
6634   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6635   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6636   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6637   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6638
6639   " support user-specified maps
6640   call netrw#UserMaps(1)
6641
6642  else
6643   " remote normal-mode maps {{{3
6644"   call Decho("make remote maps",'~'.expand("<slnum>"))
6645   call s:RemotePathAnalysis(b:netrw_curdir)
6646   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(0)<cr>
6647   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6648   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(0)<cr>
6649   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(0,0)<cr>
6650   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(0,1)<cr>
6651   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6652   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6653   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6654   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6655   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6656   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6657" ---------------------------------------------------------------------
6658   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6659   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6660   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
6661   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6662   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6663   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(0)<cr>
6664   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6665   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6666   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6667   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6668   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6669   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6670   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6671   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6672   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6673   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6674   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6675   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6676   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6677   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6678   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6679   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6680   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6681   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6682   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6683   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6684   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6685   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6686   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(0)<cr>
6687   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(0)<cr>
6688   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6689   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6690   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6691   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6692   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6693   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6694   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>
6695   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(0)<cr>
6696   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(0)<cr>
6697   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6698   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(1)<cr>
6699   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6700   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6701   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6702   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(2)<cr>
6703   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6704   if !hasmapto('<Plug>NetrwHideEdit')
6705    nmap <buffer> <c-h> <Plug>NetrwHideEdit
6706   endif
6707   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
6708   if !hasmapto('<Plug>NetrwRefresh')
6709    nmap <buffer> <c-l> <Plug>NetrwRefresh
6710   endif
6711   if !hasmapto('<Plug>NetrwTreeSqueeze')
6712    nmap <buffer> <silent> <nowait> <s-cr>	<Plug>NetrwTreeSqueeze
6713   endif
6714   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze	:call <SID>TreeSqueezeDir(0)<cr>
6715
6716   let mapsafepath     = escape(s:path, s:netrw_map_escape)
6717   let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6718
6719   nnoremap <buffer> <silent> <Plug>NetrwRefresh	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6720   if g:netrw_mousemaps == 1
6721    nmap <buffer> <leftmouse>		<Plug>NetrwLeftmouse
6722    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
6723    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6724    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(0)<cr>
6725    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6726    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(0)<cr>
6727    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6728    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(0)<cr>
6729    nmap <middlemouse>			<Plug>NetrwMiddlemouse
6730    nno  <buffer> <silent>		<middlemouse>		<Plug>NetrwMiddlemouse <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
6731    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6732    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6733    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6734    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6735    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6736    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6737    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6738   endif
6739   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6740   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6741   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6742   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6743   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6744   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6745   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6746   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6747
6748   " support user-specified maps
6749   call netrw#UserMaps(0)
6750  endif " }}}3
6751
6752"  call Dret("s:NetrwMaps")
6753endfun
6754
6755" ---------------------------------------------------------------------
6756" s:NetrwCommands: set up commands 				{{{2
6757"  If -buffer, the command is only available from within netrw buffers
6758"  Otherwise, the command is available from any window, so long as netrw
6759"  has been used at least once in the session.
6760fun! s:NetrwCommands(islocal)
6761"  call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6762
6763  com! -nargs=* -complete=file -bang	NetrwMB	call s:NetrwBookmark(<bang>0,<f-args>)
6764  com! -nargs=*			    	NetrwC	call s:NetrwSetChgwin(<q-args>)
6765  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
6766  if a:islocal
6767   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(1,<f-args>)
6768  else
6769   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(0,<f-args>)
6770  endif
6771  com! -buffer -nargs=? -complete=file	MT	call s:NetrwMarkTarget(<q-args>)
6772
6773"  call Dret("s:NetrwCommands")
6774endfun
6775
6776" ---------------------------------------------------------------------
6777" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6778"                   glob()ing only works with local files
6779fun! s:NetrwMarkFiles(islocal,...)
6780"  call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6781  let curdir = s:NetrwGetCurdir(a:islocal)
6782  let i      = 1
6783  while i <= a:0
6784   if a:islocal
6785    if v:version > 704 || (v:version == 704 && has("patch656"))
6786     let mffiles= glob(a:{i},0,1,1)
6787    else
6788     let mffiles= glob(a:{i},0,1)
6789    endif
6790   else
6791    let mffiles= [a:{i}]
6792   endif
6793"   call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6794   for mffile in mffiles
6795"    call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6796    call s:NetrwMarkFile(a:islocal,mffile)
6797   endfor
6798   let i= i + 1
6799  endwhile
6800"  call Dret("s:NetrwMarkFiles")
6801endfun
6802
6803" ---------------------------------------------------------------------
6804" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6805fun! s:NetrwMarkTarget(...)
6806"  call Dfunc("s:NetrwMarkTarget() a:0=".a:0)
6807  if a:0 == 0 || (a:0 == 1 && a:1 == "")
6808   let curdir = s:NetrwGetCurdir(1)
6809   let tgt    = b:netrw_curdir
6810  else
6811   let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6812   let tgt    = a:1
6813  endif
6814"  call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
6815  let s:netrwmftgt         = tgt
6816  let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6817  let curislocal           = b:netrw_curdir !~ '^\a\{3,}://'
6818  let svpos                = winsaveview()
6819"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6820  call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./'))
6821"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6822  call winrestview(svpos)
6823"  call Dret("s:NetrwMarkTarget")
6824endfun
6825
6826" ---------------------------------------------------------------------
6827" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6828"                  mark and unmark files.  If a markfile list exists,
6829"                  then the rename and delete functions will use it instead
6830"                  of whatever may happen to be under the cursor at that
6831"                  moment.  When the mouse and gui are available,
6832"                  shift-leftmouse may also be used to mark files.
6833"
6834"  Creates two lists
6835"    s:netrwmarkfilelist    -- holds complete paths to all marked files
6836"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
6837"
6838"  Creates a marked file match string
6839"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
6840"
6841"  Creates a buffer version of islocal
6842"    b:netrw_islocal
6843fun! s:NetrwMarkFile(islocal,fname)
6844"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6845"  call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6846
6847  " sanity check
6848  if empty(a:fname)
6849"   call Dret("s:NetrwMarkFile : empty fname")
6850   return
6851  endif
6852  let curdir = s:NetrwGetCurdir(a:islocal)
6853
6854  let ykeep   = @@
6855  let curbufnr= bufnr("%")
6856  if a:fname =~ '^\a'
6857   let leader= '\<'
6858  else
6859   let leader= ''
6860  endif
6861  if a:fname =~ '\a$'
6862   let trailer = '\>[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6863  else
6864   let trailer = '[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6865  endif
6866
6867  if exists("s:netrwmarkfilelist_".curbufnr)
6868   " markfile list pre-exists
6869"   call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6870"   call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6871"   call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6872   let b:netrw_islocal= a:islocal
6873
6874   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6875    " append filename to buffer's markfilelist
6876"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6877    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6878    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6879
6880   else
6881    " remove filename from buffer's markfilelist
6882"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6883    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6884    if s:netrwmarkfilelist_{curbufnr} == []
6885     " local markfilelist is empty; remove it entirely
6886"     call Decho("markfile list now empty",'~'.expand("<slnum>"))
6887     call s:NetrwUnmarkList(curbufnr,curdir)
6888    else
6889     " rebuild match list to display markings correctly
6890"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6891     let s:netrwmarkfilemtch_{curbufnr}= ""
6892     let first                         = 1
6893     for fname in s:netrwmarkfilelist_{curbufnr}
6894      if first
6895       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6896      else
6897       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6898      endif
6899      let first= 0
6900     endfor
6901"     call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6902    endif
6903   endif
6904
6905  else
6906   " initialize new markfilelist
6907"   call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6908
6909"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6910   let s:netrwmarkfilelist_{curbufnr}= []
6911   call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6912"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6913
6914   " build initial markfile matching pattern
6915   if a:fname =~ '/$'
6916    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6917   else
6918    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6919   endif
6920"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6921  endif
6922
6923  " handle global markfilelist
6924  if exists("s:netrwmarkfilelist")
6925   let dname= s:ComposePath(b:netrw_curdir,a:fname)
6926   if index(s:netrwmarkfilelist,dname) == -1
6927    " append new filename to global markfilelist
6928    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6929"    call Decho("append filename<".a:fname."> to global s:markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6930   else
6931    " remove new filename from global markfilelist
6932"    call Decho("remove new filename from global s:markfilelist",'~'.expand("<slnum>"))
6933"    call Decho("..filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6934    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6935"    call Decho("..ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6936    if s:netrwmarkfilelist == []
6937"     call Decho("s:netrwmarkfilelist is empty; unlet it",'~'.expand("<slnum>"))
6938     unlet s:netrwmarkfilelist
6939    endif
6940   endif
6941  else
6942   " initialize new global-directory markfilelist
6943   let s:netrwmarkfilelist= []
6944   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6945"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6946  endif
6947
6948  " set up 2match'ing to netrwmarkfilemtch_# list
6949  if has("syntax") && exists("g:syntax_on") && g:syntax_on
6950   if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6951" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6952    if exists("g:did_drchip_netrwlist_syntax")
6953     exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6954    endif
6955   else
6956" "   call Decho("2match none",'~'.expand("<slnum>"))
6957    2match none
6958   endif
6959  endif
6960  let @@= ykeep
6961"  call Decho("s:netrwmarkfilelist[".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : "")."] (avail in all buffers)",'~'.expand("<slnum>"))
6962"  call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">  (buf#".curbufnr."list)")
6963endfun
6964
6965" ---------------------------------------------------------------------
6966" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6967"                         mA: move the argument list to marked file list     (tomflist=1)
6968"                            Uses the global marked file list
6969fun! s:NetrwMarkFileArgList(islocal,tomflist)
6970"  call Dfunc("s:NetrwMarkFileArgList(islocal=".a:islocal.",tomflist=".a:tomflist.")")
6971
6972  let svpos    = winsaveview()
6973"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6974  let curdir   = s:NetrwGetCurdir(a:islocal)
6975  let curbufnr = bufnr("%")
6976
6977  if a:tomflist
6978   " mA: move argument list to marked file list
6979   while argc()
6980    let fname= argv(0)
6981"    call Decho("exe argdel ".fname,'~'.expand("<slnum>"))
6982    exe "argdel ".fnameescape(fname)
6983    call s:NetrwMarkFile(a:islocal,fname)
6984   endwhile
6985
6986  else
6987   " ma: move marked file list to argument list
6988   if exists("s:netrwmarkfilelist")
6989
6990    " for every filename in the marked list
6991    for fname in s:netrwmarkfilelist
6992"     call Decho("exe argadd ".fname,'~'.expand("<slnum>"))
6993     exe "argadd ".fnameescape(fname)
6994    endfor	" for every file in the marked list
6995
6996    " unmark list and refresh
6997    call s:NetrwUnmarkList(curbufnr,curdir)
6998    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6999"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7000    NetrwKeepj call winrestview(svpos)
7001   endif
7002  endif
7003
7004"  call Dret("s:NetrwMarkFileArgList")
7005endfun
7006
7007" ---------------------------------------------------------------------
7008" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
7009"                          compress/decompress files using the programs
7010"                          in g:netrw_compress and g:netrw_uncompress,
7011"                          using g:netrw_compress_suffix to know which to
7012"                          do.  By default:
7013"                            g:netrw_compress        = "gzip"
7014"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
7015fun! s:NetrwMarkFileCompress(islocal)
7016"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
7017  let svpos    = winsaveview()
7018"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7019  let curdir   = s:NetrwGetCurdir(a:islocal)
7020  let curbufnr = bufnr("%")
7021
7022  " sanity check
7023  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7024   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7025"   call Dret("s:NetrwMarkFileCompress")
7026   return
7027  endif
7028"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7029
7030  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
7031
7032   " for every filename in the marked list
7033   for fname in s:netrwmarkfilelist_{curbufnr}
7034    let sfx= substitute(fname,'^.\{-}\(\.\a\+\)$','\1','')
7035"    call Decho("extracted sfx<".sfx.">",'~'.expand("<slnum>"))
7036    if exists("g:netrw_decompress['".sfx."']")
7037     " fname has a suffix indicating that its compressed; apply associated decompression routine
7038     let exe= g:netrw_decompress[sfx]
7039"     call Decho("fname<".fname."> is compressed so decompress with <".exe.">",'~'.expand("<slnum>"))
7040     let exe= netrw#WinPath(exe)
7041     if a:islocal
7042      if g:netrw_keepdir
7043       let fname= s:ShellEscape(s:ComposePath(curdir,fname))
7044      endif
7045      call system(exe." ".fname)
7046      if v:shell_error
7047       NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
7048      endif
7049     else
7050      let fname= s:ShellEscape(b:netrw_curdir.fname,1)
7051      NetrwKeepj call s:RemoteSystem(exe." ".fname)
7052     endif
7053
7054    endif
7055    unlet sfx
7056
7057    if exists("exe")
7058     unlet exe
7059    elseif a:islocal
7060     " fname not a compressed file, so compress it
7061     call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
7062     if v:shell_error
7063      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_compress<".g:netrw_compress."> to something that works",104)
7064     endif
7065    else
7066     " fname not a compressed file, so compress it
7067     NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
7068    endif
7069   endfor	" for every file in the marked list
7070
7071   call s:NetrwUnmarkList(curbufnr,curdir)
7072   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7073"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7074   NetrwKeepj call winrestview(svpos)
7075  endif
7076"  call Dret("s:NetrwMarkFileCompress")
7077endfun
7078
7079" ---------------------------------------------------------------------
7080" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
7081"                      If no marked files, then set up directory as the
7082"                      target.  Currently does not support copying entire
7083"                      directories.  Uses the local-buffer marked file list.
7084"                      Returns 1=success  (used by NetrwMarkFileMove())
7085"                              0=failure
7086fun! s:NetrwMarkFileCopy(islocal,...)
7087"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
7088
7089  let curdir   = s:NetrwGetCurdir(a:islocal)
7090  let curbufnr = bufnr("%")
7091  if b:netrw_curdir !~ '/$'
7092   if !exists("b:netrw_curdir")
7093    let b:netrw_curdir= curdir
7094   endif
7095   let b:netrw_curdir= b:netrw_curdir."/"
7096  endif
7097
7098  " sanity check
7099  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7100   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7101"   call Dret("s:NetrwMarkFileCopy")
7102   return
7103  endif
7104"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7105
7106  if !exists("s:netrwmftgt")
7107   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
7108"   call Dret("s:NetrwMarkFileCopy 0")
7109   return 0
7110  endif
7111"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7112
7113  if a:islocal &&  s:netrwmftgt_islocal
7114   " Copy marked files, local directory to local directory
7115"   call Decho("copy from local to local",'~'.expand("<slnum>"))
7116   if !executable(g:netrw_localcopycmd)
7117    call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
7118"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
7119    return
7120   endif
7121
7122   " copy marked files while within the same directory (ie. allow renaming)
7123   if simplify(s:netrwmftgt) == simplify(b:netrw_curdir)
7124    if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
7125     " only one marked file
7126"     call Decho("case: only one marked file",'~'.expand("<slnum>"))
7127     let args    = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
7128     let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
7129    elseif a:0 == 1
7130"     call Decho("case: handling one input argument",'~'.expand("<slnum>"))
7131     " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
7132     let args    = s:ShellEscape(b:netrw_curdir.a:1)
7133     let oldname = a:1
7134    else
7135     " copy multiple marked files inside the same directory
7136"     call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
7137     let s:recursive= 1
7138     for oldname in s:netrwmarkfilelist_{bufnr("%")}
7139      let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
7140      if ret == 0
7141       break
7142      endif
7143     endfor
7144     unlet s:recursive
7145     call s:NetrwUnmarkList(curbufnr,curdir)
7146"     call Dret("s:NetrwMarkFileCopy ".ret)
7147     return ret
7148    endif
7149
7150    call inputsave()
7151    let newname= input("Copy ".oldname." to : ",oldname,"file")
7152    call inputrestore()
7153    if newname == ""
7154"     call Dret("s:NetrwMarkFileCopy 0")
7155     return 0
7156    endif
7157    let args= s:ShellEscape(oldname)
7158    let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
7159   else
7160    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
7161    let tgt = s:ShellEscape(s:netrwmftgt)
7162   endif
7163   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7164    let args= substitute(args,'/','\\','g')
7165    let tgt = substitute(tgt, '/','\\','g')
7166   endif
7167   if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
7168   if tgt  =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
7169   if args =~ '//'|let args= substitute(args,'//','/','g')|endif
7170   if tgt  =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
7171"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
7172"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
7173   if isdirectory(s:NetrwFile(args))
7174"    call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
7175    let copycmd= g:netrw_localcopydircmd
7176"    call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
7177    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7178     " window's xcopy doesn't copy a directory to a target properly.  Instead, it copies a directory's
7179     " contents to a target.  One must append the source directory name to the target to get xcopy to
7180     " do the right thing.
7181     let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
7182"     call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
7183    endif
7184   else
7185    let copycmd= g:netrw_localcopycmd
7186   endif
7187   if g:netrw_localcopycmd =~ '\s'
7188    let copycmd     = substitute(copycmd,'\s.*$','','')
7189    let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
7190    let copycmd     = netrw#WinPath(copycmd).copycmdargs
7191   else
7192    let copycmd = netrw#WinPath(copycmd)
7193   endif
7194"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
7195"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
7196"   call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
7197"   call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
7198   call system(copycmd.g:netrw_localcopycmdopt." '".args."' '".tgt."'")
7199   if v:shell_error != 0
7200    if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7201     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)
7202    else
7203     call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
7204    endif
7205"    call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
7206    return 0
7207   endif
7208
7209  elseif  a:islocal && !s:netrwmftgt_islocal
7210   " Copy marked files, local directory to remote directory
7211"   call Decho("copy from local to remote",'~'.expand("<slnum>"))
7212   NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
7213
7214  elseif !a:islocal &&  s:netrwmftgt_islocal
7215   " Copy marked files, remote directory to local directory
7216"   call Decho("copy from remote to local",'~'.expand("<slnum>"))
7217   NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
7218
7219  elseif !a:islocal && !s:netrwmftgt_islocal
7220   " Copy marked files, remote directory to remote directory
7221"   call Decho("copy from remote to remote",'~'.expand("<slnum>"))
7222   let curdir = getcwd()
7223   let tmpdir = s:GetTempfile("")
7224   if tmpdir !~ '/'
7225    let tmpdir= curdir."/".tmpdir
7226   endif
7227   if exists("*mkdir")
7228    call mkdir(tmpdir)
7229   else
7230    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(tmpdir,1))
7231    if v:shell_error != 0
7232     call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
7233"     call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
7234     return
7235    endif
7236   endif
7237   if isdirectory(s:NetrwFile(tmpdir))
7238    if s:NetrwLcd(tmpdir)
7239"     call Dret("s:NetrwMarkFileCopy : lcd failure")
7240     return
7241    endif
7242    NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
7243    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
7244    NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
7245    if getcwd() == tmpdir
7246     for fname in s:netrwmarkfilelist_{bufnr('%')}
7247      NetrwKeepj call s:NetrwDelete(fname)
7248     endfor
7249     if s:NetrwLcd(curdir)
7250"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7251      return
7252     endif
7253     if delete(tmpdir,"d")
7254      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
7255     endif
7256    else
7257     if s:NetrwLcd(curdir)
7258"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7259      return
7260     endif
7261    endif
7262   endif
7263  endif
7264
7265  " -------
7266  " cleanup
7267  " -------
7268"  call Decho("cleanup",'~'.expand("<slnum>"))
7269  " remove markings from local buffer
7270  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7271"  call Decho(" g:netrw_fastbrowse  =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
7272"  call Decho(" s:netrwmftgt        =".s:netrwmftgt,'~'.expand("<slnum>"))
7273"  call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
7274"  call Decho(" curdir              =".curdir,'~'.expand("<slnum>"))
7275"  call Decho(" a:islocal           =".a:islocal,'~'.expand("<slnum>"))
7276"  call Decho(" curbufnr            =".curbufnr,'~'.expand("<slnum>"))
7277  if exists("s:recursive")
7278"   call Decho(" s:recursive         =".s:recursive,'~'.expand("<slnum>"))
7279  else
7280"   call Decho(" s:recursive         =n/a",'~'.expand("<slnum>"))
7281  endif
7282  " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
7283  if g:netrw_fastbrowse <= 1
7284   NetrwKeepj call s:LocalBrowseRefresh()
7285  else
7286   " refresh local and targets for fast browsing
7287   if !exists("s:recursive")
7288    " remove markings from local buffer
7289"    call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
7290    NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
7291   endif
7292
7293   " refresh buffers
7294   if s:netrwmftgt_islocal
7295"    call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
7296    NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7297   endif
7298   if a:islocal && s:netrwmftgt != curdir
7299"    call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
7300    NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
7301   endif
7302  endif
7303
7304"  call Dret("s:NetrwMarkFileCopy 1")
7305  return 1
7306endfun
7307
7308" ---------------------------------------------------------------------
7309" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
7310"                      invoke vim's diff mode on the marked files.
7311"                      Either two or three files can be so handled.
7312"                      Uses the global marked file list.
7313fun! s:NetrwMarkFileDiff(islocal)
7314"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
7315  let curbufnr= bufnr("%")
7316
7317  " sanity check
7318  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7319   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7320"   call Dret("s:NetrwMarkFileDiff")
7321   return
7322  endif
7323  let curdir= s:NetrwGetCurdir(a:islocal)
7324"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7325
7326  if exists("s:netrwmarkfilelist_{".curbufnr."}")
7327   let cnt    = 0
7328   for fname in s:netrwmarkfilelist
7329    let cnt= cnt + 1
7330    if cnt == 1
7331"     call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
7332     exe "NetrwKeepj e ".fnameescape(fname)
7333     diffthis
7334    elseif cnt == 2 || cnt == 3
7335     vsplit
7336     wincmd l
7337"     call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
7338     exe "NetrwKeepj e ".fnameescape(fname)
7339     diffthis
7340    else
7341     break
7342    endif
7343   endfor
7344   call s:NetrwUnmarkList(curbufnr,curdir)
7345  endif
7346
7347"  call Dret("s:NetrwMarkFileDiff")
7348endfun
7349
7350" ---------------------------------------------------------------------
7351" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
7352"                       Uses global markfilelist
7353fun! s:NetrwMarkFileEdit(islocal)
7354"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
7355
7356  let curdir   = s:NetrwGetCurdir(a:islocal)
7357  let curbufnr = bufnr("%")
7358
7359  " sanity check
7360  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7361   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7362"   call Dret("s:NetrwMarkFileEdit")
7363   return
7364  endif
7365"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7366
7367  if exists("s:netrwmarkfilelist_{curbufnr}")
7368   call s:SetRexDir(a:islocal,curdir)
7369   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7370   " unmark markedfile list
7371"   call s:NetrwUnmarkList(curbufnr,curdir)
7372   call s:NetrwUnmarkAll()
7373"   call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
7374   exe "sil args ".flist
7375  endif
7376  echo "(use :bn, :bp to navigate files; :Rex to return)"
7377
7378"  call Dret("s:NetrwMarkFileEdit")
7379endfun
7380
7381" ---------------------------------------------------------------------
7382" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
7383fun! s:NetrwMarkFileQFEL(islocal,qfel)
7384"  call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
7385  call s:NetrwUnmarkAll()
7386  let curbufnr= bufnr("%")
7387
7388  if !empty(a:qfel)
7389   for entry in a:qfel
7390    let bufnmbr= entry["bufnr"]
7391"    call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
7392    if !exists("s:netrwmarkfilelist_{curbufnr}")
7393"     call Decho("case: no marked file list",'~'.expand("<slnum>"))
7394     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7395    elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
7396     " s:NetrwMarkFile will remove duplicate entries from the marked file list.
7397     " So, this test lets two or more hits on the same pattern to be ignored.
7398"     call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
7399     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7400    else
7401"     call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
7402    endif
7403   endfor
7404   echo "(use me to edit marked files)"
7405  else
7406   call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
7407  endif
7408
7409"  call Dret("s:NetrwMarkFileQFEL")
7410endfun
7411
7412" ---------------------------------------------------------------------
7413" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
7414"                     mx enbloc=0: Uses the local marked-file list, applies command to each file individually
7415"                     mX enbloc=1: Uses the global marked-file list, applies command to entire list
7416fun! s:NetrwMarkFileExe(islocal,enbloc)
7417"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")")
7418  let svpos    = winsaveview()
7419"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7420  let curdir   = s:NetrwGetCurdir(a:islocal)
7421  let curbufnr = bufnr("%")
7422
7423  if a:enbloc == 0
7424   " individually apply command to files, one at a time
7425    " sanity check
7426    if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7427     NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7428"     call Dret("s:NetrwMarkFileExe")
7429     return
7430    endif
7431"    call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7432
7433    if exists("s:netrwmarkfilelist_{curbufnr}")
7434     " get the command
7435     call inputsave()
7436     let cmd= input("Enter command: ","","file")
7437     call inputrestore()
7438"     call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7439     if cmd == ""
7440"      call Dret("s:NetrwMarkFileExe : early exit, empty command")
7441      return
7442     endif
7443
7444     " apply command to marked files, individually.  Substitute: filename -> %
7445     " If no %, then append a space and the filename to the command
7446     for fname in s:netrwmarkfilelist_{curbufnr}
7447      if a:islocal
7448       if g:netrw_keepdir
7449	let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
7450       endif
7451      else
7452       let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
7453      endif
7454      if cmd =~ '%'
7455       let xcmd= substitute(cmd,'%',fname,'g')
7456      else
7457       let xcmd= cmd.' '.fname
7458      endif
7459      if a:islocal
7460"       call Decho("local: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7461       let ret= system(xcmd)
7462      else
7463"       call Decho("remote: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7464       let ret= s:RemoteSystem(xcmd)
7465      endif
7466      if v:shell_error < 0
7467       NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7468       break
7469      else
7470       echo ret
7471      endif
7472     endfor
7473
7474   " unmark marked file list
7475   call s:NetrwUnmarkList(curbufnr,curdir)
7476
7477   " refresh the listing
7478   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7479"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7480   NetrwKeepj call winrestview(svpos)
7481  else
7482   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7483  endif
7484
7485 else " apply command to global list of files, en bloc
7486
7487  call inputsave()
7488  let cmd= input("Enter command: ","","file")
7489  call inputrestore()
7490"  call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7491  if cmd == ""
7492"   call Dret("s:NetrwMarkFileExe : early exit, empty command")
7493   return
7494  endif
7495  if cmd =~ '%'
7496   let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7497  else
7498   let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7499  endif
7500  if a:islocal
7501   call system(cmd)
7502   if v:shell_error < 0
7503    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7504   endif
7505  else
7506   let ret= s:RemoteSystem(cmd)
7507  endif
7508  call s:NetrwUnmarkAll()
7509
7510  " refresh the listing
7511  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7512"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7513  NetrwKeepj call winrestview(svpos)
7514
7515 endif
7516
7517"  call Dret("s:NetrwMarkFileExe")
7518endfun
7519
7520" ---------------------------------------------------------------------
7521" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7522"                  as the marked file(s) (toggles suffix presence)
7523"                  Uses the local marked file list.
7524fun! s:NetrwMarkHideSfx(islocal)
7525"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7526  let svpos    = winsaveview()
7527"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7528  let curbufnr = bufnr("%")
7529
7530  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7531  if exists("s:netrwmarkfilelist_{curbufnr}")
7532
7533   for fname in s:netrwmarkfilelist_{curbufnr}
7534"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7535     " construct suffix pattern
7536     if fname =~ '\.'
7537      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7538     else
7539      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7540     endif
7541     " determine if its in the hiding list or not
7542     let inhidelist= 0
7543     if g:netrw_list_hide != ""
7544      let itemnum = 0
7545      let hidelist= split(g:netrw_list_hide,',')
7546      for hidepat in hidelist
7547       if sfxpat == hidepat
7548        let inhidelist= 1
7549        break
7550       endif
7551       let itemnum= itemnum + 1
7552      endfor
7553     endif
7554"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7555     if inhidelist
7556      " remove sfxpat from list
7557      call remove(hidelist,itemnum)
7558      let g:netrw_list_hide= join(hidelist,",")
7559     elseif g:netrw_list_hide != ""
7560      " append sfxpat to non-empty list
7561      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7562     else
7563      " set hiding list to sfxpat
7564      let g:netrw_list_hide= sfxpat
7565     endif
7566    endfor
7567
7568   " refresh the listing
7569   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7570"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7571   NetrwKeepj call winrestview(svpos)
7572  else
7573   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7574  endif
7575
7576"  call Dret("s:NetrwMarkHideSfx")
7577endfun
7578
7579" ---------------------------------------------------------------------
7580" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7581"                     Uses the local marked-file list.
7582fun! s:NetrwMarkFileVimCmd(islocal)
7583"  call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")")
7584  let svpos    = winsaveview()
7585"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7586  let curdir   = s:NetrwGetCurdir(a:islocal)
7587  let curbufnr = bufnr("%")
7588
7589  " sanity check
7590  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7591   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7592"   call Dret("s:NetrwMarkFileVimCmd")
7593   return
7594  endif
7595"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7596
7597  if exists("s:netrwmarkfilelist_{curbufnr}")
7598   " get the command
7599   call inputsave()
7600   let cmd= input("Enter vim command: ","","file")
7601   call inputrestore()
7602"   call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7603   if cmd == ""
7604"    "   call Dret("s:NetrwMarkFileVimCmd : early exit, empty command")
7605    return
7606   endif
7607
7608   " apply command to marked files.  Substitute: filename -> %
7609   " If no %, then append a space and the filename to the command
7610   for fname in s:netrwmarkfilelist_{curbufnr}
7611"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7612    if a:islocal
7613     1split
7614     exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7615"     call Decho("local<".fname.">: exe ".cmd,'~'.expand("<slnum>"))
7616     exe cmd
7617     exe "sil! keepalt wq!"
7618    else
7619"     call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET",'~'.expand("<slnum>"))
7620     echo "sorry, \"mv\" not supported yet for remote files"
7621    endif
7622   endfor
7623
7624   " unmark marked file list
7625   call s:NetrwUnmarkList(curbufnr,curdir)
7626
7627   " refresh the listing
7628   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7629"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7630   NetrwKeepj call winrestview(svpos)
7631  else
7632   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7633  endif
7634
7635"  call Dret("s:NetrwMarkFileVimCmd")
7636endfun
7637
7638" ---------------------------------------------------------------------
7639" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7640"                  as the marked file(s) (toggles suffix presence)
7641"                  Uses the local marked file list.
7642fun! s:NetrwMarkHideSfx(islocal)
7643"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7644  let svpos    = winsaveview()
7645"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7646  let curbufnr = bufnr("%")
7647
7648  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7649  if exists("s:netrwmarkfilelist_{curbufnr}")
7650
7651   for fname in s:netrwmarkfilelist_{curbufnr}
7652"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7653     " construct suffix pattern
7654     if fname =~ '\.'
7655      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7656     else
7657      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7658     endif
7659     " determine if its in the hiding list or not
7660     let inhidelist= 0
7661     if g:netrw_list_hide != ""
7662      let itemnum = 0
7663      let hidelist= split(g:netrw_list_hide,',')
7664      for hidepat in hidelist
7665       if sfxpat == hidepat
7666        let inhidelist= 1
7667        break
7668       endif
7669       let itemnum= itemnum + 1
7670      endfor
7671     endif
7672"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7673     if inhidelist
7674      " remove sfxpat from list
7675      call remove(hidelist,itemnum)
7676      let g:netrw_list_hide= join(hidelist,",")
7677     elseif g:netrw_list_hide != ""
7678      " append sfxpat to non-empty list
7679      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7680     else
7681      " set hiding list to sfxpat
7682      let g:netrw_list_hide= sfxpat
7683     endif
7684    endfor
7685
7686   " refresh the listing
7687   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7688"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7689   NetrwKeepj call winrestview(svpos)
7690  else
7691   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7692  endif
7693
7694"  call Dret("s:NetrwMarkHideSfx")
7695endfun
7696
7697" ---------------------------------------------------------------------
7698" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7699"                     Uses the global markfilelist
7700fun! s:NetrwMarkFileGrep(islocal)
7701"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7702  let svpos    = winsaveview()
7703"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7704  let curbufnr = bufnr("%")
7705  let curdir   = s:NetrwGetCurdir(a:islocal)
7706
7707  if exists("s:netrwmarkfilelist")
7708"   call Decho("using s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7709   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7710"   call Decho("keeping copy of s:netrwmarkfilelist in function-local variable,'~'.expand("<slnum>"))"
7711   call s:NetrwUnmarkAll()
7712  else
7713"   call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7714   let netrwmarkfilelist= "*"
7715  endif
7716
7717  " ask user for pattern
7718"  call Decho("ask user for search pattern",'~'.expand("<slnum>"))
7719  call inputsave()
7720  let pat= input("Enter pattern: ","")
7721  call inputrestore()
7722  let patbang = ""
7723  if pat =~ '^!'
7724   let patbang = "!"
7725   let pat     = strpart(pat,2)
7726  endif
7727  if pat =~ '^\i'
7728   let pat    = escape(pat,'/')
7729   let pat    = '/'.pat.'/'
7730  else
7731   let nonisi = pat[0]
7732  endif
7733
7734  " use vimgrep for both local and remote
7735"  call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7736  try
7737   exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7738  catch /^Vim\%((\a\+)\)\=:E480/
7739   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7740"   call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7741   return
7742  endtry
7743  echo "(use :cn, :cp to navigate, :Rex to return)"
7744
7745  2match none
7746"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7747  NetrwKeepj call winrestview(svpos)
7748
7749  if exists("nonisi")
7750   " original, user-supplied pattern did not begin with a character from isident
7751"   call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7752   if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7753    call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7754   endif
7755  endif
7756
7757"  call Dret("s:NetrwMarkFileGrep")
7758endfun
7759
7760" ---------------------------------------------------------------------
7761" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7762"                      uses the global marked file list
7763"                      s:netrwmfloc= 0: target directory is remote
7764"                                  = 1: target directory is local
7765fun! s:NetrwMarkFileMove(islocal)
7766"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7767  let curdir   = s:NetrwGetCurdir(a:islocal)
7768  let curbufnr = bufnr("%")
7769
7770  " sanity check
7771  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7772   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7773"   call Dret("s:NetrwMarkFileMove")
7774   return
7775  endif
7776"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7777
7778  if !exists("s:netrwmftgt")
7779   NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7780"   call Dret("s:NetrwMarkFileCopy 0")
7781   return 0
7782  endif
7783"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7784
7785  if      a:islocal &&  s:netrwmftgt_islocal
7786   " move: local -> local
7787"   call Decho("move from local to local",'~'.expand("<slnum>"))
7788"   call Decho("local to local move",'~'.expand("<slnum>"))
7789   if !executable(g:netrw_localmovecmd)
7790    call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7791"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7792    return
7793   endif
7794   let tgt = s:ShellEscape(s:netrwmftgt)
7795"   call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7796   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7797    let tgt= substitute(tgt, '/','\\','g')
7798"    call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7799    if g:netrw_localmovecmd =~ '\s'
7800     let movecmd     = substitute(g:netrw_localmovecmd,'\s.*$','','')
7801     let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7802     let movecmd     = netrw#WinPath(movecmd).movecmdargs
7803"     call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7804    else
7805     let movecmd = netrw#WinPath(movecmd)
7806"     call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7807    endif
7808   else
7809    let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7810"    call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7811   endif
7812   for fname in s:netrwmarkfilelist_{bufnr("%")}
7813    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7814     let fname= substitute(fname,'/','\\','g')
7815    endif
7816"    call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7817    let ret= system(movecmd.g:netrw_localmovecmdopt." ".s:ShellEscape(fname)." ".tgt)
7818    if v:shell_error != 0
7819     if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7820      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)
7821     else
7822      call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7823     endif
7824     break
7825    endif
7826   endfor
7827
7828  elseif  a:islocal && !s:netrwmftgt_islocal
7829   " move: local -> remote
7830"   call Decho("move from local to remote",'~'.expand("<slnum>"))
7831"   call Decho("copy",'~'.expand("<slnum>"))
7832   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7833   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7834"   call Decho("remove",'~'.expand("<slnum>"))
7835   for fname in mflist
7836    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7837    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7838   endfor
7839   unlet mflist
7840
7841  elseif !a:islocal &&  s:netrwmftgt_islocal
7842   " move: remote -> local
7843"   call Decho("move from remote to local",'~'.expand("<slnum>"))
7844"   call Decho("copy",'~'.expand("<slnum>"))
7845   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7846   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7847"   call Decho("remove",'~'.expand("<slnum>"))
7848   for fname in mflist
7849    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7850    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7851   endfor
7852   unlet mflist
7853
7854  elseif !a:islocal && !s:netrwmftgt_islocal
7855   " move: remote -> remote
7856"   call Decho("move from remote to remote",'~'.expand("<slnum>"))
7857"   call Decho("copy",'~'.expand("<slnum>"))
7858   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7859   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7860"   call Decho("remove",'~'.expand("<slnum>"))
7861   for fname in mflist
7862    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7863    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7864   endfor
7865   unlet mflist
7866  endif
7867
7868  " -------
7869  " cleanup
7870  " -------
7871"  call Decho("cleanup",'~'.expand("<slnum>"))
7872
7873  " remove markings from local buffer
7874  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7875
7876  " refresh buffers
7877  if !s:netrwmftgt_islocal
7878"   call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7879   NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7880  endif
7881  if a:islocal
7882"   call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7883   NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7884  endif
7885  if g:netrw_fastbrowse <= 1
7886"   call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7887   NetrwKeepj call s:LocalBrowseRefresh()
7888  endif
7889
7890"  call Dret("s:NetrwMarkFileMove")
7891endfun
7892
7893" ---------------------------------------------------------------------
7894" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7895"                       using the hardcopy command.  Local marked-file list only.
7896fun! s:NetrwMarkFilePrint(islocal)
7897"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7898  let curbufnr= bufnr("%")
7899
7900  " sanity check
7901  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7902   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7903"   call Dret("s:NetrwMarkFilePrint")
7904   return
7905  endif
7906"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7907  let curdir= s:NetrwGetCurdir(a:islocal)
7908
7909  if exists("s:netrwmarkfilelist_{curbufnr}")
7910   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7911   call s:NetrwUnmarkList(curbufnr,curdir)
7912   for fname in netrwmarkfilelist
7913    if a:islocal
7914     if g:netrw_keepdir
7915      let fname= s:ComposePath(curdir,fname)
7916     endif
7917    else
7918     let fname= curdir.fname
7919    endif
7920    1split
7921    " the autocmds will handle both local and remote files
7922"    call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7923    exe "sil NetrwKeepj e ".fnameescape(fname)
7924"    call Decho("hardcopy",'~'.expand("<slnum>"))
7925    hardcopy
7926    q
7927   endfor
7928   2match none
7929  endif
7930"  call Dret("s:NetrwMarkFilePrint")
7931endfun
7932
7933" ---------------------------------------------------------------------
7934" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7935"                        files when given a regexp (for which a prompt is
7936"                        issued) (matches to name of files).
7937fun! s:NetrwMarkFileRegexp(islocal)
7938"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7939
7940  " get the regular expression
7941  call inputsave()
7942  let regexp= input("Enter regexp: ","","file")
7943  call inputrestore()
7944
7945  if a:islocal
7946   let curdir= s:NetrwGetCurdir(a:islocal)
7947"   call Decho("curdir<".fnameescape(curdir).">")
7948   " get the matching list of files using local glob()
7949"   call Decho("handle local regexp",'~'.expand("<slnum>"))
7950   let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7951   if v:version > 704 || (v:version == 704 && has("patch656"))
7952    let filelist= glob(s:ComposePath(dirname,regexp),0,1,1)
7953   else
7954    let files   = glob(s:ComposePath(dirname,regexp),0,0)
7955    let filelist= split(files,"\n")
7956   endif
7957"   call Decho("files<".string(filelist).">",'~'.expand("<slnum>"))
7958
7959  " mark the list of files
7960  for fname in filelist
7961   if fname =~ '^'.fnameescape(curdir)
7962"    call Decho("fname<".substitute(fname,'^'.fnameescape(curdir).'/','','').">",'~'.expand("<slnum>"))
7963    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^'.fnameescape(curdir).'/','',''))
7964   else
7965"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7966    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7967   endif
7968  endfor
7969
7970  else
7971"   call Decho("handle remote regexp",'~'.expand("<slnum>"))
7972
7973   " convert displayed listing into a filelist
7974   let eikeep = &ei
7975   let areg   = @a
7976   sil NetrwKeepj %y a
7977   setl ei=all ma
7978"   call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7979   1split
7980   NetrwKeepj call s:NetrwEnew()
7981   NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
7982   sil NetrwKeepj norm! "ap
7983   NetrwKeepj 2
7984   let bannercnt= search('^" =====','W')
7985   exe "sil NetrwKeepj 1,".bannercnt."d"
7986   setl bt=nofile
7987   if     g:netrw_liststyle == s:LONGLIST
7988    sil NetrwKeepj %s/\s\{2,}\S.*$//e
7989    call histdel("/",-1)
7990   elseif g:netrw_liststyle == s:WIDELIST
7991    sil NetrwKeepj %s/\s\{2,}/\r/ge
7992    call histdel("/",-1)
7993   elseif g:netrw_liststyle == s:TREELIST
7994    exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7995    sil! NetrwKeepj g/^ .*$/d
7996    call histdel("/",-1)
7997    call histdel("/",-1)
7998   endif
7999   " convert regexp into the more usual glob-style format
8000   let regexp= substitute(regexp,'\*','.*','g')
8001"   call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
8002   exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
8003   call histdel("/",-1)
8004   let filelist= getline(1,line("$"))
8005   q!
8006   for filename in filelist
8007    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
8008   endfor
8009   unlet filelist
8010   let @a  = areg
8011   let &ei = eikeep
8012  endif
8013  echo "  (use me to edit marked files)"
8014
8015"  call Dret("s:NetrwMarkFileRegexp")
8016endfun
8017
8018" ---------------------------------------------------------------------
8019" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
8020"                        Uses the local marked file list.
8021fun! s:NetrwMarkFileSource(islocal)
8022"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
8023  let curbufnr= bufnr("%")
8024
8025  " sanity check
8026  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
8027   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
8028"   call Dret("s:NetrwMarkFileSource")
8029   return
8030  endif
8031"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
8032  let curdir= s:NetrwGetCurdir(a:islocal)
8033
8034  if exists("s:netrwmarkfilelist_{curbufnr}")
8035   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
8036   call s:NetrwUnmarkList(curbufnr,curdir)
8037   for fname in netrwmarkfilelist
8038    if a:islocal
8039     if g:netrw_keepdir
8040      let fname= s:ComposePath(curdir,fname)
8041     endif
8042    else
8043     let fname= curdir.fname
8044    endif
8045    " the autocmds will handle sourcing both local and remote files
8046"    call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
8047    exe "so ".fnameescape(fname)
8048   endfor
8049   2match none
8050  endif
8051"  call Dret("s:NetrwMarkFileSource")
8052endfun
8053
8054" ---------------------------------------------------------------------
8055" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
8056"                     Uses the global markfilelist
8057fun! s:NetrwMarkFileTag(islocal)
8058"  call Dfunc("s:NetrwMarkFileTag(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 curbufnr = bufnr("%")
8063
8064  " sanity check
8065  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
8066   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
8067"   call Dret("s:NetrwMarkFileTag")
8068   return
8069  endif
8070"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
8071
8072  if exists("s:netrwmarkfilelist")
8073"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
8074   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
8075   call s:NetrwUnmarkAll()
8076
8077   if a:islocal
8078
8079"    call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("<slnum>"))
8080    call system(g:netrw_ctags." ".netrwmarkfilelist)
8081    if v:shell_error
8082     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
8083    endif
8084
8085   else
8086    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
8087    call netrw#Obtain(a:islocal,"tags")
8088    let curdir= b:netrw_curdir
8089    1split
8090    NetrwKeepj e tags
8091    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
8092"    call Decho("curdir<".curdir."> path<".path.">",'~'.expand("<slnum>"))
8093    exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
8094    call histdel("/",-1)
8095    wq!
8096   endif
8097   2match none
8098   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8099"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8100   call winrestview(svpos)
8101  endif
8102
8103"  call Dret("s:NetrwMarkFileTag")
8104endfun
8105
8106" ---------------------------------------------------------------------
8107" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
8108"   Sets up two variables,
8109"     s:netrwmftgt         : holds the target directory
8110"     s:netrwmftgt_islocal : 0=target directory is remote
8111"                            1=target directory is local
8112fun! s:NetrwMarkFileTgt(islocal)
8113" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
8114  let svpos  = winsaveview()
8115"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8116  let curdir = s:NetrwGetCurdir(a:islocal)
8117  let hadtgt = exists("s:netrwmftgt")
8118  if !exists("w:netrw_bannercnt")
8119   let w:netrw_bannercnt= b:netrw_bannercnt
8120  endif
8121
8122  " set up target
8123  if line(".") < w:netrw_bannercnt
8124"   call Decho("set up target: line(.) < w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
8125   " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
8126   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
8127"    call Decho("cursor in banner region, and target already is <".b:netrw_curdir.">: removing target",'~'.expand("<slnum>"))
8128    unlet s:netrwmftgt s:netrwmftgt_islocal
8129    if g:netrw_fastbrowse <= 1
8130     call s:LocalBrowseRefresh()
8131    endif
8132    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8133"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8134    call winrestview(svpos)
8135"    call Dret("s:NetrwMarkFileTgt : removed target")
8136    return
8137   else
8138    let s:netrwmftgt= b:netrw_curdir
8139"    call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8140   endif
8141
8142  else
8143   " get word under cursor.
8144   "  * If directory, use it for the target.
8145   "  * If file, use b:netrw_curdir for the target
8146"   call Decho("get word under cursor",'~'.expand("<slnum>"))
8147   let curword= s:NetrwGetWord()
8148   let tgtdir = s:ComposePath(curdir,curword)
8149   if a:islocal && isdirectory(s:NetrwFile(tgtdir))
8150    let s:netrwmftgt = tgtdir
8151"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8152   elseif !a:islocal && tgtdir =~ '/$'
8153    let s:netrwmftgt = tgtdir
8154"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8155   else
8156    let s:netrwmftgt = curdir
8157"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8158   endif
8159  endif
8160  if a:islocal
8161   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
8162   let s:netrwmftgt= simplify(s:netrwmftgt)
8163"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8164  endif
8165  if g:netrw_cygwin
8166   let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
8167   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
8168  endif
8169  let s:netrwmftgt_islocal= a:islocal
8170
8171  " need to do refresh so that the banner will be updated
8172  "  s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
8173  if g:netrw_fastbrowse <= 1
8174"   call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers",'~'.expand("<slnum>"))
8175   call s:LocalBrowseRefresh()
8176  endif
8177"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8178  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8179   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop))
8180  else
8181   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8182  endif
8183"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8184  call winrestview(svpos)
8185  if !hadtgt
8186   sil! NetrwKeepj norm! j
8187  endif
8188
8189"  call Decho("getmatches=".string(getmatches()),'~'.expand("<slnum>"))
8190"  call Decho("s:netrwmarkfilelist=".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : 'n/a'),'~'.expand("<slnum>"))
8191"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
8192endfun
8193
8194" ---------------------------------------------------------------------
8195" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
8196fun! s:NetrwGetCurdir(islocal)
8197"  call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
8198
8199  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8200   let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
8201"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
8202  elseif !exists("b:netrw_curdir")
8203   let b:netrw_curdir= getcwd()
8204"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
8205  endif
8206
8207"  call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>"))
8208  if b:netrw_curdir !~ '\<\a\{3,}://'
8209   let curdir= b:netrw_curdir
8210"   call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
8211   if g:netrw_keepdir == 0
8212    call s:NetrwLcd(curdir)
8213   endif
8214  endif
8215
8216"  call Dret("s:NetrwGetCurdir <".curdir.">")
8217  return b:netrw_curdir
8218endfun
8219
8220" ---------------------------------------------------------------------
8221" s:NetrwOpenFile: query user for a filename and open it {{{2
8222fun! s:NetrwOpenFile(islocal)
8223"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
8224  let ykeep= @@
8225  call inputsave()
8226  let fname= input("Enter filename: ")
8227  call inputrestore()
8228"  call Decho("(s:NetrwOpenFile) fname<".fname.">",'~'.expand("<slnum>"))
8229
8230  " determine if Lexplore is in use
8231  if exists("t:netrw_lexbufnr")
8232   " check if t:netrw_lexbufnr refers to a netrw window
8233"   call Decho("(s:netrwOpenFile) ..t:netrw_lexbufnr=".t:netrw_lexbufnr,'~'.expand("<slnum>"))
8234   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
8235   if lexwinnr != -1 && exists("g:netrw_chgwin") && g:netrw_chgwin != -1
8236"    call Decho("(s:netrwOpenFile) ..Lexplore in use",'~'.expand("<slnum>"))
8237    exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
8238    exe "NetrwKeepj e ".fnameescape(fname)
8239    let @@= ykeep
8240"    call Dret("s:NetrwOpenFile : creating a file with Lexplore mode")
8241   endif
8242  endif
8243
8244  " Does the filename contain a path?
8245  if fname !~ '[/\\]'
8246   if exists("b:netrw_curdir")
8247    if exists("g:netrw_quiet")
8248     let netrw_quiet_keep = g:netrw_quiet
8249    endif
8250    let g:netrw_quiet = 1
8251    " save position for benefit of Rexplore
8252    let s:rexposn_{bufnr("%")}= winsaveview()
8253"    call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
8254    if b:netrw_curdir =~ '/$'
8255     exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
8256    else
8257     exe "e ".fnameescape(b:netrw_curdir."/".fname)
8258    endif
8259    if exists("netrw_quiet_keep")
8260     let g:netrw_quiet= netrw_quiet_keep
8261    else
8262     unlet g:netrw_quiet
8263    endif
8264   endif
8265  else
8266   exe "NetrwKeepj e ".fnameescape(fname)
8267  endif
8268  let @@= ykeep
8269"  call Dret("s:NetrwOpenFile")
8270endfun
8271
8272" ---------------------------------------------------------------------
8273" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
8274"               For the mapping to this function be made via
8275"               netrwPlugin, you'll need to have had
8276"               g:netrw_usetab set to non-zero.
8277fun! netrw#Shrink()
8278"  call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
8279  let curwin  = winnr()
8280  let wiwkeep = &wiw
8281  set wiw=1
8282
8283  if &ft == "netrw"
8284   if winwidth(0) > g:netrw_wiw
8285    let t:netrw_winwidth= winwidth(0)
8286    exe "vert resize ".g:netrw_wiw
8287    wincmd l
8288    if winnr() == curwin
8289     wincmd h
8290    endif
8291"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8292   else
8293    exe "vert resize ".t:netrw_winwidth
8294"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8295   endif
8296
8297  elseif exists("t:netrw_lexbufnr")
8298   exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
8299   if     winwidth(bufwinnr(t:netrw_lexbufnr)) >  g:netrw_wiw
8300    let t:netrw_winwidth= winwidth(0)
8301    exe "vert resize ".g:netrw_wiw
8302    wincmd l
8303    if winnr() == curwin
8304     wincmd h
8305    endif
8306"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8307   elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
8308    exe "vert resize ".t:netrw_winwidth
8309"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8310   else
8311    call netrw#Lexplore(0,0)
8312   endif
8313
8314  else
8315   call netrw#Lexplore(0,0)
8316  endif
8317  let wiw= wiwkeep
8318
8319"  call Dret("netrw#Shrink")
8320endfun
8321
8322" ---------------------------------------------------------------------
8323" s:NetSortSequence: allows user to edit the sorting sequence {{{2
8324fun! s:NetSortSequence(islocal)
8325"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
8326
8327  let ykeep= @@
8328  let svpos= winsaveview()
8329"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8330  call inputsave()
8331  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
8332  call inputrestore()
8333
8334  " refresh the listing
8335  let g:netrw_sort_sequence= newsortseq
8336  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8337"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8338  NetrwKeepj call winrestview(svpos)
8339  let @@= ykeep
8340
8341"  call Dret("NetSortSequence")
8342endfun
8343
8344" ---------------------------------------------------------------------
8345" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
8346"   User access provided by the <mF> mapping. (see :help netrw-mF)
8347"   Used by many MarkFile functions.
8348fun! s:NetrwUnmarkList(curbufnr,curdir)
8349"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
8350
8351  "  remove all files in local marked-file list from global list
8352  if exists("s:netrwmarkfilelist")
8353   for mfile in s:netrwmarkfilelist_{a:curbufnr}
8354    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
8355    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
8356    call remove(s:netrwmarkfilelist,idx)            " remove from global list
8357   endfor
8358   if s:netrwmarkfilelist == []
8359    unlet s:netrwmarkfilelist
8360   endif
8361
8362   " getting rid of the local marked-file lists is easy
8363   unlet s:netrwmarkfilelist_{a:curbufnr}
8364  endif
8365  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
8366   unlet s:netrwmarkfilemtch_{a:curbufnr}
8367  endif
8368  2match none
8369"  call Dret("s:NetrwUnmarkList")
8370endfun
8371
8372" ---------------------------------------------------------------------
8373" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
8374fun! s:NetrwUnmarkAll()
8375"  call Dfunc("s:NetrwUnmarkAll()")
8376  if exists("s:netrwmarkfilelist")
8377   unlet s:netrwmarkfilelist
8378  endif
8379  sil call s:NetrwUnmarkAll2()
8380  2match none
8381"  call Dret("s:NetrwUnmarkAll")
8382endfun
8383
8384" ---------------------------------------------------------------------
8385" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
8386fun! s:NetrwUnmarkAll2()
8387"  call Dfunc("s:NetrwUnmarkAll2()")
8388  redir => netrwmarkfilelist_let
8389  let
8390  redir END
8391  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
8392  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
8393  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
8394  for flist in netrwmarkfilelist_list
8395   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
8396   unlet s:netrwmarkfilelist_{curbufnr}
8397   unlet s:netrwmarkfilemtch_{curbufnr}
8398  endfor
8399"  call Dret("s:NetrwUnmarkAll2")
8400endfun
8401
8402" ---------------------------------------------------------------------
8403" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
8404"
8405" Marked files are in two types of lists:
8406"    s:netrwmarkfilelist    -- holds complete paths to all marked files
8407"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
8408"
8409" Marked files suitable for use with 2match are in:
8410"    s:netrwmarkfilemtch_#   -- used with 2match to display marked files
8411fun! s:NetrwUnMarkFile(islocal)
8412"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
8413  let svpos    = winsaveview()
8414"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8415  let curbufnr = bufnr("%")
8416
8417  " unmark marked file list
8418  " (although I expect s:NetrwUpload() to do it, I'm just making sure)
8419  if exists("s:netrwmarkfilelist")
8420"   "   call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
8421   unlet s:netrwmarkfilelist
8422  endif
8423
8424  let ibuf= 1
8425  while ibuf < bufnr("$")
8426   if exists("s:netrwmarkfilelist_".ibuf)
8427    unlet s:netrwmarkfilelist_{ibuf}
8428    unlet s:netrwmarkfilemtch_{ibuf}
8429   endif
8430   let ibuf = ibuf + 1
8431  endwhile
8432  2match none
8433
8434"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8435"call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8436call winrestview(svpos)
8437"  call Dret("s:NetrwUnMarkFile")
8438endfun
8439
8440" ---------------------------------------------------------------------
8441" s:NetrwMenu: generates the menu for gvim and netrw {{{2
8442fun! s:NetrwMenu(domenu)
8443
8444  if !exists("g:NetrwMenuPriority")
8445   let g:NetrwMenuPriority= 80
8446  endif
8447
8448  if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8449"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
8450
8451   if !exists("s:netrw_menu_enabled") && a:domenu
8452"    call Decho("initialize menu",'~'.expand("<slnum>"))
8453    let s:netrw_menu_enabled= 1
8454    exe 'sil! menu '.g:NetrwMenuPriority.'.1      '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
8455    exe 'sil! menu '.g:NetrwMenuPriority.'.5      '.g:NetrwTopLvlMenu.'-Sep1-	:'
8456    exe 'sil! menu '.g:NetrwMenuPriority.'.6      '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
8457    exe 'sil! menu '.g:NetrwMenuPriority.'.7      '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
8458    if g:netrw_dirhistmax > 0
8459     exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
8460     exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
8461     exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
8462     exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
8463    else
8464     exe 'sil! menu '.g:NetrwMenuPriority.'.8     '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History	:echo "(disabled)"'."\<cr>"
8465    endif
8466    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1    '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o	o'
8467    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2    '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v	v'
8468    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3    '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t	t'
8469    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4    '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p	p'
8470    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
8471    exe 'sil! menu '.g:NetrwMenuPriority.'.9.6    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
8472    exe 'sil! menu '.g:NetrwMenuPriority.'.9.7    '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
8473    exe 'sil! menu '.g:NetrwMenuPriority.'.9.8    '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
8474    exe 'sil! menu '.g:NetrwMenuPriority.'.9.9    '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
8475    exe 'sil! menu '.g:NetrwMenuPriority.'.10     '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
8476    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
8477    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
8478    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
8479    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
8480    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
8481    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t	t'
8482    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
8483    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1   '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
8484    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
8485    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
8486    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
8487    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
8488    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
8489    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
8490    exe 'sil! menu '.g:NetrwMenuPriority.'.13     '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
8491    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
8492    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
8493    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3   '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
8494    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4   '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
8495    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5   '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
8496    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6   '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
8497    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7   '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
8498    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8   '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
8499    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9   '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
8500    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10  '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
8501    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11  '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
8502    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12  '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
8503    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13  '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
8504    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14  '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
8505    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15  '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
8506    exe 'sil! menu '.g:NetrwMenuPriority.'.15     '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
8507    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i	:let w:netrw_liststyle=0<cr><c-L>'
8508    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i	:let w:netrw_liststyle=1<cr><c-L>'
8509    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i	:let w:netrw_liststyle=2<cr><c-L>'
8510    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i	:let w:netrw_liststyle=3<cr><c-L>'
8511    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>'
8512    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>'
8513    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>'
8514    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3   '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
8515    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>'
8516    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>'
8517    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>'
8518    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>'
8519    exe 'sil! menu '.g:NetrwMenuPriority.'.17     '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
8520    exe 'sil! menu '.g:NetrwMenuPriority.'.18     '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
8521    let s:netrw_menucnt= 28
8522    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
8523    call s:NetrwTgtMenu()      " let bookmarks and history be easy targets
8524
8525   elseif !a:domenu
8526    let s:netrwcnt = 0
8527    let curwin     = winnr()
8528    windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8529    exe curwin."wincmd w"
8530
8531    if s:netrwcnt <= 1
8532"     call Decho("clear menus",'~'.expand("<slnum>"))
8533     exe 'sil! unmenu '.g:NetrwTopLvlMenu
8534"     call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8535     sil! unlet s:netrw_menu_enabled
8536    endif
8537   endif
8538"   call Dret("NetrwMenu")
8539   return
8540  endif
8541
8542endfun
8543
8544" ---------------------------------------------------------------------
8545" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8546"                Used by the O maps (as <SID>NetrwObtain())
8547fun! s:NetrwObtain(islocal)
8548"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8549
8550  let ykeep= @@
8551  if exists("s:netrwmarkfilelist_{bufnr('%')}")
8552   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8553   call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8554   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
8555  else
8556   call netrw#Obtain(a:islocal,s:NetrwGetWord())
8557  endif
8558  let @@= ykeep
8559
8560"  call Dret("NetrwObtain")
8561endfun
8562
8563" ---------------------------------------------------------------------
8564" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
8565"   If there's only one window, then the window will first be split.
8566"   Returns:
8567"     choice = 0 : didn't have to choose
8568"     choice = 1 : saved modified file in window first
8569"     choice = 2 : didn't save modified file, opened window
8570"     choice = 3 : cancel open
8571fun! s:NetrwPrevWinOpen(islocal)
8572"  call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")")
8573
8574  let ykeep= @@
8575  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8576  let curdir = b:netrw_curdir
8577
8578  " get last window number and the word currently under the cursor
8579  let origwin   = winnr()
8580  let lastwinnr = winnr("$")
8581  let curword   = s:NetrwGetWord()
8582  let choice    = 0
8583  let s:prevwinopen= 1	" lets s:NetrwTreeDir() know that NetrwPrevWinOpen called it
8584  let s:treedir = s:NetrwTreeDir(a:islocal)
8585  let curdir    = s:treedir
8586"  call Decho("winnr($)#".lastwinnr." curword<".curword.">",'~'.expand("<slnum>"))
8587
8588  let didsplit = 0
8589  if lastwinnr == 1
8590   " if only one window, open a new one first
8591"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("<slnum>"))
8592   " g:netrw_preview=0: preview window shown in a horizontally split window
8593   " g:netrw_preview=1: preview window shown in a vertically   split window
8594   if g:netrw_preview
8595    " vertically split preview window
8596    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8597"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("<slnum>"))
8598    exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8599   else
8600    " horizontally split preview window
8601    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8602"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8603    exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8604   endif
8605   let didsplit = 1
8606"   call Decho("did split",'~'.expand("<slnum>"))
8607
8608  else
8609   NetrwKeepj call s:SaveBufVars()
8610   let eikeep= &ei
8611   setl ei=all
8612   wincmd p
8613"   call Decho("wincmd p  (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
8614
8615   " prevwinnr: the window number of the "prev" window
8616   " prevbufnr: the buffer number of the buffer in the "prev" window
8617   " bnrcnt   : the qty of windows open on the "prev" buffer
8618   let prevwinnr   = winnr()
8619   let prevbufnr   = bufnr("%")
8620   let prevbufname = bufname("%")
8621   let prevmod     = &mod
8622   let bnrcnt      = 0
8623   NetrwKeepj call s:RestoreBufVars()
8624"   call Decho("after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr,'~'.expand("<slnum>"))
8625
8626   " if the previous window's buffer has been changed (ie. its modified flag is set),
8627   " and it doesn't appear in any other extant window, then ask the
8628   " user if s/he wants to abandon modifications therein.
8629   if prevmod
8630"    call Decho("detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr(),'~'.expand("<slnum>"))
8631    windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8632"    call Decho("prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr,'~'.expand("<slnum>"))
8633    exe prevwinnr."wincmd w"
8634
8635    if bnrcnt == 1 && &hidden == 0
8636     " only one copy of the modified buffer in a window, and
8637     " hidden not set, so overwriting will lose the modified file.  Ask first...
8638     let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8639"     call Decho("prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("<slnum>"))
8640     let &ei= eikeep
8641
8642     if choice == 1
8643      " Yes -- write file & then browse
8644      let v:errmsg= ""
8645      sil w
8646      if v:errmsg != ""
8647       call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8648       exe origwin."wincmd w"
8649       let &ei = eikeep
8650       let @@  = ykeep
8651"       call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">")
8652       return choice
8653      endif
8654
8655     elseif choice == 2
8656      " No -- don't worry about changed file, just browse anyway
8657"      call Decho("don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")",'~'.expand("<slnum>"))
8658      echomsg "**note** changes to ".prevbufname." abandoned"
8659
8660     else
8661      " Cancel -- don't do this
8662"      call Decho("cancel, don't browse, switch to win#".origwin,'~'.expand("<slnum>"))
8663      exe origwin."wincmd w"
8664      let &ei= eikeep
8665      let @@ = ykeep
8666"      call Dret("s:NetrwPrevWinOpen ".choice." : cancelled")
8667      return choice
8668     endif
8669    endif
8670   endif
8671   let &ei= eikeep
8672  endif
8673
8674  " restore b:netrw_curdir (window split/enew may have lost it)
8675  let b:netrw_curdir= curdir
8676  if a:islocal < 2
8677   if a:islocal
8678    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
8679   else
8680    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
8681   endif
8682  endif
8683  let @@= ykeep
8684"  call Dret("s:NetrwPrevWinOpen ".choice)
8685  return choice
8686endfun
8687
8688" ---------------------------------------------------------------------
8689" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8690"                Always assumed to be local -> remote
8691"                call s:NetrwUpload(filename, target)
8692"                call s:NetrwUpload(filename, target, fromdirectory)
8693fun! s:NetrwUpload(fname,tgt,...)
8694"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
8695
8696  if a:tgt =~ '^\a\{3,}://'
8697   let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
8698  else
8699   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
8700  endif
8701"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
8702
8703  if a:0 > 0
8704   let fromdir= a:1
8705  else
8706   let fromdir= getcwd()
8707  endif
8708"  call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
8709
8710  if type(a:fname) == 1
8711   " handle uploading a single file using NetWrite
8712"   call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8713   1split
8714"   call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8715   exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8716"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8717   if a:tgt =~ '/$'
8718    let wfname= substitute(a:fname,'^.*/','','')
8719"    call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8720    exe "w! ".fnameescape(a:tgt.wfname)
8721   else
8722"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8723    exe "w ".fnameescape(a:tgt)
8724"    call Decho("done writing local->remote",'~'.expand("<slnum>"))
8725   endif
8726   q!
8727
8728  elseif type(a:fname) == 3
8729   " handle uploading a list of files via scp
8730"   call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8731   let curdir= getcwd()
8732   if a:tgt =~ '^scp:'
8733    if s:NetrwLcd(fromdir)
8734"     call Dret("s:NetrwUpload : lcd failure")
8735     return
8736    endif
8737    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8738    let args    = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8739    if exists("g:netrw_port") && g:netrw_port != ""
8740     let useport= " ".g:netrw_scpport." ".g:netrw_port
8741    else
8742     let useport= ""
8743    endif
8744    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8745    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8746    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8747    if s:NetrwLcd(curdir)
8748"     call Dret("s:NetrwUpload : lcd failure")
8749     return
8750    endif
8751
8752   elseif a:tgt =~ '^ftp:'
8753    call s:NetrwMethod(a:tgt)
8754
8755    if b:netrw_method == 2
8756     " handle uploading a list of files via ftp+.netrc
8757     let netrw_fname = b:netrw_fname
8758     sil NetrwKeepj new
8759"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8760
8761     NetrwKeepj put =g:netrw_ftpmode
8762"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8763
8764     if exists("g:netrw_ftpextracmd")
8765      NetrwKeepj put =g:netrw_ftpextracmd
8766"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8767     endif
8768
8769     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8770"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8771
8772     if tgtdir == ""
8773      let tgtdir= '/'
8774     endif
8775     NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8776"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8777
8778     for fname in a:fname
8779      NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8780"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8781     endfor
8782
8783     if exists("g:netrw_port") && g:netrw_port != ""
8784      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8785     else
8786"      call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8787      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8788     endif
8789     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8790     sil NetrwKeepj g/Local directory now/d
8791     call histdel("/",-1)
8792     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8793      call netrw#ErrorMsg(s:ERROR,getline(1),14)
8794     else
8795      bw!|q
8796     endif
8797
8798    elseif b:netrw_method == 3
8799     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8800     let netrw_fname= b:netrw_fname
8801     NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8802     let tmpbufnr= bufnr("%")
8803     setl ff=unix
8804
8805     if exists("g:netrw_port") && g:netrw_port != ""
8806      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8807"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8808     else
8809      NetrwKeepj put ='open '.g:netrw_machine
8810"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8811     endif
8812
8813     if exists("g:netrw_uid") && g:netrw_uid != ""
8814      if exists("g:netrw_ftp") && g:netrw_ftp == 1
8815       NetrwKeepj put =g:netrw_uid
8816"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8817       if exists("s:netrw_passwd")
8818        NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8819       endif
8820"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8821      elseif exists("s:netrw_passwd")
8822       NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8823"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8824      endif
8825     endif
8826
8827     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8828"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8829
8830     if exists("b:netrw_fname") && b:netrw_fname != ""
8831      NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8832"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8833     endif
8834
8835     if exists("g:netrw_ftpextracmd")
8836      NetrwKeepj put =g:netrw_ftpextracmd
8837"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8838     endif
8839
8840     for fname in a:fname
8841      NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8842"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8843     endfor
8844
8845     " perform ftp:
8846     " -i       : turns off interactive prompting from ftp
8847     " -n  unix : DON'T use <.netrc>, even though it exists
8848     " -n  win32: quit being obnoxious about password
8849     NetrwKeepj norm! 1G"_dd
8850     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8851     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8852     sil NetrwKeepj g/Local directory now/d
8853     call histdel("/",-1)
8854     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8855      let debugkeep= &debug
8856      setl debug=msg
8857      call netrw#ErrorMsg(s:ERROR,getline(1),15)
8858      let &debug = debugkeep
8859      let mod    = 1
8860     else
8861      bw!|q
8862     endif
8863    elseif !exists("b:netrw_method") || b:netrw_method < 0
8864"     call Dret("s:#NetrwUpload : unsupported method")
8865     return
8866    endif
8867   else
8868    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
8869   endif
8870  endif
8871
8872"  call Dret("s:NetrwUpload")
8873endfun
8874
8875" ---------------------------------------------------------------------
8876" s:NetrwPreview: supports netrw's "p" map {{{2
8877fun! s:NetrwPreview(path) range
8878"  call Dfunc("NetrwPreview(path<".a:path.">)")
8879"  call Decho("g:netrw_alto   =".(exists("g:netrw_alto")?    g:netrw_alto    : 'n/a'),'~'.expand("<slnum>"))
8880"  call Decho("g:netrw_preview=".(exists("g:netrw_preview")? g:netrw_preview : 'n/a'),'~'.expand("<slnum>"))
8881  let ykeep= @@
8882  NetrwKeepj call s:NetrwOptionsSave("s:")
8883  if a:path !~ '^\*\{1,2}/' && a:path !~ '^\a\{3,}://'
8884   NetrwKeepj call s:NetrwOptionsSafe(1)
8885  else
8886   NetrwKeepj call s:NetrwOptionsSafe(0)
8887  endif
8888  if has("quickfix")
8889"   call Decho("has quickfix",'~'.expand("<slnum>"))
8890   if !isdirectory(s:NetrwFile(a:path))
8891"    call Decho("good; not previewing a directory",'~'.expand("<slnum>"))
8892    if g:netrw_preview
8893     " vertical split
8894     let pvhkeep = &pvh
8895     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8896     let &pvh    = winwidth(0) - winsz
8897"     call Decho("g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily)  g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8898    else
8899     " horizontal split
8900     let pvhkeep = &pvh
8901     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8902     let &pvh    = winheight(0) - winsz
8903"     call Decho("!g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily)  g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8904    endif
8905    " g:netrw_preview   g:netrw_alto
8906    "    1 : vert        1: top       -- preview window is vertically   split off and on the left
8907    "    1 : vert        0: bot       -- preview window is vertically   split off and on the right
8908    "    0 :             1: top       -- preview window is horizontally split off and on the top
8909    "    0 :             0: bot       -- preview window is horizontally split off and on the bottom
8910    "
8911    " Note that the file being previewed is already known to not be a directory, hence we can avoid doing a LocalBrowseCheck() check via
8912    " the BufEnter event set up in netrwPlugin.vim
8913"    call Decho("exe ".(g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path),'~'.expand("<slnum>"))
8914    let eikeep = &ei
8915    set ei=BufEnter
8916    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8917    let &ei= eikeep
8918"    call Decho("winnr($)=".winnr("$"),'~'.expand("<slnum>"))
8919    if exists("pvhkeep")
8920     let &pvh= pvhkeep
8921    endif
8922   elseif !exists("g:netrw_quiet")
8923    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
8924   endif
8925  elseif !exists("g:netrw_quiet")
8926   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
8927  endif
8928  NetrwKeepj call s:NetrwOptionsRestore("s:")
8929  let @@= ykeep
8930"  call Dret("NetrwPreview")
8931endfun
8932
8933" ---------------------------------------------------------------------
8934" s:NetrwRefresh: {{{2
8935fun! s:NetrwRefresh(islocal,dirname)
8936"  call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") g:netrw_hide=".g:netrw_hide." g:netrw_sort_direction=".g:netrw_sort_direction)
8937  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
8938  setl ma noro
8939"  call Decho("setl ma noro",'~'.expand("<slnum>"))
8940"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8941  let ykeep      = @@
8942  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8943   if !exists("w:netrw_treetop")
8944    if exists("b:netrw_curdir")
8945     let w:netrw_treetop= b:netrw_curdir
8946    else
8947     let w:netrw_treetop= getcwd()
8948    endif
8949   endif
8950   NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
8951  endif
8952
8953  " save the cursor position before refresh.
8954  let screenposn = winsaveview()
8955"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8956
8957"  call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8958"  call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
8959  sil! NetrwKeepj %d _
8960  if a:islocal
8961   NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
8962  else
8963   NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
8964  endif
8965
8966  " restore position
8967"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8968  NetrwKeepj call winrestview(screenposn)
8969
8970  " restore file marks
8971  if has("syntax") && exists("g:syntax_on") && g:syntax_on
8972   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8973" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8974    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8975   else
8976" "   call Decho("2match none  (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8977    2match none
8978   endif
8979 endif
8980
8981"  restore
8982  let @@= ykeep
8983"  call Dret("s:NetrwRefresh")
8984endfun
8985
8986" ---------------------------------------------------------------------
8987" s:NetrwRefreshDir: refreshes a directory by name {{{2
8988"                    Called by NetrwMarkFileCopy()
8989"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
8990fun! s:NetrwRefreshDir(islocal,dirname)
8991"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) g:netrw_fastbrowse=".g:netrw_fastbrowse)
8992  if g:netrw_fastbrowse == 0
8993   " slowest mode (keep buffers refreshed, local or remote)
8994"   call Decho("slowest mode: keep buffers refreshed, local or remote",'~'.expand("<slnum>"))
8995   let tgtwin= bufwinnr(a:dirname)
8996"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin,'~'.expand("<slnum>"))
8997
8998   if tgtwin > 0
8999    " tgtwin is being displayed, so refresh it
9000    let curwin= winnr()
9001"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")",'~'.expand("<slnum>"))
9002    exe tgtwin."wincmd w"
9003    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
9004    exe curwin."wincmd w"
9005
9006   elseif bufnr(a:dirname) > 0
9007    let bn= bufnr(a:dirname)
9008"    call Decho("bd bufnr(".a:dirname.")=".bn,'~'.expand("<slnum>"))
9009    exe "sil keepj bd ".bn
9010   endif
9011
9012  elseif g:netrw_fastbrowse <= 1
9013"   call Decho("medium-speed mode: refresh local buffers only",'~'.expand("<slnum>"))
9014   NetrwKeepj call s:LocalBrowseRefresh()
9015  endif
9016"  call Dret("s:NetrwRefreshDir")
9017endfun
9018
9019" ---------------------------------------------------------------------
9020" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
9021" window number to do its editing in.
9022" Supports   [count]C  where the count, if present, is used to specify
9023" a window to use for editing via the <cr> mapping.
9024fun! s:NetrwSetChgwin(...)
9025"  call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
9026  if a:0 > 0
9027"   call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
9028   if a:1 == ""    " :NetrwC win#
9029    let g:netrw_chgwin= winnr()
9030   else              " :NetrwC
9031    let g:netrw_chgwin= a:1
9032   endif
9033  elseif v:count > 0 " [count]C
9034   let g:netrw_chgwin= v:count
9035  else               " C
9036   let g:netrw_chgwin= winnr()
9037  endif
9038  echo "editing window now set to window#".g:netrw_chgwin
9039"  call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
9040endfun
9041
9042" ---------------------------------------------------------------------
9043" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
9044"          What this function does is to compute a priority for the patterns
9045"          in the g:netrw_sort_sequence.  It applies a substitute to any
9046"          "files" that satisfy each pattern, putting the priority / in
9047"          front.  An "*" pattern handles the default priority.
9048fun! s:NetrwSetSort()
9049"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
9050  let ykeep= @@
9051  if w:netrw_liststyle == s:LONGLIST
9052   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
9053  else
9054   let seqlist  = g:netrw_sort_sequence
9055  endif
9056  " sanity check -- insure that * appears somewhere
9057  if seqlist == ""
9058   let seqlist= '*'
9059  elseif seqlist !~ '\*'
9060   let seqlist= seqlist.',*'
9061  endif
9062  let priority = 1
9063  while seqlist != ""
9064   if seqlist =~ ','
9065    let seq     = substitute(seqlist,',.*$','','e')
9066    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
9067   else
9068    let seq     = seqlist
9069    let seqlist = ""
9070   endif
9071   if priority < 10
9072    let spriority= "00".priority.g:netrw_sepchr
9073   elseif priority < 100
9074    let spriority= "0".priority.g:netrw_sepchr
9075   else
9076    let spriority= priority.g:netrw_sepchr
9077   endif
9078"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
9079
9080   " sanity check
9081   if w:netrw_bannercnt > line("$")
9082    " apparently no files were left after a Hiding pattern was used
9083"    call Dret("SetSort : no files left after hiding")
9084    return
9085   endif
9086   if seq == '*'
9087    let starpriority= spriority
9088   else
9089    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
9090    call histdel("/",-1)
9091    " sometimes multiple sorting patterns will match the same file or directory.
9092    " The following substitute is intended to remove the excess matches.
9093    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
9094    NetrwKeepj call histdel("/",-1)
9095   endif
9096   let priority = priority + 1
9097  endwhile
9098  if exists("starpriority")
9099   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
9100   NetrwKeepj call histdel("/",-1)
9101  endif
9102
9103  " Following line associated with priority -- items that satisfy a priority
9104  " pattern get prefixed by ###/ which permits easy sorting by priority.
9105  " Sometimes files can satisfy multiple priority patterns -- only the latest
9106  " priority pattern needs to be retained.  So, at this point, these excess
9107  " priority prefixes need to be removed, but not directories that happen to
9108  " be just digits themselves.
9109  exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
9110  NetrwKeepj call histdel("/",-1)
9111  let @@= ykeep
9112
9113"  call Dret("SetSort")
9114endfun
9115
9116" ---------------------------------------------------------------------
9117" s:NetrwSetTgt: sets the target to the specified choice index {{{2
9118"    Implements [count]Tb  (bookhist<b>)
9119"               [count]Th  (bookhist<h>)
9120"               See :help netrw-qb for how to make the choice.
9121fun! s:NetrwSetTgt(islocal,bookhist,choice)
9122"  call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
9123
9124  if     a:bookhist == 'b'
9125   " supports choosing a bookmark as a target using a qb-generated list
9126   let choice= a:choice - 1
9127   if exists("g:netrw_bookmarklist[".choice."]")
9128    call netrw#MakeTgt(g:netrw_bookmarklist[choice])
9129   else
9130    echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
9131   endif
9132
9133  elseif a:bookhist == 'h'
9134   " supports choosing a history stack entry as a target using a qb-generated list
9135   let choice= (a:choice % g:netrw_dirhistmax) + 1
9136   if exists("g:netrw_dirhist_".choice)
9137    let histentry = g:netrw_dirhist_{choice}
9138    call netrw#MakeTgt(histentry)
9139   else
9140    echomsg "Sorry, history#".a:choice." not available!"
9141   endif
9142  endif
9143
9144  " refresh the display
9145  if !exists("b:netrw_curdir")
9146   let b:netrw_curdir= getcwd()
9147  endif
9148  call s:NetrwRefresh(a:islocal,b:netrw_curdir)
9149
9150"  call Dret("s:NetrwSetTgt")
9151endfun
9152
9153" =====================================================================
9154" s:NetrwSortStyle: change sorting style (name - time - size - exten) and refresh display {{{2
9155fun! s:NetrwSortStyle(islocal)
9156"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
9157  NetrwKeepj call s:NetrwSaveWordPosn()
9158  let svpos= winsaveview()
9159"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9160
9161  let g:netrw_sort_by= (g:netrw_sort_by =~# '^n')? 'time' : (g:netrw_sort_by =~# '^t')? 'size' : (g:netrw_sort_by =~# '^siz')? 'exten' : 'name'
9162  NetrwKeepj norm! 0
9163  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
9164"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9165  NetrwKeepj call winrestview(svpos)
9166
9167"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
9168endfun
9169
9170" ---------------------------------------------------------------------
9171" s:NetrwSplit: mode {{{2
9172"           =0 : net   and o
9173"           =1 : net   and t
9174"           =2 : net   and v
9175"           =3 : local and o
9176"           =4 : local and t
9177"           =5 : local and v
9178fun! s:NetrwSplit(mode)
9179"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
9180
9181  let ykeep= @@
9182  call s:SaveWinVars()
9183
9184  if a:mode == 0
9185   " remote and o
9186   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
9187   if winsz == 0|let winsz= ""|endif
9188"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
9189   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
9190   let s:didsplit= 1
9191   NetrwKeepj call s:RestoreWinVars()
9192   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
9193   unlet s:didsplit
9194
9195  elseif a:mode == 1
9196   " remote and t
9197   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
9198"   call Decho("tabnew",'~'.expand("<slnum>"))
9199   tabnew
9200   let s:didsplit= 1
9201   NetrwKeepj call s:RestoreWinVars()
9202   NetrwKeepj call s:NetrwBrowse(0,newdir)
9203   unlet s:didsplit
9204
9205  elseif a:mode == 2
9206   " remote and v
9207   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
9208   if winsz == 0|let winsz= ""|endif
9209"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
9210   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
9211   let s:didsplit= 1
9212   NetrwKeepj call s:RestoreWinVars()
9213   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
9214   unlet s:didsplit
9215
9216  elseif a:mode == 3
9217   " local and o
9218   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
9219   if winsz == 0|let winsz= ""|endif
9220"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
9221   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
9222   let s:didsplit= 1
9223   NetrwKeepj call s:RestoreWinVars()
9224   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
9225   unlet s:didsplit
9226
9227  elseif a:mode == 4
9228   " local and t
9229   let cursorword  = s:NetrwGetWord()
9230   let eikeep      = &ei
9231   let netrw_winnr = winnr()
9232   let netrw_line  = line(".")
9233   let netrw_col   = virtcol(".")
9234   NetrwKeepj norm! H0
9235   let netrw_hline = line(".")
9236   setl ei=all
9237   exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
9238   exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
9239   let &ei          = eikeep
9240   let netrw_curdir = s:NetrwTreeDir(0)
9241"   call Decho("tabnew",'~'.expand("<slnum>"))
9242   tabnew
9243   let b:netrw_curdir = netrw_curdir
9244   let s:didsplit     = 1
9245   NetrwKeepj call s:RestoreWinVars()
9246   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
9247   if &ft == "netrw"
9248    setl ei=all
9249    exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
9250    exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
9251    let &ei= eikeep
9252   endif
9253   unlet s:didsplit
9254
9255  elseif a:mode == 5
9256   " local and v
9257   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
9258   if winsz == 0|let winsz= ""|endif
9259"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
9260   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
9261   let s:didsplit= 1
9262   NetrwKeepj call s:RestoreWinVars()
9263   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
9264   unlet s:didsplit
9265
9266  else
9267   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
9268  endif
9269
9270  let @@= ykeep
9271"  call Dret("s:NetrwSplit")
9272endfun
9273
9274" ---------------------------------------------------------------------
9275" s:NetrwTgtMenu: {{{2
9276fun! s:NetrwTgtMenu()
9277  if !exists("s:netrw_menucnt")
9278   return
9279  endif
9280"  call Dfunc("s:NetrwTgtMenu()")
9281
9282  " the following test assures that gvim is running, has menus available, and has menus enabled.
9283  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
9284   if exists("g:NetrwTopLvlMenu")
9285"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
9286    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
9287   endif
9288   if !exists("s:netrw_initbookhist")
9289    call s:NetrwBookHistRead()
9290   endif
9291
9292   " try to cull duplicate entries
9293   let tgtdict={}
9294
9295   " target bookmarked places
9296   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
9297"    call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
9298    let cnt= 1
9299    for bmd in g:netrw_bookmarklist
9300     if has_key(tgtdict,bmd)
9301      let cnt= cnt + 1
9302      continue
9303     endif
9304     let tgtdict[bmd]= cnt
9305     let ebmd= escape(bmd,g:netrw_menu_escape)
9306     " show bookmarks for goto menu
9307"     call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
9308     exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd."	:call netrw#MakeTgt('".bmd."')\<cr>"
9309     let cnt= cnt + 1
9310    endfor
9311   endif
9312
9313   " target directory browsing history
9314   if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
9315"    call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
9316    let histcnt = 1
9317    while histcnt <= g:netrw_dirhistmax
9318     let priority = g:netrw_dirhistcnt + histcnt
9319     if exists("g:netrw_dirhist_{histcnt}")
9320      let histentry  = g:netrw_dirhist_{histcnt}
9321      if has_key(tgtdict,histentry)
9322       let histcnt = histcnt + 1
9323       continue
9324      endif
9325      let tgtdict[histentry] = histcnt
9326      let ehistentry         = escape(histentry,g:netrw_menu_escape)
9327"      call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
9328      exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry."	:call netrw#MakeTgt('".histentry."')\<cr>"
9329     endif
9330     let histcnt = histcnt + 1
9331    endwhile
9332   endif
9333  endif
9334"  call Dret("s:NetrwTgtMenu")
9335endfun
9336
9337" ---------------------------------------------------------------------
9338" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
9339" (full path directory with trailing slash returned)
9340fun! s:NetrwTreeDir(islocal)
9341"  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)
9342"  call Decho("Determine tree directory given current cursor position")
9343"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
9344"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9345"  call Decho("w:netrw_treetop  =".(exists("w:netrw_treetop")?   w:netrw_treetop   : 'n/a'),'~'.expand("<slnum>"))
9346"  call Decho("current line<".getline(".").">")
9347
9348  if exists("s:treedir") && exists("s:prevwinopen")
9349   " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
9350"   call Decho('s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early')
9351   let treedir= s:treedir
9352   unlet s:treedir
9353   unlet s:prevwinopen
9354"   call Dret("s:NetrwTreeDir ".treedir.": early return since s:treedir existed previously")
9355   return treedir
9356  endif
9357  if exists("s:prevwinopen")
9358   unlet s:prevwinopen
9359  endif
9360
9361  if !exists("b:netrw_curdir") || b:netrw_curdir == ""
9362   let b:netrw_curdir= getcwd()
9363  endif
9364  let treedir = b:netrw_curdir
9365"  call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>"))
9366
9367  let s:treecurpos= winsaveview()
9368"  call Decho("saving posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9369
9370  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9371"   call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>"))
9372"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9373
9374   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
9375   let curline= substitute(getline('.'),"\t -->.*$",'','')
9376   if curline =~ '/$'
9377"    call Decho("extract tree subdirectory from current line",'~'.expand("<slnum>"))
9378    let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9379"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9380   elseif curline =~ '@$'
9381"    call Decho("handle symbolic link from current line",'~'.expand("<slnum>"))
9382    let treedir= resolve(substitute(substitute(getline('.'),'@.*$','','e'),'^|*\s*','','e'))
9383"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9384   else
9385"    call Decho("do not extract tree subdirectory from current line and set treedir to empty",'~'.expand("<slnum>"))
9386    let treedir= ""
9387   endif
9388
9389   " detect user attempting to close treeroot
9390"   call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>"))
9391"   call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9392"   call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~# '^'.s:treedepthstring)? '=~#' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>"))
9393   if curline !~ '^'.s:treedepthstring && getline('.') != '..'
9394"    call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>"))
9395    " now force a refresh
9396"    call Decho(".force refresh: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9397    sil! NetrwKeepj %d _
9398"    call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9399    return b:netrw_curdir
9400"   else " Decho
9401"    call Decho(".user not attempting to close treeroot",'~'.expand("<slnum>"))
9402   endif
9403
9404"   call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>"))
9405   let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
9406"   call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(potentialdir),'~'.expand("<slnum>"))
9407
9408   " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
9409"   if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
9410"    let newdir          = w:netrw_treetop.'/'.potentialdir
9411" "   call Decho("apply NetrwTreePath to newdir<".newdir.">",'~'.expand("<slnum>"))
9412"    let treedir         = s:NetrwTreePath(newdir)
9413"    let w:netrw_treetop = newdir
9414" "   call Decho("newdir <".newdir.">",'~'.expand("<slnum>"))
9415"   else
9416"    call Decho("apply NetrwTreePath to treetop<".w:netrw_treetop.">",'~'.expand("<slnum>"))
9417    let treedir = s:NetrwTreePath(w:netrw_treetop)
9418"   endif
9419  endif
9420
9421  " sanity maintenance: keep those //s away...
9422  let treedir= substitute(treedir,'//$','/','')
9423"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9424
9425"  call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9426  return treedir
9427endfun
9428
9429" ---------------------------------------------------------------------
9430" s:NetrwTreeDisplay: recursive tree display {{{2
9431fun! s:NetrwTreeDisplay(dir,depth)
9432"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
9433
9434  " insure that there are no folds
9435  setl nofen
9436
9437  " install ../ and shortdir
9438  if a:depth == ""
9439   call setline(line("$")+1,'../')
9440"   call Decho("setline#".line("$")." ../ (depth is zero)",'~'.expand("<slnum>"))
9441  endif
9442  if a:dir =~ '^\a\{3,}://'
9443   if a:dir == w:netrw_treetop
9444    let shortdir= a:dir
9445   else
9446    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
9447   endif
9448   call setline(line("$")+1,a:depth.shortdir)
9449  else
9450   let shortdir= substitute(a:dir,'^.*/','','e')
9451   call setline(line("$")+1,a:depth.shortdir.'/')
9452  endif
9453"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">",'~'.expand("<slnum>"))
9454  " append a / to dir if its missing one
9455  let dir= a:dir
9456
9457  " display subtrees (if any)
9458  let depth= s:treedepthstring.a:depth
9459"  call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>"))
9460
9461  " implement g:netrw_hide for tree listings (uses g:netrw_list_hide)
9462  if     g:netrw_hide == 1
9463   " hide given patterns
9464   let listhide= split(g:netrw_list_hide,',')
9465"   call Decho("listhide=".string(listhide))
9466   for pat in listhide
9467    call filter(w:netrw_treedict[dir],'v:val !~ "'.escape(pat,'\\').'"')
9468   endfor
9469
9470  elseif g:netrw_hide == 2
9471   " show given patterns (only)
9472   let listhide= split(g:netrw_list_hide,',')
9473"   call Decho("listhide=".string(listhide))
9474   let entries=[]
9475   for entry in w:netrw_treedict[dir]
9476    for pat in listhide
9477     if entry =~ pat
9478      call add(entries,entry)
9479      break
9480     endif
9481    endfor
9482   endfor
9483   let w:netrw_treedict[dir]= entries
9484  endif
9485  if depth != ""
9486   " always remove "." and ".." entries when there's depth
9487   call filter(w:netrw_treedict[dir],'v:val !~ "\\.\\.$"')
9488   call filter(w:netrw_treedict[dir],'v:val !~ "\\.$"')
9489  endif
9490
9491"  call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>"))
9492  for entry in w:netrw_treedict[dir]
9493   if dir =~ '/$'
9494    let direntry= substitute(dir.entry,'[@/]$','','e')
9495   else
9496    let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
9497   endif
9498"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9499   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9500"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9501    NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
9502   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9503"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9504    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9505   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9506"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9507    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9508   else
9509"    call Decho("<".entry."> is not a key in treedict (no subtree)",'~'.expand("<slnum>"))
9510    sil! NetrwKeepj call setline(line("$")+1,depth.entry)
9511   endif
9512  endfor
9513"  call Decho("displaying: ".string(getline(w:netrw_bannercnt,'$')))
9514
9515"  call Dret("NetrwTreeDisplay")
9516endfun
9517
9518" ---------------------------------------------------------------------
9519" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
9520fun! s:NetrwRefreshTreeDict(dir)
9521"  call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)")
9522  if !exists("w:netrw_treedict")
9523"   call Dret("s:NetrwRefreshTreeDict : w:netrw_treedict doesn't exist")
9524   return
9525  endif
9526
9527  for entry in w:netrw_treedict[a:dir]
9528   let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
9529"   call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9530
9531   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9532"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9533    NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
9534    let liststar                   = s:NetrwGlob(direntry,'*',1)
9535    let listdotstar                = s:NetrwGlob(direntry,'.*',1)
9536    let w:netrw_treedict[direntry] = liststar + listdotstar
9537"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9538
9539   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9540"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9541    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9542    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9543    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9544    let w:netrw_treedict[direntry]= liststar + listdotstar
9545"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9546
9547   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9548"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9549    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9550    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9551    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9552"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9553
9554   else
9555"    call Decho('not updating w:netrw_treedict['.string(direntry).'] with entry<'.string(entry).'> (no subtree)','~'.expand("<slnum>"))
9556   endif
9557  endfor
9558"  call Dret("s:NetrwRefreshTreeDict")
9559endfun
9560
9561" ---------------------------------------------------------------------
9562" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
9563"                     Called by s:PerformListing()
9564fun! s:NetrwTreeListing(dirname)
9565  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9566"   call Dfunc("s:NetrwTreeListing() bufname<".expand("%").">")
9567"   call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
9568"   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>"))
9569"   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>"))
9570
9571   " update the treetop
9572   if !exists("w:netrw_treetop")
9573"    call Decho("update the treetop  (w:netrw_treetop doesn't exist yet)",'~'.expand("<slnum>"))
9574    let w:netrw_treetop= a:dirname
9575    let s:netrw_treetop= w:netrw_treetop
9576"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>"))
9577   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
9578"    call Decho("update the treetop  (override w:netrw_treetop with a:dirname<".a:dirname.">)",'~'.expand("<slnum>"))
9579    let w:netrw_treetop= a:dirname
9580    let s:netrw_treetop= w:netrw_treetop
9581"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
9582   endif
9583   if exists("w:netrw_treetop")
9584    let s:netrw_treetop= w:netrw_treetop
9585   else
9586    let w:netrw_treetop= getcwd()
9587    let s:netrw_treetop= w:netrw_treetop
9588   endif
9589
9590   if !exists("w:netrw_treedict")
9591    " insure that we have a treedict, albeit empty
9592"    call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
9593    let w:netrw_treedict= {}
9594   endif
9595
9596   " update the dictionary for the current directory
9597"   call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>"))
9598"   call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9599   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
9600   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
9601"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
9602   exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9603
9604   " if past banner, record word
9605   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
9606    let fname= expand("<cword>")
9607   else
9608    let fname= ""
9609   endif
9610"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9611"   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>"))
9612
9613   " display from treetop on down
9614"   call Decho("(s:NetrwTreeListing) w:netrw_treetop<".w:netrw_treetop.">")
9615   NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
9616"   call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
9617
9618   " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
9619   while getline(1) =~ '^\s*$' && byte2line(1) > 0
9620"    call Decho("deleting blank line",'~'.expand("<slnum>"))
9621    1d
9622   endwhile
9623
9624   exe "setl ".g:netrw_bufsettings
9625
9626"   call Dret("s:NetrwTreeListing : bufname<".expand("%").">")
9627   return
9628  endif
9629endfun
9630
9631" ---------------------------------------------------------------------
9632" s:NetrwTreePath: returns path to current file/directory in tree listing {{{2
9633"                  Normally, treetop is w:netrw_treetop, but a
9634"                  user of the function ( netrw#SetTreetop() )
9635"                  wipes that out prior to calling this function
9636fun! s:NetrwTreePath(treetop)
9637"  call Dfunc("s:NetrwTreePath(treetop<".a:treetop.">) line#".line(".")."<".getline(".").">")
9638  if line(".") < w:netrw_bannercnt + 2
9639   let treedir= a:treetop
9640   if treedir !~ '/$'
9641    let treedir= treedir.'/'
9642   endif
9643"   call Dret("s:NetrwTreePath ".treedir." : line#".line(".")." ≤ ".(w:netrw_bannercnt+2))
9644   return treedir
9645  endif
9646
9647  let svpos = winsaveview()
9648"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9649  let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
9650"  call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
9651  let depth = substitute(depth,'^'.s:treedepthstring,'','')
9652"  call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
9653  let curline= getline('.')
9654"  call Decho("curline<".curline.'>','~'.expand("<slnum>"))
9655  if curline =~ '/$'
9656"   call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9657   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9658"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9659  elseif curline =~ '@\s\+-->'
9660"   call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9661   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9662   let treedir= substitute(treedir,'@\s\+-->.*$','','e')
9663"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9664  else
9665"   call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9666   let treedir= ""
9667  endif
9668  " construct treedir by searching backwards at correct depth
9669"  call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9670"  call Decho("initial      treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
9671  while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
9672   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9673   let treedir= dirname.treedir
9674   let depth  = substitute(depth,'^'.s:treedepthstring,'','')
9675"   call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
9676  endwhile
9677"  call Decho("treedir#1<".treedir.">",'~'.expand("<slnum>"))
9678  if a:treetop =~ '/$'
9679   let treedir= a:treetop.treedir
9680  else
9681   let treedir= a:treetop.'/'.treedir
9682  endif
9683"  call Decho("treedir#2<".treedir.">",'~'.expand("<slnum>"))
9684  let treedir= substitute(treedir,'//$','/','')
9685"  call Decho("treedir#3<".treedir.">",'~'.expand("<slnum>"))
9686"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
9687  call winrestview(svpos)
9688"  call Dret("s:NetrwTreePath <".treedir.">")
9689  return treedir
9690endfun
9691
9692" ---------------------------------------------------------------------
9693" s:NetrwWideListing: {{{2
9694fun! s:NetrwWideListing()
9695
9696  if w:netrw_liststyle == s:WIDELIST
9697"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9698   " look for longest filename (cpf=characters per filename)
9699   " cpf: characters per filename
9700   " fpl: filenames per line
9701   " fpc: filenames per column
9702   setl ma noro
9703   let keepa= @a
9704"   call Decho("setl ma noro",'~'.expand("<slnum>"))
9705   let b:netrw_cpf= 0
9706   if line("$") >= w:netrw_bannercnt
9707    " determine the maximum filename size; use that to set cpf
9708    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
9709    NetrwKeepj call histdel("/",-1)
9710   else
9711    let @a= keepa
9712"    call Dret("NetrwWideListing")
9713    return
9714   endif
9715   " allow for two spaces to separate columns
9716   let b:netrw_cpf= b:netrw_cpf + 2
9717"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
9718
9719   " determine qty files per line (fpl)
9720   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9721   if w:netrw_fpl <= 0
9722    let w:netrw_fpl= 1
9723   endif
9724"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
9725
9726   " make wide display
9727   "   fpc: files per column of wide listing
9728   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9729   NetrwKeepj call histdel("/",-1)
9730   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9731   let newcolstart = w:netrw_bannercnt + fpc
9732   let newcolend   = newcolstart + fpc - 1
9733"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9734   if has("clipboard") && g:netrw_clipboard
9735"    call Decho("(s:NetrwWideListing) save @* and @+",'~'.expand("<slnum>"))
9736    sil! let keepregstar = @*
9737    sil! let keepregplus = @+
9738   endif
9739   while line("$") >= newcolstart
9740    if newcolend > line("$") | let newcolend= line("$") | endif
9741    let newcolqty= newcolend - newcolstart
9742    exe newcolstart
9743    " COMBAK: both of the visual-mode using lines below are problematic vis-a-vis @*
9744    if newcolqty == 0
9745     exe "sil! NetrwKeepj norm! 0\<c-v>$h\"ax".w:netrw_bannercnt."G$\"ap"
9746    else
9747     exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$h"ax'.w:netrw_bannercnt.'G$"ap'
9748    endif
9749    exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
9750    exe 'sil! NetrwKeepj '.w:netrw_bannercnt
9751   endwhile
9752   if has("clipboard")
9753"    call Decho("(s:NetrwWideListing) restore @* and @+",'~'.expand("<slnum>"))
9754    if @* != keepregstar | sil! let @* = keepregstar | endif
9755    if @+ != keepregplus | sil! let @+ = keepregplus | endif
9756   endif
9757   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9758   NetrwKeepj call histdel("/",-1)
9759   exe 'nno <buffer> <silent> w	:call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9760   exe 'nno <buffer> <silent> b	:call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9761"   call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9762   exe "setl ".g:netrw_bufsettings
9763    let @a= keepa
9764"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9765"   call Dret("NetrwWideListing")
9766   return
9767  else
9768   if hasmapto("w","n")
9769    sil! nunmap <buffer> w
9770   endif
9771   if hasmapto("b","n")
9772    sil! nunmap <buffer> b
9773   endif
9774  endif
9775
9776endfun
9777
9778" ---------------------------------------------------------------------
9779" s:PerformListing: {{{2
9780fun! s:PerformListing(islocal)
9781"  call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9782"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9783"  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>"))
9784  sil! NetrwKeepj %d _
9785"  call DechoBuf(bufnr("%"))
9786
9787  " set up syntax highlighting {{{3
9788"  call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
9789  sil! setl ft=netrw
9790
9791  NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
9792  setl noro ma
9793"  call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
9794
9795"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
9796"   call Decho("Processing your browsing request...",'~'.expand("<slnum>"))
9797"  endif								" Decho
9798
9799"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9800  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
9801   " force a refresh for tree listings
9802"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9803   sil! NetrwKeepj %d _
9804  endif
9805
9806  " save current directory on directory history list
9807  NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
9808
9809  " Set up the banner {{{3
9810  if g:netrw_banner
9811"   call Decho("--set up banner",'~'.expand("<slnum>"))
9812   NetrwKeepj call setline(1,'" ============================================================================')
9813   if exists("g:netrw_pchk")
9814    " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9815    " failure detections.
9816    NetrwKeepj call setline(2,'" Netrw Directory Listing')
9817   else
9818    NetrwKeepj call setline(2,'" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')')
9819   endif
9820   if exists("g:netrw_pchk")
9821    let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9822   else
9823    let curdir= b:netrw_curdir
9824   endif
9825   if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9826    NetrwKeepj call setline(3,'"   '.substitute(curdir,'/','\\','g'))
9827   else
9828    NetrwKeepj call setline(3,'"   '.curdir)
9829   endif
9830   let w:netrw_bannercnt= 3
9831   NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
9832  else
9833"   call Decho("--no banner",'~'.expand("<slnum>"))
9834   NetrwKeepj 1
9835   let w:netrw_bannercnt= 1
9836  endif
9837"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9838"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9839
9840  " construct sortby string: [name|time|size|exten] [reversed]
9841  let sortby= g:netrw_sort_by
9842  if g:netrw_sort_direction =~# "^r"
9843   let sortby= sortby." reversed"
9844  endif
9845
9846  " Sorted by... {{{3
9847  if g:netrw_banner
9848"   call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9849   if g:netrw_sort_by =~# "^n"
9850"   call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9851    " sorted by name (also includes the sorting sequence in the banner)
9852    NetrwKeepj put ='\"   Sorted by      '.sortby
9853    NetrwKeepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
9854    let w:netrw_bannercnt= w:netrw_bannercnt + 2
9855   else
9856"   call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9857    " sorted by time, size, exten
9858    NetrwKeepj put ='\"   Sorted by '.sortby
9859    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9860   endif
9861   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9862"  else " Decho
9863"   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>"))
9864  endif
9865
9866  " show copy/move target, if any {{{3
9867  if g:netrw_banner
9868   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9869"    call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9870    NetrwKeepj put =''
9871    if s:netrwmftgt_islocal
9872     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9873    else
9874     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9875    endif
9876    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9877   else
9878"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
9879   endif
9880   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9881  endif
9882
9883  " Hiding...  -or-  Showing... {{{3
9884  if g:netrw_banner
9885"   call Decho("--handle hiding/showing in banner (g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9886   if g:netrw_list_hide != "" && g:netrw_hide
9887    if g:netrw_hide == 1
9888     NetrwKeepj put ='\"   Hiding:        '.g:netrw_list_hide
9889    else
9890     NetrwKeepj put ='\"   Showing:       '.g:netrw_list_hide
9891    endif
9892    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9893   endif
9894   exe "NetrwKeepj ".w:netrw_bannercnt
9895
9896"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9897   let quickhelp   = g:netrw_quickhelp%len(s:QuickHelp)
9898"   call Decho("quickhelp   =".quickhelp,'~'.expand("<slnum>"))
9899   NetrwKeepj put ='\"   Quick Help: <F1>:help  '.s:QuickHelp[quickhelp]
9900"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9901   NetrwKeepj put ='\" =============================================================================='
9902   let w:netrw_bannercnt= w:netrw_bannercnt + 2
9903"  else " Decho
9904"   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>"))
9905  endif
9906
9907  " bannercnt should index the line just after the banner
9908  if g:netrw_banner
9909   let w:netrw_bannercnt= w:netrw_bannercnt + 1
9910   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9911"   call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9912"  else " Decho
9913"   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>"))
9914  endif
9915
9916  " get list of files
9917"  call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
9918  if a:islocal
9919   NetrwKeepj call s:LocalListing()
9920  else " remote
9921   NetrwKeepj let badresult= s:NetrwRemoteListing()
9922   if badresult
9923"    call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9924"    call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9925    return
9926   endif
9927  endif
9928
9929  " manipulate the directory listing (hide, sort) {{{3
9930  if !exists("w:netrw_bannercnt")
9931   let w:netrw_bannercnt= 0
9932  endif
9933"  call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9934"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9935"  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>"))
9936
9937  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9938"   call Decho("manipulate directory listing (support hide)",'~'.expand("<slnum>"))
9939"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9940   if g:netrw_hide && g:netrw_list_hide != ""
9941    NetrwKeepj call s:NetrwListHide()
9942   endif
9943   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9944"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9945
9946    if g:netrw_sort_by =~# "^n"
9947     " sort by name
9948"     call Decho("sort by name",'~'.expand("<slnum>"))
9949     NetrwKeepj call s:NetrwSetSort()
9950
9951     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9952"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9953      if g:netrw_sort_direction =~# 'n'
9954       " name: sort by name of file
9955       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9956      else
9957       " reverse direction sorting
9958       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9959      endif
9960     endif
9961
9962     " remove priority pattern prefix
9963"     call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9964     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9965     NetrwKeepj call histdel("/",-1)
9966
9967    elseif g:netrw_sort_by =~# "^ext"
9968     " exten: sort by extension
9969     "   The histdel(...,-1) calls remove the last search from the search history
9970"     call Decho("sort by extension",'~'.expand("<slnum>"))
9971     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9972     NetrwKeepj call histdel("/",-1)
9973     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9974     NetrwKeepj call histdel("/",-1)
9975     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9976     NetrwKeepj call histdel("/",-1)
9977     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9978"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9979      if g:netrw_sort_direction =~# 'n'
9980       " normal direction sorting
9981       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9982      else
9983       " reverse direction sorting
9984       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9985      endif
9986     endif
9987     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9988     NetrwKeepj call histdel("/",-1)
9989
9990    elseif a:islocal
9991     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9992"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9993      if g:netrw_sort_direction =~# 'n'
9994"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9995       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9996      else
9997"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9998       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9999      endif
10000"     call Decho("remove leading digits/ (sorting) information from listing",'~'.expand("<slnum>"))
10001     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
10002     NetrwKeepj call histdel("/",-1)
10003     endif
10004    endif
10005
10006   elseif g:netrw_sort_direction =~# 'r'
10007"    call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
10008    if !g:netrw_banner || w:netrw_bannercnt < line('$')
10009     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
10010     call histdel("/",-1)
10011    endif
10012   endif
10013  endif
10014"  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>"))
10015
10016  " convert to wide/tree listing {{{3
10017"  call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
10018"  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>"))
10019  NetrwKeepj call s:NetrwWideListing()
10020"  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>"))
10021  NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
10022"  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>"))
10023
10024  " resolve symbolic links if local and (thin or tree)
10025  if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
10026"   call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
10027   sil! g/@$/call s:ShowLink()
10028  endif
10029
10030  if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
10031   " place cursor on the top-left corner of the file listing
10032"   call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
10033   exe 'sil! '.w:netrw_bannercnt
10034   sil! NetrwKeepj norm! 0
10035"   call Decho("  tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
10036  else
10037"   call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
10038"   call Decho("  w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
10039"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
10040"   call Decho("  g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
10041  endif
10042
10043  " record previous current directory
10044  let w:netrw_prvdir= b:netrw_curdir
10045"  call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
10046
10047  " save certain window-oriented variables into buffer-oriented variables {{{3
10048"  call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
10049"  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>"))
10050  NetrwKeepj call s:SetBufWinVars()
10051"  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>"))
10052  NetrwKeepj call s:NetrwOptionsRestore("w:")
10053"  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>"))
10054
10055  " set display to netrw display settings
10056"  call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
10057  exe "setl ".g:netrw_bufsettings
10058"  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>"))
10059  if g:netrw_liststyle == s:LONGLIST
10060"   call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
10061   exe "setl ts=".(g:netrw_maxfilenamelen+1)
10062  endif
10063"  call Decho("PerformListing buffer:",'~'.expand("<slnum>"))
10064"  call DechoBuf(bufnr("%"))
10065
10066  if exists("s:treecurpos")
10067"   call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
10068"   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>"))
10069"   call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
10070   NetrwKeepj call winrestview(s:treecurpos)
10071   unlet s:treecurpos
10072  endif
10073
10074"  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>"))
10075"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
10076"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
10077endfun
10078
10079" ---------------------------------------------------------------------
10080" s:SetupNetrwStatusLine: {{{2
10081fun! s:SetupNetrwStatusLine(statline)
10082"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
10083
10084  if !exists("s:netrw_setup_statline")
10085   let s:netrw_setup_statline= 1
10086"   call Decho("do first-time status line setup",'~'.expand("<slnum>"))
10087
10088   if !exists("s:netrw_users_stl")
10089    let s:netrw_users_stl= &stl
10090   endif
10091   if !exists("s:netrw_users_ls")
10092    let s:netrw_users_ls= &laststatus
10093   endif
10094
10095   " set up User9 highlighting as needed
10096   let keepa= @a
10097   redir @a
10098   try
10099    hi User9
10100   catch /^Vim\%((\a\{3,})\)\=:E411/
10101    if &bg == "dark"
10102     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
10103    else
10104     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
10105    endif
10106   endtry
10107   redir END
10108   let @a= keepa
10109  endif
10110
10111  " set up status line (may use User9 highlighting)
10112  " insure that windows have a statusline
10113  " make sure statusline is displayed
10114  let &stl=a:statline
10115  setl laststatus=2
10116"  call Decho("stl=".&stl,'~'.expand("<slnum>"))
10117  redraw
10118
10119"  call Dret("SetupNetrwStatusLine : stl=".&stl)
10120endfun
10121
10122" =========================================
10123"  Remote Directory Browsing Support:  {{{1
10124" =========================================
10125
10126" ---------------------------------------------------------------------
10127" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
10128"  This function assumes that a long listing will be received.  Size, time,
10129"  and reverse sorts will be requested of the server but not otherwise
10130"  enforced here.
10131fun! s:NetrwRemoteFtpCmd(path,listcmd)
10132"  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 : "???")))
10133"  call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
10134  " sanity check: {{{3
10135  if !exists("w:netrw_method")
10136   if exists("b:netrw_method")
10137    let w:netrw_method= b:netrw_method
10138   else
10139    call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
10140"    call Dret("NetrwRemoteFtpCmd")
10141    return
10142   endif
10143  endif
10144
10145  " WinXX ftp uses unix style input, so set ff to unix	" {{{3
10146  let ffkeep= &ff
10147  setl ma ff=unix noro
10148"  call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
10149
10150  " clear off any older non-banner lines	" {{{3
10151  " note that w:netrw_bannercnt indexes the line after the banner
10152"  call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _  (clear off old non-banner lines)",'~'.expand("<slnum>"))
10153  exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
10154
10155  ".........................................
10156  if w:netrw_method == 2 || w:netrw_method == 5	" {{{3
10157   " ftp + <.netrc>:  Method #2
10158   if a:path != ""
10159    NetrwKeepj put ='cd \"'.a:path.'\"'
10160   endif
10161   if exists("g:netrw_ftpextracmd")
10162    NetrwKeepj put =g:netrw_ftpextracmd
10163"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
10164   endif
10165   NetrwKeepj call setline(line("$")+1,a:listcmd)
10166"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
10167   if exists("g:netrw_port") && g:netrw_port != ""
10168"    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>"))
10169    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)
10170   else
10171"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
10172    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
10173   endif
10174
10175  ".........................................
10176  elseif w:netrw_method == 3	" {{{3
10177   " ftp + machine,id,passwd,filename:  Method #3
10178    setl ff=unix
10179    if exists("g:netrw_port") && g:netrw_port != ""
10180     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
10181    else
10182     NetrwKeepj put ='open '.g:netrw_machine
10183    endif
10184
10185    " handle userid and password
10186    let host= substitute(g:netrw_machine,'\..*$','','')
10187"    call Decho("host<".host.">",'~'.expand("<slnum>"))
10188    if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
10189     call NetUserPass("ftp:".host)
10190    endif
10191    if exists("g:netrw_uid") && g:netrw_uid != ""
10192     if exists("g:netrw_ftp") && g:netrw_ftp == 1
10193      NetrwKeepj put =g:netrw_uid
10194      if exists("s:netrw_passwd") && s:netrw_passwd != ""
10195       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
10196      endif
10197     elseif exists("s:netrw_passwd")
10198      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
10199     endif
10200    endif
10201
10202   if a:path != ""
10203    NetrwKeepj put ='cd \"'.a:path.'\"'
10204   endif
10205   if exists("g:netrw_ftpextracmd")
10206    NetrwKeepj put =g:netrw_ftpextracmd
10207"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
10208   endif
10209   NetrwKeepj call setline(line("$")+1,a:listcmd)
10210
10211   " perform ftp:
10212   " -i       : turns off interactive prompting from ftp
10213   " -n  unix : DON'T use <.netrc>, even though it exists
10214   " -n  win32: quit being obnoxious about password
10215   if exists("w:netrw_bannercnt")
10216"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
10217    call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
10218"   else " Decho
10219"    call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
10220"    g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
10221   endif
10222
10223  ".........................................
10224  elseif w:netrw_method == 9	" {{{3
10225   " sftp username@machine: Method #9
10226   " s:netrw_sftp_cmd
10227   setl ff=unix
10228
10229   " restore settings
10230   let &ff= ffkeep
10231"   call Dret("NetrwRemoteFtpCmd")
10232   return
10233
10234  ".........................................
10235  else	" {{{3
10236   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
10237  endif
10238
10239  " cleanup for Windows " {{{3
10240  if has("win32") || has("win95") || has("win64") || has("win16")
10241   sil! NetrwKeepj %s/\r$//e
10242   NetrwKeepj call histdel("/",-1)
10243  endif
10244  if a:listcmd == "dir"
10245   " infer directory/link based on the file permission string
10246   sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
10247   sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
10248   NetrwKeepj call histdel("/",-1)
10249   NetrwKeepj call histdel("/",-1)
10250   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10251    exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
10252    NetrwKeepj call histdel("/",-1)
10253   endif
10254  endif
10255
10256  " ftp's listing doesn't seem to include ./ or ../ " {{{3
10257  if !search('^\.\/$\|\s\.\/$','wn')
10258   exe 'NetrwKeepj '.w:netrw_bannercnt
10259   NetrwKeepj put ='./'
10260  endif
10261  if !search('^\.\.\/$\|\s\.\.\/$','wn')
10262   exe 'NetrwKeepj '.w:netrw_bannercnt
10263   NetrwKeepj put ='../'
10264  endif
10265
10266  " restore settings " {{{3
10267  let &ff= ffkeep
10268"  call Dret("NetrwRemoteFtpCmd")
10269endfun
10270
10271" ---------------------------------------------------------------------
10272" s:NetrwRemoteListing: {{{2
10273fun! s:NetrwRemoteListing()
10274"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
10275
10276  if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
10277   let w:netrw_bannercnt= s:bannercnt
10278  endif
10279  if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
10280   let w:netrw_bannercnt= s:bannercnt
10281  endif
10282
10283  call s:RemotePathAnalysis(b:netrw_curdir)
10284
10285  " sanity check:
10286  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
10287"   call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
10288   if !executable("ftp")
10289"    call Decho("ftp is not executable",'~'.expand("<slnum>"))
10290    if !exists("g:netrw_quiet")
10291     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
10292    endif
10293    call s:NetrwOptionsRestore("w:")
10294"    call Dret("s:NetrwRemoteListing -1")
10295    return -1
10296   endif
10297
10298  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
10299"   call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
10300   if !exists("g:netrw_quiet")
10301    if g:netrw_list_cmd == ""
10302     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)
10303    else
10304     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
10305    endif
10306   endif
10307
10308   NetrwKeepj call s:NetrwOptionsRestore("w:")
10309"   call Dret("s:NetrwRemoteListing -1")
10310   return -1
10311  endif  " (remote handling sanity check)
10312"  call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
10313
10314  if exists("b:netrw_method")
10315"   call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
10316   let w:netrw_method= b:netrw_method
10317  endif
10318
10319  if s:method == "ftp"
10320   " use ftp to get remote file listing {{{3
10321"   call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
10322   let s:method  = "ftp"
10323   let listcmd = g:netrw_ftp_list_cmd
10324   if g:netrw_sort_by =~# '^t'
10325    let listcmd= g:netrw_ftp_timelist_cmd
10326   elseif g:netrw_sort_by =~# '^s'
10327    let listcmd= g:netrw_ftp_sizelist_cmd
10328   endif
10329"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
10330   call s:NetrwRemoteFtpCmd(s:path,listcmd)
10331"   exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
10332
10333   " report on missing file or directory messages
10334   if search('[Nn]o such file or directory\|Failed to change directory')
10335    let mesg= getline(".")
10336    if exists("w:netrw_bannercnt")
10337     setl ma
10338     exe w:netrw_bannercnt.",$d _"
10339     setl noma
10340    endif
10341    NetrwKeepj call s:NetrwOptionsRestore("w:")
10342    call netrw#ErrorMsg(s:WARNING,mesg,96)
10343"    call Dret("s:NetrwRemoteListing : -1")
10344    return -1
10345   endif
10346
10347   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10348    " shorten the listing
10349"    call Decho("generate short listing",'~'.expand("<slnum>"))
10350    exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
10351
10352    " cleanup
10353    if g:netrw_ftp_browse_reject != ""
10354     exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
10355     NetrwKeepj call histdel("/",-1)
10356    endif
10357    sil! NetrwKeepj %s/\r$//e
10358    NetrwKeepj call histdel("/",-1)
10359
10360    " if there's no ../ listed, then put ../ in
10361    let line1= line(".")
10362    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10363    let line2= search('\.\.\/\%(\s\|$\)','cnW')
10364"    call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2."  w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
10365    if line2 == 0
10366"     call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
10367     sil! NetrwKeepj put='../'
10368    endif
10369    exe "sil! NetrwKeepj ".line1
10370    sil! NetrwKeepj norm! 0
10371
10372"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
10373    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10374"     call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
10375     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
10376     NetrwKeepj call histdel("/",-1)
10377    else " normal ftp cleanup
10378"     call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
10379     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
10380     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
10381     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
10382     NetrwKeepj call histdel("/",-1)
10383     NetrwKeepj call histdel("/",-1)
10384     NetrwKeepj call histdel("/",-1)
10385    endif
10386   endif
10387
10388   else
10389   " use ssh to get remote file listing {{{3
10390"   call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
10391   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
10392"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
10393   if g:netrw_scp_cmd =~ '^pscp'
10394"    call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
10395    exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
10396    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
10397    sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
10398    sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
10399    sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
10400    NetrwKeepj call histdel("/",-1)
10401    NetrwKeepj call histdel("/",-1)
10402    NetrwKeepj call histdel("/",-1)
10403    if g:netrw_liststyle != s:LONGLIST
10404     sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
10405     NetrwKeepj call histdel("/",-1)
10406    endif
10407   else
10408    if s:path == ""
10409"     call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
10410     exe "NetrwKeepj keepalt r! ".listcmd
10411    else
10412"     call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
10413     exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
10414"     call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
10415    endif
10416   endif
10417
10418   " cleanup
10419   if g:netrw_ssh_browse_reject != ""
10420"    call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
10421    exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
10422    NetrwKeepj call histdel("/",-1)
10423   endif
10424  endif
10425
10426  if w:netrw_liststyle == s:LONGLIST
10427   " do a long listing; these substitutions need to be done prior to sorting {{{3
10428"   call Decho("fix long listing:",'~'.expand("<slnum>"))
10429
10430   if s:method == "ftp"
10431    " cleanup
10432    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10433    while getline('.') =~# g:netrw_ftp_browse_reject
10434     sil! NetrwKeepj d
10435    endwhile
10436    " if there's no ../ listed, then put ../ in
10437    let line1= line(".")
10438    sil! NetrwKeepj 1
10439    sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
10440    let line2= line(".")
10441    if line2 == 0
10442     if b:netrw_curdir != '/'
10443      exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
10444     endif
10445    endif
10446    exe "sil! NetrwKeepj ".line1
10447    sil! NetrwKeepj norm! 0
10448   endif
10449
10450   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10451"    call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
10452    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/'
10453   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
10454"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
10455    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
10456    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
10457    exe 'sil NetrwKeepj '.w:netrw_bannercnt
10458    NetrwKeepj call histdel("/",-1)
10459    NetrwKeepj call histdel("/",-1)
10460    NetrwKeepj call histdel("/",-1)
10461   endif
10462  endif
10463
10464"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
10465"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
10466"  endif " Decho
10467
10468"  call Dret("s:NetrwRemoteListing 0")
10469  return 0
10470endfun
10471
10472" ---------------------------------------------------------------------
10473" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
10474fun! s:NetrwRemoteRm(usrhost,path) range
10475"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
10476"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10477  let svpos= winsaveview()
10478"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10479
10480  let all= 0
10481  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10482   " remove all marked files
10483"   call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>"))
10484   for fname in s:netrwmarkfilelist_{bufnr("%")}
10485    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
10486    if ok =~# 'q\%[uit]'
10487     break
10488    elseif ok =~# 'a\%[ll]'
10489     let all= 1
10490    endif
10491   endfor
10492   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10493
10494  else
10495   " remove files specified by range
10496"   call Decho("remove files specified by range",'~'.expand("<slnum>"))
10497
10498   " preparation for removing multiple files/directories
10499   let keepsol = &l:sol
10500   setl nosol
10501   let ctr    = a:firstline
10502
10503   " remove multiple files and directories
10504   while ctr <= a:lastline
10505    exe "NetrwKeepj ".ctr
10506    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
10507    if ok =~# 'q\%[uit]'
10508     break
10509    elseif ok =~# 'a\%[ll]'
10510     let all= 1
10511    endif
10512    let ctr= ctr + 1
10513   endwhile
10514   let &l:sol = keepsol
10515  endif
10516
10517  " refresh the (remote) directory listing
10518"  call Decho("refresh remote directory listing",'~'.expand("<slnum>"))
10519  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10520"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10521  NetrwKeepj call winrestview(svpos)
10522
10523"  call Dret("s:NetrwRemoteRm")
10524endfun
10525
10526" ---------------------------------------------------------------------
10527" s:NetrwRemoteRmFile: {{{2
10528fun! s:NetrwRemoteRmFile(path,rmfile,all)
10529"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
10530
10531  let all= a:all
10532  let ok = ""
10533
10534  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
10535   " attempt to remove file
10536"    call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
10537   if !all
10538    echohl Statement
10539"    call Decho("case all=0:",'~'.expand("<slnum>"))
10540    call inputsave()
10541    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10542    call inputrestore()
10543    echohl NONE
10544    if ok == ""
10545     let ok="no"
10546    endif
10547    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10548    if ok =~# 'a\%[ll]'
10549     let all= 1
10550    endif
10551   endif
10552
10553   if all || ok =~# 'y\%[es]' || ok == ""
10554"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
10555    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10556"     call Decho("case ftp:",'~'.expand("<slnum>"))
10557     let path= a:path
10558     if path =~ '^\a\{3,}://'
10559      let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
10560     endif
10561     sil! NetrwKeepj .,$d _
10562     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
10563    else
10564"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
10565     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
10566"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10567     if !exists("b:netrw_curdir")
10568      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
10569      let ok="q"
10570     else
10571      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
10572"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10573"      call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
10574"      call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
10575      if remotedir != ""
10576       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
10577      else
10578       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
10579      endif
10580"      call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
10581      let ret= system(netrw_rm_cmd)
10582      if v:shell_error != 0
10583       if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
10584	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)
10585       else
10586        call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10587       endif
10588      elseif ret != 0
10589       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10590      endif
10591"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10592     endif
10593    endif
10594   elseif ok =~# 'q\%[uit]'
10595"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10596   endif
10597
10598  else
10599   " attempt to remove directory
10600"    call Decho("attempt to remove directory",'~'.expand("<slnum>"))
10601   if !all
10602    call inputsave()
10603    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10604    call inputrestore()
10605    if ok == ""
10606     let ok="no"
10607    endif
10608    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10609    if ok =~# 'a\%[ll]'
10610     let all= 1
10611    endif
10612   endif
10613
10614   if all || ok =~# 'y\%[es]' || ok == ""
10615    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10616     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
10617    else
10618     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
10619     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
10620"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
10621     let ret= system(netrw_rmdir_cmd)
10622"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10623
10624     if v:shell_error != 0
10625"      call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
10626      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
10627"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
10628      let ret= system(netrw_rmf_cmd)
10629"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10630
10631      if v:shell_error != 0 && !exists("g:netrw_quiet")
10632      	NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
10633      endif
10634     endif
10635    endif
10636
10637   elseif ok =~# 'q\%[uit]'
10638"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10639   endif
10640  endif
10641
10642"  call Dret("s:NetrwRemoteRmFile ".ok)
10643  return ok
10644endfun
10645
10646" ---------------------------------------------------------------------
10647" s:NetrwRemoteRename: rename a remote file or directory {{{2
10648fun! s:NetrwRemoteRename(usrhost,path) range
10649"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
10650
10651  " preparation for removing multiple files/directories
10652  let svpos      = winsaveview()
10653"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10654  let ctr        = a:firstline
10655  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10656
10657  " rename files given by the markfilelist
10658  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10659   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10660"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10661    if exists("subfrom")
10662     let newname= substitute(oldname,subfrom,subto,'')
10663"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10664    else
10665     call inputsave()
10666     let newname= input("Moving ".oldname." to : ",oldname)
10667     call inputrestore()
10668     if newname =~ '^s/'
10669      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10670      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10671      let newname = substitute(oldname,subfrom,subto,'')
10672"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10673     endif
10674    endif
10675
10676    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10677     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10678    else
10679     let oldname= s:ShellEscape(a:path.oldname)
10680     let newname= s:ShellEscape(a:path.newname)
10681"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10682     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10683    endif
10684
10685   endfor
10686   call s:NetrwUnMarkFile(1)
10687
10688  else
10689
10690  " attempt to rename files/directories
10691   let keepsol= &l:sol
10692   setl nosol
10693   while ctr <= a:lastline
10694    exe "NetrwKeepj ".ctr
10695
10696    let oldname= s:NetrwGetWord()
10697"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10698
10699    call inputsave()
10700    let newname= input("Moving ".oldname." to : ",oldname)
10701    call inputrestore()
10702
10703    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10704     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10705    else
10706     let oldname= s:ShellEscape(a:path.oldname)
10707     let newname= s:ShellEscape(a:path.newname)
10708"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10709     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10710    endif
10711
10712    let ctr= ctr + 1
10713   endwhile
10714   let &l:sol= keepsol
10715  endif
10716
10717  " refresh the directory
10718  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10719"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10720  NetrwKeepj call winrestview(svpos)
10721
10722"  call Dret("NetrwRemoteRename")
10723endfun
10724
10725" ==========================================
10726"  Local Directory Browsing Support:    {{{1
10727" ==========================================
10728
10729" ---------------------------------------------------------------------
10730" netrw#FileUrlEdit: handles editing file://* files {{{2
10731"   Should accept:   file://localhost/etc/fstab
10732"                    file:///etc/fstab
10733"                    file:///c:/WINDOWS/clock.avi
10734"                    file:///c|/WINDOWS/clock.avi
10735"                    file://localhost/c:/WINDOWS/clock.avi
10736"                    file://localhost/c|/WINDOWS/clock.avi
10737"                    file://c:/foo.txt
10738"                    file:///c:/foo.txt
10739" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
10740fun! netrw#FileUrlEdit(fname)
10741"  call Dfunc("netrw#FileUrlEdit(fname<".a:fname.">)")
10742  let fname = a:fname
10743  if fname =~ '^file://localhost/'
10744"   call Decho('converting file://localhost/   -to-  file:///','~'.expand("<slnum>"))
10745   let fname= substitute(fname,'^file://localhost/','file:///','')
10746"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10747  endif
10748  if (has("win32") || has("win95") || has("win64") || has("win16"))
10749   if fname  =~ '^file:///\=\a[|:]/'
10750"    call Decho('converting file:///\a|/   -to-  file://\a:/','~'.expand("<slnum>"))
10751    let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10752"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10753   endif
10754  endif
10755  let fname2396 = netrw#RFC2396(fname)
10756  let fname2396e= fnameescape(fname2396)
10757  let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
10758  if (has("win32") || has("win95") || has("win64") || has("win16"))
10759"   call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10760   if plainfname =~ '^/\+\a:'
10761"    call Decho('removing leading "/"s','~'.expand("<slnum>"))
10762    let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10763   endif
10764  endif
10765
10766"  call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10767"  call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
10768  exe "sil doau BufReadPre ".fname2396e
10769  exe 'NetrwKeepj keepalt edit '.plainfname
10770  exe 'sil! NetrwKeepj keepalt bdelete '.fnameescape(a:fname)
10771
10772"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10773"  call Dret("netrw#FileUrlEdit")
10774  exe "sil doau BufReadPost ".fname2396e
10775endfun
10776
10777" ---------------------------------------------------------------------
10778" netrw#LocalBrowseCheck: {{{2
10779fun! netrw#LocalBrowseCheck(dirname)
10780  " This function is called by netrwPlugin.vim's s:LocalBrowseCheck(), s:NetrwRexplore(),
10781  " and by <cr> when atop a listed file/directory (via a buffer-local map)
10782  "
10783  " unfortunate interaction -- split window debugging can't be used here, must use
10784  "                            D-echoRemOn or D-echoTabOn as the BufEnter event triggers
10785  "                            another call to LocalBrowseCheck() when attempts to write
10786  "                            to the DBG buffer are made.
10787  "
10788  " The &ft == "netrw" test was installed because the BufEnter event
10789  " would hit when re-entering netrw windows, creating unexpected
10790  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
10791"  call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">)")
10792"  call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>"))
10793"  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>"))
10794"  call Dredir("ls!","netrw#LocalBrowseCheck")
10795"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10796"  call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
10797
10798  let ykeep= @@
10799  if isdirectory(s:NetrwFile(a:dirname))
10800"   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>"))
10801
10802   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10803"    call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10804"    call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10805    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10806
10807   elseif &ft == "netrw" && line("$") == 1
10808"    call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10809    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10810
10811   elseif exists("s:treeforceredraw")
10812"    call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10813    unlet s:treeforceredraw
10814    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10815   endif
10816"   call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10817"   call Dret("netrw#LocalBrowseCheck")
10818   return
10819  endif
10820
10821  " The following code wipes out currently unused netrw buffers
10822  "       IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10823  "   AND IF the listing style is not a tree listing
10824  if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
10825"   call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10826   let ibuf    = 1
10827   let buflast = bufnr("$")
10828   while ibuf <= buflast
10829    if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10830     exe "sil! keepj keepalt ".ibuf."bw!"
10831    endif
10832    let ibuf= ibuf + 1
10833   endwhile
10834  endif
10835  let @@= ykeep
10836"  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>"))
10837"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10838  " not a directory, ignore it
10839"  call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
10840endfun
10841
10842" ---------------------------------------------------------------------
10843" s:LocalBrowseRefresh: this function is called after a user has {{{2
10844" performed any shell command.  The idea is to cause all local-browsing
10845" buffers to be refreshed after a user has executed some shell command,
10846" on the chance that s/he removed/created a file/directory with it.
10847fun! s:LocalBrowseRefresh()
10848"  call Dfunc("s:LocalBrowseRefresh() tabpagenr($)=".tabpagenr("$"))
10849"  call Decho("s:netrw_browselist =".(exists("s:netrw_browselist")?  string(s:netrw_browselist)  : '<n/a>'),'~'.expand("<slnum>"))
10850"  call Decho("w:netrw_bannercnt  =".(exists("w:netrw_bannercnt")?   string(w:netrw_bannercnt)   : '<n/a>'),'~'.expand("<slnum>"))
10851
10852  " determine which buffers currently reside in a tab
10853  if !exists("s:netrw_browselist")
10854"   call Dret("s:LocalBrowseRefresh : browselist is empty")
10855   return
10856  endif
10857  if !exists("w:netrw_bannercnt")
10858"   call Dret("s:LocalBrowseRefresh : don't refresh when focus not on netrw window")
10859   return
10860  endif
10861  if exists("s:netrw_events") && s:netrw_events == 1
10862   " s:LocalFastBrowser gets called (indirectly) from a
10863   let s:netrw_events= 2
10864"   call Dret("s:LocalBrowseRefresh : avoid initial double refresh")
10865   return
10866  endif
10867  let itab       = 1
10868  let buftablist = []
10869  let ykeep      = @@
10870  while itab <= tabpagenr("$")
10871   let buftablist = buftablist + tabpagebuflist()
10872   let itab       = itab + 1
10873   sil! tabn
10874  endwhile
10875"  call Decho("buftablist".string(buftablist),'~'.expand("<slnum>"))
10876"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("<slnum>"))
10877  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10878  "   | refresh any netrw window
10879  "   | wipe out any non-displaying netrw buffer
10880  let curwinid = win_getid(winnr())
10881  let ibl    = 0
10882  for ibuf in s:netrw_browselist
10883"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("<slnum>"))
10884   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10885    " wipe out any non-displaying netrw buffer
10886    " (ibuf not shown in a current window AND
10887    "  ibuf not in any tab)
10888"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("<slnum>"))
10889    exe "sil! keepj bd ".fnameescape(ibuf)
10890    call remove(s:netrw_browselist,ibl)
10891"    call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10892    continue
10893   elseif index(tabpagebuflist(),ibuf) != -1
10894    " refresh any netrw buffer
10895"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>"))
10896    exe bufwinnr(ibuf)."wincmd w"
10897    if getline(".") =~# 'Quick Help'
10898     " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10899     " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10900     let g:netrw_quickhelp= g:netrw_quickhelp - 1
10901    endif
10902"    call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>"))
10903    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10904     NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10905    endif
10906    NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10907   endif
10908   let ibl= ibl + 1
10909"   call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("<slnum>"))
10910  endfor
10911"  call Decho("restore window: win_gotoid(".curwinid.")")
10912  call win_gotoid(curwinid)
10913  let @@= ykeep
10914
10915"  call Dret("s:LocalBrowseRefresh")
10916endfun
10917
10918" ---------------------------------------------------------------------
10919" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10920"
10921"     g:netrw_    Directory Is
10922"     fastbrowse  Local  Remote
10923"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
10924"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
10925"  fast   2         H      H
10926"
10927"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10928"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
10929"                       (re-using a buffer may not be as accurate)
10930"
10931"  s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds with medium-speed or fast browsing
10932"                   =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10933"                       BufEnter may be first event, then a FocusGained event.  Ignore the first FocusGained event.
10934"                       If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10935"                   =2: autocmds installed (doesn't ignore any FocusGained events)
10936fun! s:LocalFastBrowser()
10937"  call Dfunc("s:LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
10938"  call Decho("s:netrw_events        ".(exists("s:netrw_events")? "exists"            : 'n/a'),'~'.expand("<slnum>"))
10939"  call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")?  "already installed" : "not installed"),'~'.expand("<slnum>"))
10940"  call Decho("autocmd: FocusGained  ".(exists("#FocusGained")?   "already installed" : "not installed"),'~'.expand("<slnum>"))
10941
10942  " initialize browselist, a list of buffer numbers that the local browser has used
10943  if !exists("s:netrw_browselist")
10944"   call Decho("initialize s:netrw_browselist",'~'.expand("<slnum>"))
10945   let s:netrw_browselist= []
10946  endif
10947
10948  " append current buffer to fastbrowse list
10949  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
10950"   call Decho("appendng current buffer to browselist",'~'.expand("<slnum>"))
10951   call add(s:netrw_browselist,bufnr("%"))
10952"   call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10953  endif
10954
10955  " enable autocmd events to handle refreshing/removing local browser buffers
10956  "    If local browse buffer is currently showing: refresh it
10957  "    If local browse buffer is currently hidden : wipe it
10958  "    g:netrw_fastbrowse=0 : slow   speed, never re-use directory listing
10959  "                      =1 : medium speed, re-use directory listing for remote only
10960  "                      =2 : fast   speed, always re-use directory listing when possible
10961  if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
10962   let s:netrw_events= 1
10963   augroup AuNetrwEvent
10964    au!
10965    if (has("win32") || has("win95") || has("win64") || has("win16"))
10966"     call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
10967     au ShellCmdPost			*	call s:LocalBrowseRefresh()
10968    else
10969"     call Decho("installing autocmds: ShellCmdPost FocusGained",'~'.expand("<slnum>"))
10970     au ShellCmdPost,FocusGained	*	call s:LocalBrowseRefresh()
10971    endif
10972   augroup END
10973
10974  " user must have changed fastbrowse to its fast setting, so remove
10975  " the associated autocmd events
10976  elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
10977"   call Decho("remove AuNetrwEvent autcmd group",'~'.expand("<slnum>"))
10978   unlet s:netrw_events
10979   augroup AuNetrwEvent
10980    au!
10981   augroup END
10982   augroup! AuNetrwEvent
10983  endif
10984
10985"  call Dret("s:LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
10986endfun
10987
10988" ---------------------------------------------------------------------
10989"  s:LocalListing: does the job of "ls" for local directories {{{2
10990fun! s:LocalListing()
10991"  call Dfunc("s:LocalListing()")
10992"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10993"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
10994"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10995
10996"  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
10997"  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
10998"  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>"))
10999
11000  " get the list of files contained in the current directory
11001  let dirname    = b:netrw_curdir
11002  let dirnamelen = strlen(b:netrw_curdir)
11003  let filelist   = s:NetrwGlob(dirname,"*",0)
11004  let filelist   = filelist + s:NetrwGlob(dirname,".*",0)
11005"  call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
11006
11007  if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
11008"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
11009  elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
11010    " include ../ in the glob() entry if its missing
11011"   call Decho("forcibly including on \"..\"",'~'.expand("<slnum>"))
11012   let filelist= filelist+[s:ComposePath(b:netrw_curdir,"../")]
11013"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
11014  endif
11015
11016"  call Decho("before while: dirname   <".dirname.">",'~'.expand("<slnum>"))
11017"  call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>"))
11018"  call Decho("before while: filelist  =".string(filelist),'~'.expand("<slnum>"))
11019
11020  if get(g:, 'netrw_dynamic_maxfilenamelen', 0)
11021   let filelistcopy           = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
11022   let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
11023"   call Decho("dynamic_maxfilenamelen: filenames             =".string(filelistcopy),'~'.expand("<slnum>"))
11024"   call Decho("dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen,'~'.expand("<slnum>"))
11025  endif
11026"  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>"))
11027
11028  for filename in filelist
11029"   call Decho(" ",'~'.expand("<slnum>"))
11030"   call Decho("for filename in filelist: filename<".filename.">",'~'.expand("<slnum>"))
11031
11032   if getftype(filename) == "link"
11033    " indicate a symbolic link
11034"    call Decho("indicate <".filename."> is a symbolic link with trailing @",'~'.expand("<slnum>"))
11035    let pfile= filename."@"
11036
11037   elseif getftype(filename) == "socket"
11038    " indicate a socket
11039"    call Decho("indicate <".filename."> is a socket with trailing =",'~'.expand("<slnum>"))
11040    let pfile= filename."="
11041
11042   elseif getftype(filename) == "fifo"
11043    " indicate a fifo
11044"    call Decho("indicate <".filename."> is a fifo with trailing |",'~'.expand("<slnum>"))
11045    let pfile= filename."|"
11046
11047   elseif isdirectory(s:NetrwFile(filename))
11048    " indicate a directory
11049"    call Decho("indicate <".filename."> is a directory with trailing /",'~'.expand("<slnum>"))
11050    let pfile= filename."/"
11051
11052   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
11053    if (has("win32") || has("win95") || has("win64") || has("win16"))
11054     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
11055      " indicate an executable
11056"      call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
11057      let pfile= filename."*"
11058     else
11059      " normal file
11060      let pfile= filename
11061     endif
11062    elseif executable(filename)
11063     " indicate an executable
11064"     call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
11065     let pfile= filename."*"
11066    else
11067     " normal file
11068     let pfile= filename
11069    endif
11070
11071   else
11072    " normal file
11073    let pfile= filename
11074   endif
11075"   call Decho("pfile<".pfile."> (after *@/ appending)",'~'.expand("<slnum>"))
11076
11077   if pfile =~ '//$'
11078    let pfile= substitute(pfile,'//$','/','e')
11079"    call Decho("change // to /: pfile<".pfile.">",'~'.expand("<slnum>"))
11080   endif
11081   let pfile= strpart(pfile,dirnamelen)
11082   let pfile= substitute(pfile,'^[/\\]','','e')
11083"   call Decho("filename<".filename.">",'~'.expand("<slnum>"))
11084"   call Decho("pfile   <".pfile.">",'~'.expand("<slnum>"))
11085
11086   if w:netrw_liststyle == s:LONGLIST
11087    let sz   = getfsize(filename)
11088    let fsz  = strpart("               ",1,15-strlen(sz)).sz
11089    if g:netrw_sizestyle =~# "[hH]"
11090     let sz= s:NetrwHumanReadable(sz)
11091    endif
11092    let longfile= printf("%-".(g:netrw_maxfilenamelen+1)."s",pfile)
11093    let pfile   = longfile.sz." ".strftime(g:netrw_timefmt,getftime(filename))
11094"    call Decho("longlist support: sz=".sz." fsz=".fsz,'~'.expand("<slnum>"))
11095   endif
11096
11097   if     g:netrw_sort_by =~# "^t"
11098    " sort by time (handles time up to 1 quintillion seconds, US)
11099    " Decorate listing by prepending a timestamp/  .  Sorting will then be done based on time.
11100"    call Decho("implementing g:netrw_sort_by=".g:netrw_sort_by." (time)")
11101"    call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>"))
11102    let t  = getftime(filename)
11103    let ft = strpart("000000000000000000",1,18-strlen(t)).t
11104"    call Decho("exe NetrwKeepj put ='".ft.'/'.pfile."'",'~'.expand("<slnum>"))
11105    let ftpfile= ft.'/'.pfile
11106    sil! NetrwKeepj put=ftpfile
11107
11108   elseif g:netrw_sort_by =~ "^s"
11109    " sort by size (handles file sizes up to 1 quintillion bytes, US)
11110"    call Decho("implementing g:netrw_sort_by=".g:netrw_sort_by." (size)")
11111"    call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>"))
11112    let sz   = getfsize(filename)
11113    if g:netrw_sizestyle =~# "[hH]"
11114     let sz= s:NetrwHumanReadable(sz)
11115    endif
11116    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
11117"    call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>"))
11118    let fszpfile= fsz.'/'.pfile
11119    sil! NetrwKeepj put =fszpfile
11120
11121   else
11122    " sort by name
11123"    call Decho("implementing g:netrw_sort_by=".g:netrw_sort_by." (name)")
11124"    call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("<slnum>"))
11125    sil! NetrwKeepj put=pfile
11126   endif
11127"   call DechoBuf(bufnr("%"),"bufnr(%)")
11128  endfor
11129
11130  " cleanup any windows mess at end-of-line
11131  sil! NetrwKeepj g/^$/d
11132  sil! NetrwKeepj %s/\r$//e
11133  call histdel("/",-1)
11134"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
11135  exe "setl ts=".(g:netrw_maxfilenamelen+1)
11136
11137"  call Dret("s:LocalListing")
11138endfun
11139
11140" ---------------------------------------------------------------------
11141" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
11142fun! s:NetrwLocalExecute(cmd)
11143"  call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
11144  let ykeep= @@
11145  " sanity check
11146  if !executable(a:cmd)
11147   call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
11148   let @@= ykeep
11149"   call Dret("s:NetrwLocalExecute")
11150   return
11151  endif
11152
11153  let optargs= input(":!".a:cmd,"","file")
11154"  call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
11155  let result= system(a:cmd.optargs)
11156"  call Decho("result,'~'.expand("<slnum>"))
11157
11158  " strip any ansi escape sequences off
11159  let result = substitute(result,"\e\\[[0-9;]*m","","g")
11160
11161  " show user the result(s)
11162  echomsg result
11163  let @@= ykeep
11164
11165"  call Dret("s:NetrwLocalExecute")
11166endfun
11167
11168" ---------------------------------------------------------------------
11169" s:NetrwLocalRename: rename a local file or directory {{{2
11170fun! s:NetrwLocalRename(path) range
11171"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
11172
11173  " preparation for removing multiple files/directories
11174  let ykeep     = @@
11175  let ctr       = a:firstline
11176  let svpos     = winsaveview()
11177  let all       = 0
11178"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11179
11180  " rename files given by the markfilelist
11181  if exists("s:netrwmarkfilelist_{bufnr('%')}")
11182   for oldname in s:netrwmarkfilelist_{bufnr("%")}
11183"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
11184    if exists("subfrom")
11185     let newname= substitute(oldname,subfrom,subto,'')
11186"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
11187    else
11188     call inputsave()
11189     let newname= input("Moving ".oldname." to : ",oldname,"file")
11190     call inputrestore()
11191     if newname =~ ''
11192      " two ctrl-x's : ignore all of string preceding the ctrl-x's
11193      let newname = substitute(newname,'^.*','','')
11194     elseif newname =~ ''
11195      " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
11196      let newname = substitute(newname,'[^/]*','','')
11197     endif
11198     if newname =~ '^s/'
11199      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
11200      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
11201"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
11202      let newname = substitute(oldname,subfrom,subto,'')
11203     endif
11204    endif
11205    if !all && filereadable(newname)
11206     call inputsave()
11207      let response= input("File<".newname."> already exists; do you want to overwrite it? (y/all/n) ")
11208     call inputrestore()
11209     if response == "all"
11210      let all= 1
11211     elseif response != "y" && response != "yes"
11212      " refresh the directory
11213"      call Decho("refresh the directory listing",'~'.expand("<slnum>"))
11214      NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11215"      call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11216      NetrwKeepj call winrestview(svpos)
11217      let @@= ykeep
11218"      call Dret("NetrwLocalRename")
11219      return
11220     endif
11221    endif
11222    call rename(oldname,newname)
11223   endfor
11224   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
11225
11226  else
11227
11228   " attempt to rename files/directories
11229   while ctr <= a:lastline
11230    exe "NetrwKeepj ".ctr
11231
11232    " sanity checks
11233    if line(".") < w:netrw_bannercnt
11234     let ctr= ctr + 1
11235     continue
11236    endif
11237    let curword= s:NetrwGetWord()
11238    if curword == "./" || curword == "../"
11239     let ctr= ctr + 1
11240     continue
11241    endif
11242
11243    NetrwKeepj norm! 0
11244    let oldname= s:ComposePath(a:path,curword)
11245"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
11246
11247    call inputsave()
11248    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
11249    call inputrestore()
11250
11251    call rename(oldname,newname)
11252"    call Decho("renaming <".oldname."> to <".newname.">",'~'.expand("<slnum>"))
11253
11254    let ctr= ctr + 1
11255   endwhile
11256  endif
11257
11258  " refresh the directory
11259"  call Decho("refresh the directory listing",'~'.expand("<slnum>"))
11260  NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11261"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11262  NetrwKeepj call winrestview(svpos)
11263  let @@= ykeep
11264
11265"  call Dret("NetrwLocalRename")
11266endfun
11267
11268" ---------------------------------------------------------------------
11269" s:NetrwLocalRm: {{{2
11270fun! s:NetrwLocalRm(path) range
11271"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
11272"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
11273
11274  " preparation for removing multiple files/directories
11275  let ykeep = @@
11276  let ret   = 0
11277  let all   = 0
11278  let svpos = winsaveview()
11279"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11280
11281  if exists("s:netrwmarkfilelist_{bufnr('%')}")
11282   " remove all marked files
11283"   call Decho("remove all marked files",'~'.expand("<slnum>"))
11284   for fname in s:netrwmarkfilelist_{bufnr("%")}
11285    let ok= s:NetrwLocalRmFile(a:path,fname,all)
11286    if ok =~# 'q\%[uit]' || ok == "no"
11287     break
11288    elseif ok =~# 'a\%[ll]'
11289     let all= 1
11290    endif
11291   endfor
11292   call s:NetrwUnMarkFile(1)
11293
11294  else
11295  " remove (multiple) files and directories
11296"   call Decho("remove files in range [".a:firstline.",".a:lastline."]",'~'.expand("<slnum>"))
11297
11298   let keepsol= &l:sol
11299   setl nosol
11300   let ctr = a:firstline
11301   while ctr <= a:lastline
11302    exe "NetrwKeepj ".ctr
11303
11304    " sanity checks
11305    if line(".") < w:netrw_bannercnt
11306     let ctr= ctr + 1
11307     continue
11308    endif
11309    let curword= s:NetrwGetWord()
11310    if curword == "./" || curword == "../"
11311     let ctr= ctr + 1
11312     continue
11313    endif
11314    let ok= s:NetrwLocalRmFile(a:path,curword,all)
11315    if ok =~# 'q\%[uit]' || ok == "no"
11316     break
11317    elseif ok =~# 'a\%[ll]'
11318     let all= 1
11319    endif
11320    let ctr= ctr + 1
11321   endwhile
11322   let &l:sol= keepsol
11323  endif
11324
11325  " refresh the directory
11326"  call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>"))
11327  if bufname("%") != "NetrwMessage"
11328   NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11329"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11330   NetrwKeepj call winrestview(svpos)
11331  endif
11332  let @@= ykeep
11333
11334"  call Dret("s:NetrwLocalRm")
11335endfun
11336
11337" ---------------------------------------------------------------------
11338" s:NetrwLocalRmFile: remove file fname given the path {{{2
11339"                     Give confirmation prompt unless all==1
11340fun! s:NetrwLocalRmFile(path,fname,all)
11341"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
11342
11343  let all= a:all
11344  let ok = ""
11345  NetrwKeepj norm! 0
11346  let rmfile= s:NetrwFile(s:ComposePath(a:path,a:fname))
11347"  call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
11348
11349  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
11350   " attempt to remove file
11351"   call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
11352   if !all
11353    echohl Statement
11354    call inputsave()
11355    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11356    call inputrestore()
11357    echohl NONE
11358    if ok == ""
11359     let ok="no"
11360    endif
11361"    call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
11362    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11363"    call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
11364    if ok =~# 'a\%[ll]'
11365     let all= 1
11366    endif
11367   endif
11368
11369   if all || ok =~# 'y\%[es]' || ok == ""
11370    let ret= s:NetrwDelete(rmfile)
11371"    call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
11372   endif
11373
11374  else
11375   " attempt to remove directory
11376   if !all
11377    echohl Statement
11378    call inputsave()
11379    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11380    call inputrestore()
11381    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11382    if ok == ""
11383     let ok="no"
11384    endif
11385    if ok =~# 'a\%[ll]'
11386     let all= 1
11387    endif
11388   endif
11389   let rmfile= substitute(rmfile,'[\/]$','','e')
11390
11391   if all || ok =~# 'y\%[es]' || ok == ""
11392    if v:version < 704 || (v:version == 704 && !has("patch1107"))
11393" "    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>"))
11394     call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile))
11395" "    call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>"))
11396
11397     if v:shell_error != 0
11398" "     call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11399      let errcode= s:NetrwDelete(rmfile)
11400" "     call Decho("errcode=".errcode,'~'.expand("<slnum>"))
11401
11402      if errcode != 0
11403       if has("unix")
11404" "       call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11405	call system("rm ".s:ShellEscape(rmfile))
11406	if v:shell_error != 0 && !exists("g:netrw_quiet")
11407	 call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
11408	 let ok="no"
11409	endif
11410       elseif !exists("g:netrw_quiet")
11411	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
11412	let ok="no"
11413       endif
11414      endif
11415     endif
11416    else
11417     if delete(rmfile,"d")
11418      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
11419     endif
11420    endif
11421   endif
11422  endif
11423
11424"  call Dret("s:NetrwLocalRmFile ".ok)
11425  return ok
11426endfun
11427
11428" =====================================================================
11429" Support Functions: {{{1
11430
11431" ---------------------------------------------------------------------
11432" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
11433"   0: marked file list of current buffer
11434"   1: marked file target
11435fun! netrw#Access(ilist)
11436  if     a:ilist == 0
11437   if exists("s:netrwmarkfilelist_".bufnr('%'))
11438    return s:netrwmarkfilelist_{bufnr('%')}
11439   else
11440    return "no-list-buf#".bufnr('%')
11441   endif
11442  elseif a:ilist == 1
11443   return s:netrwmftgt
11444  endif
11445endfun
11446
11447" ---------------------------------------------------------------------
11448" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
11449fun! netrw#Call(funcname,...)
11450  return call("s:".a:funcname,a:000)
11451endfun
11452
11453" ---------------------------------------------------------------------
11454" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
11455"               I expect this function to be used in
11456"                 :PChkAssert netrw#Expose("netrwmarkfilelist")
11457"               for example.
11458fun! netrw#Expose(varname)
11459"   call Dfunc("netrw#Expose(varname<".a:varname.">)")
11460  if exists("s:".a:varname)
11461   exe "let retval= s:".a:varname
11462"   call Decho("retval=".retval,'~'.expand("<slnum>"))
11463   if exists("g:netrw_pchk")
11464"    call Decho("type(g:netrw_pchk=".g:netrw_pchk.")=".type(retval),'~'.expand("<slnum>"))
11465    if type(retval) == 3
11466     let retval = copy(retval)
11467     let i      = 0
11468     while i < len(retval)
11469      let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
11470      let i        = i + 1
11471     endwhile
11472    endif
11473"     call Dret("netrw#Expose ".string(retval)),'~'.expand("<slnum>"))
11474    return string(retval)
11475   else
11476"    call Decho("g:netrw_pchk doesn't exist",'~'.expand("<slnum>"))
11477   endif
11478  else
11479"   call Decho("s:".a:varname." doesn't exist",'~'.expand("<slnum>"))
11480   let retval= "n/a"
11481  endif
11482
11483"  call Dret("netrw#Expose ".string(retval))
11484  return retval
11485endfun
11486
11487" ---------------------------------------------------------------------
11488" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
11489fun! netrw#Modify(varname,newvalue)
11490"  call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
11491  exe "let s:".a:varname."= ".string(a:newvalue)
11492"  call Dret("netrw#Modify")
11493endfun
11494
11495" ---------------------------------------------------------------------
11496"  netrw#RFC2396: converts %xx into characters {{{2
11497fun! netrw#RFC2396(fname)
11498"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
11499  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
11500"  call Dret("netrw#RFC2396 ".fname)
11501  return fname
11502endfun
11503
11504" ---------------------------------------------------------------------
11505" netrw#UserMaps: supports user-specified maps {{{2
11506"                 see :help function()
11507"
11508"                 g:Netrw_UserMaps is a List with members such as:
11509"                       [[keymap sequence, function reference],...]
11510"
11511"                 The referenced function may return a string,
11512"                 	refresh : refresh the display
11513"                 	-other- : this string will be executed
11514"                 or it may return a List of strings.
11515"
11516"                 Each keymap-sequence will be set up with a nnoremap
11517"                 to invoke netrw#UserMaps(a:islocal).
11518"                 Related functions:
11519"                   netrw#Expose(varname)          -- see s:varname variables
11520"                   netrw#Modify(varname,newvalue) -- modify value of s:varname variable
11521"                   netrw#Call(funcname,...)       -- call internal netrw function with optional arguments
11522fun! netrw#UserMaps(islocal)
11523"  call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
11524"  call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
11525
11526   " set up usermaplist
11527   if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
11528"    call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
11529    for umap in g:Netrw_UserMaps
11530"     call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
11531"     call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
11532     " if umap[0] is a string and umap[1] is a string holding a function name
11533     if type(umap[0]) == 1 && type(umap[1]) == 1
11534"      call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
11535      exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
11536      else
11537       call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
11538     endif
11539    endfor
11540   endif
11541"  call Dret("netrw#UserMaps")
11542endfun
11543
11544" ---------------------------------------------------------------------
11545" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
11546fun! netrw#WinPath(path)
11547"  call Dfunc("netrw#WinPath(path<".a:path.">)")
11548  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
11549   " remove cygdrive prefix, if present
11550   let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
11551   " remove trailing slash (Win95)
11552   let path = substitute(path, '\(\\\|/\)$', '', 'g')
11553   " remove escaped spaces
11554   let path = substitute(path, '\ ', ' ', 'g')
11555   " convert slashes to backslashes
11556   let path = substitute(path, '/', '\', 'g')
11557  else
11558   let path= a:path
11559  endif
11560"  call Dret("netrw#WinPath <".path.">")
11561  return path
11562endfun
11563
11564" ---------------------------------------------------------------------
11565" s:NetrwBadd: adds marked files to buffer list or vice versa {{{2
11566"              cb : bl2mf=0  add marked files to buffer list
11567"              cB : bl2mf=1  use bufferlist to mark files
11568"              (mnemonic: cb = copy (marked files) to buffer list)
11569fun! s:NetrwBadd(islocal,bl2mf)
11570"  "  call Dfunc("s:NetrwBadd(islocal=".a:islocal." mf2bl=".mf2bl.")")
11571  if a:bl2mf
11572   " cB: add buffer list to marked files
11573   redir => bufl
11574    ls
11575   redir END
11576   let bufl = map(split(bufl,"\n"),'substitute(v:val,''^.\{-}"\(.*\)".\{-}$'',''\1'','''')')
11577   for fname in bufl
11578    call s:NetrwMarkFile(a:islocal,fname)
11579   endfor
11580  else
11581   " cb: add marked files to buffer list
11582   for fname in s:netrwmarkfilelist_{bufnr("%")}
11583" "   call Decho("badd ".fname,'~'.expand("<slnum>"))
11584    exe "badd ".fnameescape(fname)
11585   endfor
11586   let curbufnr = bufnr("%")
11587   let curdir   = s:NetrwGetCurdir(a:islocal)
11588   call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
11589  endif
11590"  call Dret("s:NetrwBadd")
11591endfun
11592
11593" ---------------------------------------------------------------------
11594"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
11595fun! s:ComposePath(base,subdir)
11596"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
11597
11598  if has("amiga")
11599"   call Decho("amiga",'~'.expand("<slnum>"))
11600   let ec = a:base[s:Strlen(a:base)-1]
11601   if ec != '/' && ec != ':'
11602    let ret = a:base."/" . a:subdir
11603   else
11604    let ret = a:base.a:subdir
11605   endif
11606
11607   " COMBAK: test on windows with changing to root directory: :e C:/
11608  elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11609"   call Decho("windows",'~'.expand("<slnum>"))
11610   let ret= a:subdir
11611
11612  elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11613"   call Decho("windows",'~'.expand("<slnum>"))
11614   if a:base =~ '[/\\]$'
11615    let ret= a:base.a:subdir
11616   else
11617    let ret= a:base.'/'.a:subdir
11618   endif
11619
11620  elseif a:base =~ '^\a\{3,}://'
11621"   call Decho("remote linux/macos",'~'.expand("<slnum>"))
11622   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
11623   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
11624   if a:subdir == '../'
11625    if curpath =~ '[^/]/[^/]\+/$'
11626     let curpath= substitute(curpath,'[^/]\+/$','','')
11627    else
11628     let curpath=""
11629    endif
11630    let ret= urlbase.curpath
11631   else
11632    let ret= urlbase.curpath.a:subdir
11633   endif
11634"   call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
11635"   call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
11636"   call Decho("ret<".ret.">",'~'.expand("<slnum>"))
11637
11638  else
11639"   call Decho("local linux/macos",'~'.expand("<slnum>"))
11640   let ret = substitute(a:base."/".a:subdir,"//","/","g")
11641   if a:base =~ '^//'
11642    " keeping initial '//' for the benefit of network share listing support
11643    let ret= '/'.ret
11644   endif
11645   let ret= simplify(ret)
11646  endif
11647
11648"  call Dret("s:ComposePath ".ret)
11649  return ret
11650endfun
11651
11652" ---------------------------------------------------------------------
11653" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
11654"   Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
11655fun! s:DeleteBookmark(fname)
11656"  call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
11657  call s:MergeBookmarks()
11658
11659  if exists("g:netrw_bookmarklist")
11660   let indx= index(g:netrw_bookmarklist,a:fname)
11661   if indx == -1
11662    let indx= 0
11663    while indx < len(g:netrw_bookmarklist)
11664     if g:netrw_bookmarklist[indx] =~ a:fname
11665      call remove(g:netrw_bookmarklist,indx)
11666      let indx= indx - 1
11667     endif
11668     let indx= indx + 1
11669    endwhile
11670   else
11671    " remove exact match
11672    call remove(g:netrw_bookmarklist,indx)
11673   endif
11674  endif
11675
11676"  call Dret("s:DeleteBookmark")
11677endfun
11678
11679" ---------------------------------------------------------------------
11680" s:FileReadable: o/s independent filereadable {{{2
11681fun! s:FileReadable(fname)
11682"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
11683
11684  if g:netrw_cygwin
11685   let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
11686  else
11687   let ret= filereadable(s:NetrwFile(a:fname))
11688  endif
11689
11690"  call Dret("s:FileReadable ".ret)
11691  return ret
11692endfun
11693
11694" ---------------------------------------------------------------------
11695"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
11696"                 Places correct suffix on end of temporary filename,
11697"                 using the suffix provided with fname
11698fun! s:GetTempfile(fname)
11699"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
11700
11701  if !exists("b:netrw_tmpfile")
11702   " get a brand new temporary filename
11703   let tmpfile= tempname()
11704"   call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
11705
11706   let tmpfile= substitute(tmpfile,'\','/','ge')
11707"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
11708
11709   " sanity check -- does the temporary file's directory exist?
11710   if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
11711"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11712    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
11713"    call Dret("s:GetTempfile getcwd<".getcwd().">")
11714    return ""
11715   endif
11716
11717   " let netrw#NetSource() know about the tmpfile
11718   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
11719"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
11720
11721   " o/s dependencies
11722   if g:netrw_cygwin != 0
11723    let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
11724   elseif has("win32") || has("win95") || has("win64") || has("win16")
11725    if !exists("+shellslash") || !&ssl
11726     let tmpfile = substitute(tmpfile,'/','\','g')
11727    endif
11728   else
11729    let tmpfile = tmpfile
11730   endif
11731   let b:netrw_tmpfile= tmpfile
11732"   call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
11733  else
11734   " re-use temporary filename
11735   let tmpfile= b:netrw_tmpfile
11736"   call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
11737  endif
11738
11739  " use fname's suffix for the temporary file
11740  if a:fname != ""
11741   if a:fname =~ '\.[^./]\+$'
11742"    call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11743    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11744     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11745    elseif a:fname =~ '.txz$'
11746     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11747    else
11748     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11749    endif
11750"    call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11751    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11752"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11753    let tmpfile .= suffix
11754"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11755    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
11756   endif
11757  endif
11758
11759"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11760"  call Dret("s:GetTempfile <".tmpfile.">")
11761  return tmpfile
11762endfun
11763
11764" ---------------------------------------------------------------------
11765" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
11766"               a correct command for use with a system() call
11767fun! s:MakeSshCmd(sshcmd)
11768"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
11769  if s:user == ""
11770   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
11771  else
11772   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
11773  endif
11774  if exists("g:netrw_port") && g:netrw_port != ""
11775   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
11776  elseif exists("s:port") && s:port != ""
11777   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
11778  else
11779   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
11780  endif
11781"  call Dret("s:MakeSshCmd <".sshcmd.">")
11782  return sshcmd
11783endfun
11784
11785" ---------------------------------------------------------------------
11786" s:MakeBookmark: enters a bookmark into Netrw's bookmark system   {{{2
11787fun! s:MakeBookmark(fname)
11788"  call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
11789
11790  if !exists("g:netrw_bookmarklist")
11791   let g:netrw_bookmarklist= []
11792  endif
11793
11794  if index(g:netrw_bookmarklist,a:fname) == -1
11795   " curdir not currently in g:netrw_bookmarklist, so include it
11796   if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11797    call add(g:netrw_bookmarklist,a:fname.'/')
11798   elseif a:fname !~ '/'
11799    call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11800   else
11801    call add(g:netrw_bookmarklist,a:fname)
11802   endif
11803   call sort(g:netrw_bookmarklist)
11804  endif
11805
11806"  call Dret("s:MakeBookmark")
11807endfun
11808
11809" ---------------------------------------------------------------------
11810" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11811fun! s:MergeBookmarks()
11812"  call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
11813  " get bookmarks from .netrwbook file
11814  let savefile= s:NetrwHome()."/.netrwbook"
11815  if filereadable(s:NetrwFile(savefile))
11816"   call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11817   NetrwKeepj call s:NetrwBookHistSave()
11818"   call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11819   NetrwKeepj call delete(savefile)
11820  endif
11821"  call Dret("s:MergeBookmarks")
11822endfun
11823
11824" ---------------------------------------------------------------------
11825" s:NetrwBMShow: {{{2
11826fun! s:NetrwBMShow()
11827"  call Dfunc("s:NetrwBMShow()")
11828  redir => bmshowraw
11829   menu
11830  redir END
11831  let bmshowlist = split(bmshowraw,'\n')
11832  if bmshowlist != []
11833   let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"')
11834   if bmshowfuncs != []
11835    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11836    if bmshowfunc =~# '^call.*BMShow()'
11837     exe "sil! NetrwKeepj ".bmshowfunc
11838    endif
11839   endif
11840  endif
11841"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
11842endfun
11843
11844" ---------------------------------------------------------------------
11845" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
11846fun! s:NetrwCursor(editfile)
11847  if !exists("w:netrw_liststyle")
11848   let w:netrw_liststyle= g:netrw_liststyle
11849  endif
11850"  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)
11851
11852"  call Decho("(s:NetrwCursor) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11853
11854  if &ft != "netrw"
11855   " if the current window isn't a netrw directory listing window, then use user cursorline/column
11856   " settings.  Affects when netrw is used to read/write a file using scp/ftp/etc.
11857"   call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
11858
11859  elseif g:netrw_cursor == 8
11860   if w:netrw_liststyle == s:WIDELIST
11861    setl cursorline
11862    setl cursorcolumn
11863   else
11864    setl cursorline
11865   endif
11866  elseif g:netrw_cursor == 7
11867    setl cursorline
11868  elseif g:netrw_cursor == 6
11869   if w:netrw_liststyle == s:WIDELIST
11870    setl cursorline
11871   endif
11872  elseif g:netrw_cursor == 4
11873   " all styles: cursorline, cursorcolumn
11874"   call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
11875   setl cursorline
11876   setl cursorcolumn
11877
11878  elseif g:netrw_cursor == 3
11879   " thin-long-tree: cursorline, user's cursorcolumn
11880   " wide          : cursorline, cursorcolumn
11881   if w:netrw_liststyle == s:WIDELIST
11882"    call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11883    setl cursorline
11884    setl cursorcolumn
11885   else
11886"    call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11887    setl cursorline
11888   endif
11889
11890  elseif g:netrw_cursor == 2
11891   " thin-long-tree: cursorline, user's cursorcolumn
11892   " wide          : cursorline, user's cursorcolumn
11893"   call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11894   setl cursorline
11895
11896  elseif g:netrw_cursor == 1
11897   " thin-long-tree: user's cursorline, user's cursorcolumn
11898   " wide          : cursorline,        user's cursorcolumn
11899   if w:netrw_liststyle == s:WIDELIST
11900"    call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11901    setl cursorline
11902   else
11903"    call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11904   endif
11905
11906  else
11907   " all styles: user's cursorline, user's cursorcolumn
11908"   call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11909   let &l:cursorline   = s:netrw_usercul
11910   let &l:cursorcolumn = s:netrw_usercuc
11911  endif
11912
11913" call Decho("(s:NetrwCursor) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11914"  call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
11915endfun
11916
11917" ---------------------------------------------------------------------
11918" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11919fun! s:RestoreCursorline()
11920"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
11921  if exists("s:netrw_usercul")
11922   let &l:cursorline   = s:netrw_usercul
11923  endif
11924  if exists("s:netrw_usercuc")
11925   let &l:cursorcolumn = s:netrw_usercuc
11926  endif
11927"  call Decho("(s:RestoreCursorline) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11928"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
11929endfun
11930
11931" ---------------------------------------------------------------------
11932" s:NetrwDelete: Deletes a file. {{{2
11933"           Uses Steve Hall's idea to insure that Windows paths stay
11934"           acceptable.  No effect on Unix paths.
11935"  Examples of use:  let result= s:NetrwDelete(path)
11936fun! s:NetrwDelete(path)
11937"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
11938
11939  let path = netrw#WinPath(a:path)
11940  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
11941   if exists("+shellslash")
11942    let sskeep= &shellslash
11943    setl noshellslash
11944    let result      = delete(path)
11945    let &shellslash = sskeep
11946   else
11947"    call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11948    let result= delete(path)
11949   endif
11950  else
11951"   call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11952   let result= delete(path)
11953  endif
11954  if result < 0
11955   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
11956  endif
11957
11958"  call Dret("s:NetrwDelete ".result)
11959  return result
11960endfun
11961
11962" ---------------------------------------------------------------------
11963" s:NetrwBufRemover: removes a buffer that: {{{2s
11964"                    has buffer-id > 1
11965"                    is unlisted
11966"                    is unnamed
11967"                    does not appear in any window
11968fun! s:NetrwBufRemover(bufid)
11969"  call Dfunc("s:NetrwBufRemover(".a:bufid.")")
11970"  call Decho("buf#".a:bufid."           ".((a:bufid > 1)? ">" : "≯")." must be >1 for removal","~".expand("<slnum>"))
11971"  call Decho("buf#".a:bufid." is        ".(buflisted(a:bufid)? "listed" : "unlisted"),"~".expand("<slnum>"))
11972"  call Decho("buf#".a:bufid." has name <".bufname(a:bufid).">","~".expand("<slnum>"))
11973"  call Decho("buf#".a:bufid." has winid#".bufwinid(a:bufid),"~".expand("<slnum>"))
11974
11975  if a:bufid > 1 && !buflisted(a:bufid) && bufname(a:bufid) == "" && bufwinid(a:bufid) == -1
11976"   call Decho("(s:NetrwBufRemover) removing buffer#".a:bufid,"~".expand("<slnum>"))
11977   exe "bd! ".a:bufid
11978  endif
11979
11980"  call Dret("s:NetrwBufRemover")
11981endfun
11982
11983" ---------------------------------------------------------------------
11984" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
11985fun! s:NetrwEnew(...)
11986"  call Dfunc("s:NetrwEnew() a:0=".a:0." win#".winnr()." winnr($)=".winnr("$")." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
11987"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
11988
11989  " Clean out the last buffer:
11990  " Check if the last buffer has # > 1, is unlisted, is unnamed, and does not appear in a window
11991  " If so, delete it.
11992  call s:NetrwBufRemover(bufnr("$"))
11993
11994  " grab a function-local-variable copy of buffer variables
11995"  call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
11996  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
11997  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
11998  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
11999  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
12000  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
12001  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
12002  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
12003  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
12004  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
12005  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
12006  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
12007  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
12008  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
12009  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
12010  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
12011  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
12012
12013  NetrwKeepj call s:NetrwOptionsRestore("w:")
12014"  call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>"))
12015  " when tree listing uses file TreeListing... a new buffer is made.
12016  " Want the old buffer to be unlisted.
12017  " COMBAK: this causes a problem, see P43
12018"  setl nobl
12019  let netrw_keepdiff= &l:diff
12020  noswapfile NetrwKeepj keepalt enew!
12021  let &l:diff= netrw_keepdiff
12022"  call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
12023  NetrwKeepj call s:NetrwOptionsSave("w:")
12024
12025  " copy function-local-variables to buffer variable equivalents
12026"  call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
12027  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
12028  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
12029  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
12030  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
12031  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
12032  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
12033  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
12034  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
12035  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
12036  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
12037  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
12038  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
12039  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
12040  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
12041  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
12042  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
12043
12044  if a:0 > 0
12045   let b:netrw_curdir= a:1
12046   if b:netrw_curdir =~ '/$'
12047    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
12048     setl nobl
12049     file NetrwTreeListing
12050     setl nobl bt=nowrite bh=hide
12051     nno <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
12052     nno <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
12053    else
12054     call s:NetrwBufRename(b:netrw_curdir)
12055    endif
12056   endif
12057  endif
12058  if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
12059   let &l:bexpr = "netrw#BalloonHelp()"
12060  endif
12061
12062"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
12063endfun
12064
12065" ---------------------------------------------------------------------
12066" s:NetrwExe: executes a string using "!" {{{2
12067fun! s:NetrwExe(cmd)
12068"  call Dfunc("s:NetrwExe(a:cmd<".a:cmd.">)")
12069  if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin
12070"    call Decho("using win32:",expand("<slnum>"))
12071    let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
12072    set shell& shellcmdflag& shellxquote& shellxescape&
12073    set shellquote& shellpipe& shellredir& shellslash&
12074    exe a:cmd
12075    let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
12076  else
12077"   call Decho("exe ".a:cmd,'~'.expand("<slnum>"))
12078   exe a:cmd
12079  endif
12080  if v:shell_error
12081   call netrw#ErrorMsg(s:WARNING,"shell signalled an error",106)
12082  endif
12083"  call Dret("s:NetrwExe : v:shell_error=".v:shell_error)
12084endfun
12085
12086" ---------------------------------------------------------------------
12087" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
12088fun! s:NetrwInsureWinVars()
12089  if !exists("w:netrw_liststyle")
12090"   call Dfunc("s:NetrwInsureWinVars() win#".winnr())
12091   let curbuf = bufnr("%")
12092   let curwin = winnr()
12093   let iwin   = 1
12094   while iwin <= winnr("$")
12095    exe iwin."wincmd w"
12096    if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
12097     " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
12098     let winvars= w:
12099     break
12100    endif
12101    let iwin= iwin + 1
12102   endwhile
12103   exe "keepalt ".curwin."wincmd w"
12104   if exists("winvars")
12105"    call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
12106    for k in keys(winvars)
12107     let w:{k}= winvars[k]
12108    endfor
12109   endif
12110"   call Dret("s:NetrwInsureWinVars win#".winnr())
12111  endif
12112endfun
12113
12114" ---------------------------------------------------------------------
12115" s:NetrwLcd: handles changing the (local) directory {{{2
12116"   Returns: 0=success
12117"           -1=failed
12118fun! s:NetrwLcd(newdir)
12119"  call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
12120"  call Decho("changing local directory",'~'.expand("<slnum>"))
12121
12122  let err472= 0
12123  try
12124   exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
12125  catch /^Vim\%((\a\+)\)\=:E344/
12126     " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
12127     " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
12128     " 'root' (ie. '\').  The share name may start with either backslashes ('\\Foo') or
12129     " forward slashes ('//Foo'), depending on whether backslashes have been converted to
12130     " forward slashes by earlier code; so check for both.
12131     if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
12132       if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
12133         let dirname = '\'
12134	 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
12135       endif
12136     endif
12137  catch /^Vim\%((\a\+)\)\=:E472/
12138   let err472= 1
12139  endtry
12140
12141  if err472
12142   call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
12143   if exists("w:netrw_prvdir")
12144    let a:newdir= w:netrw_prvdir
12145   else
12146    call s:NetrwOptionsRestore("w:")
12147"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
12148    exe "setl ".g:netrw_bufsettings
12149"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
12150    let a:newdir= dirname
12151   endif
12152"   call Dret("s:NetrwBrowse -1 : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
12153   return -1
12154  endif
12155
12156"  call Decho("getcwd        <".getcwd().">")
12157"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
12158"  call Dret("s:NetrwLcd 0")
12159  return 0
12160endfun
12161
12162" ------------------------------------------------------------------------
12163" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
12164" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
12165fun! s:NetrwSaveWordPosn()
12166"  call Dfunc("NetrwSaveWordPosn()")
12167  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
12168"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
12169endfun
12170
12171" ---------------------------------------------------------------------
12172" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
12173"                       1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
12174fun! s:NetrwHumanReadable(sz)
12175"  call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
12176
12177  if g:netrw_sizestyle == 'h'
12178   if a:sz >= 1000000000
12179    let sz = printf("%.1f",a:sz/1000000000.0)."g"
12180   elseif a:sz >= 10000000
12181    let sz = printf("%d",a:sz/1000000)."m"
12182   elseif a:sz >= 1000000
12183    let sz = printf("%.1f",a:sz/1000000.0)."m"
12184   elseif a:sz >= 10000
12185    let sz = printf("%d",a:sz/1000)."k"
12186   elseif a:sz >= 1000
12187    let sz = printf("%.1f",a:sz/1000.0)."k"
12188   else
12189    let sz= a:sz
12190   endif
12191
12192  elseif g:netrw_sizestyle == 'H'
12193   if a:sz >= 1073741824
12194    let sz = printf("%.1f",a:sz/1073741824.0)."G"
12195   elseif a:sz >= 10485760
12196    let sz = printf("%d",a:sz/1048576)."M"
12197   elseif a:sz >= 1048576
12198    let sz = printf("%.1f",a:sz/1048576.0)."M"
12199   elseif a:sz >= 10240
12200    let sz = printf("%d",a:sz/1024)."K"
12201   elseif a:sz >= 1024
12202    let sz = printf("%.1f",a:sz/1024.0)."K"
12203   else
12204    let sz= a:sz
12205   endif
12206
12207  else
12208   let sz= a:sz
12209  endif
12210
12211"  call Dret("s:NetrwHumanReadable ".sz)
12212  return sz
12213endfun
12214
12215" ---------------------------------------------------------------------
12216" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
12217"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
12218fun! s:NetrwRestoreWordPosn()
12219"  call Dfunc("NetrwRestoreWordPosn()")
12220  sil! call search(s:netrw_saveword,'w')
12221"  call Dret("NetrwRestoreWordPosn")
12222endfun
12223
12224" ---------------------------------------------------------------------
12225" s:RestoreBufVars: {{{2
12226fun! s:RestoreBufVars()
12227"  call Dfunc("s:RestoreBufVars()")
12228
12229  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
12230  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
12231  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
12232  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
12233  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
12234  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
12235
12236"  call Dret("s:RestoreBufVars")
12237endfun
12238
12239" ---------------------------------------------------------------------
12240" s:RemotePathAnalysis: {{{2
12241fun! s:RemotePathAnalysis(dirname)
12242"  call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
12243
12244  "                method   ://    user  @      machine      :port            /path
12245  let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
12246  let s:method  = substitute(a:dirname,dirpat,'\1','')
12247  let s:user    = substitute(a:dirname,dirpat,'\3','')
12248  let s:machine = substitute(a:dirname,dirpat,'\4','')
12249  let s:port    = substitute(a:dirname,dirpat,'\5','')
12250  let s:path    = substitute(a:dirname,dirpat,'\6','')
12251  let s:fname   = substitute(s:path,'^.*/\ze.','','')
12252  if s:machine =~ '@'
12253   let dirpat    = '^\(.*\)@\(.\{-}\)$'
12254   let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')
12255   let s:machine = substitute(s:machine,dirpat,'\2','')
12256  endif
12257
12258"  call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
12259"  call Decho("set up s:user   <".s:user   .">",'~'.expand("<slnum>"))
12260"  call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
12261"  call Decho("set up s:port   <".s:port.">",'~'.expand("<slnum>"))
12262"  call Decho("set up s:path   <".s:path   .">",'~'.expand("<slnum>"))
12263"  call Decho("set up s:fname  <".s:fname  .">",'~'.expand("<slnum>"))
12264
12265"  call Dret("s:RemotePathAnalysis")
12266endfun
12267
12268" ---------------------------------------------------------------------
12269" s:RemoteSystem: runs a command on a remote host using ssh {{{2
12270"                 Returns status
12271" Runs system() on
12272"    [cd REMOTEDIRPATH;] a:cmd
12273" Note that it doesn't do s:ShellEscape(a:cmd)!
12274fun! s:RemoteSystem(cmd)
12275"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
12276  if !executable(g:netrw_ssh_cmd)
12277   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
12278  elseif !exists("b:netrw_curdir")
12279   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
12280  else
12281   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
12282   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
12283   if remotedir != ""
12284    let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
12285   else
12286    let cmd= cmd.' '
12287   endif
12288   let cmd= cmd.a:cmd
12289"   call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
12290   let ret= system(cmd)
12291  endif
12292"  call Dret("s:RemoteSystem ".ret)
12293  return ret
12294endfun
12295
12296" ---------------------------------------------------------------------
12297" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
12298fun! s:RestoreWinVars()
12299"  call Dfunc("s:RestoreWinVars()")
12300  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
12301  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
12302  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
12303  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
12304  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
12305  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
12306  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
12307  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
12308  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
12309  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
12310  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
12311  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
12312  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
12313  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
12314  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
12315  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
12316  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
12317  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
12318"  call Dret("s:RestoreWinVars")
12319endfun
12320
12321" ---------------------------------------------------------------------
12322" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
12323"
12324"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
12325"             is true) and a command, :Rexplore, which call this function.
12326"
12327"             s:netrw_posn is set up by s:NetrwBrowseChgDir()
12328"
12329"             s:rexposn_BUFNR used to save/restore cursor position
12330fun! s:NetrwRexplore(islocal,dirname)
12331  if exists("s:netrwdrag")
12332   return
12333  endif
12334"  call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
12335"  call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
12336"  call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
12337
12338  if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
12339   " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
12340"   call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
12341   exe "NetrwKeepj e ".w:netrw_rexfile
12342   unlet w:netrw_rexfile
12343"   call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%").">  (ft=".&ft.")")
12344   return
12345"  else " Decho
12346"   call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
12347"   call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
12348  endif
12349
12350  " ---------------------------
12351  " :Rex issued while in a file
12352  " ---------------------------
12353
12354  " record current file so :Rex can return to it from netrw
12355  let w:netrw_rexfile= expand("%")
12356"  call Decho("set w:netrw_rexfile<".w:netrw_rexfile.">  (win#".winnr().")",'~'.expand("<slnum>"))
12357
12358  if !exists("w:netrw_rexlocal")
12359"   call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
12360   return
12361  endif
12362"  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>"))
12363  if w:netrw_rexlocal
12364   NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
12365  else
12366   NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
12367  endif
12368  if exists("s:initbeval")
12369   setl beval
12370  endif
12371  if exists("s:rexposn_".bufnr("%"))
12372"   call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
12373   " restore position in directory listing
12374"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
12375   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
12376   if exists("s:rexposn_".bufnr('%'))
12377    unlet s:rexposn_{bufnr('%')}
12378   endif
12379  else
12380"   call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
12381  endif
12382
12383  if has("syntax") && exists("g:syntax_on") && g:syntax_on
12384   if exists("s:explore_match")
12385    exe "2match netrwMarkFile /".s:explore_match."/"
12386   endif
12387  endif
12388
12389"  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>"))
12390"  call Dret("s:NetrwRexplore : ft=".&ft)
12391endfun
12392
12393" ---------------------------------------------------------------------
12394" s:SaveBufVars: save selected b: variables to s: variables {{{2
12395"                use s:RestoreBufVars() to restore b: variables from s: variables
12396fun! s:SaveBufVars()
12397"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
12398
12399  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
12400  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
12401  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
12402  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
12403  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
12404  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
12405
12406"  call Dret("s:SaveBufVars")
12407endfun
12408
12409" ---------------------------------------------------------------------
12410" s:SavePosn: saves position associated with current buffer into a dictionary {{{2
12411fun! s:SavePosn(posndict)
12412"  call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12413
12414  if !exists("a:posndict[bufnr('%')]")
12415   let a:posndict[bufnr("%")]= []
12416  endif
12417"  call Decho("before push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12418  call add(a:posndict[bufnr("%")],winsaveview())
12419"  call Decho("after  push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12420
12421"  call Dret("s:SavePosn posndict")
12422  return a:posndict
12423endfun
12424
12425" ---------------------------------------------------------------------
12426" s:RestorePosn: restores position associated with current buffer using dictionary {{{2
12427fun! s:RestorePosn(posndict)
12428"  call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12429  if exists("a:posndict")
12430   if has_key(a:posndict,bufnr("%"))
12431"    call Decho("before pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12432    let posnlen= len(a:posndict[bufnr("%")])
12433    if posnlen > 0
12434     let posnlen= posnlen - 1
12435"     call Decho("restoring posn posndict[".bufnr("%")."][".posnlen."]=".string(a:posndict[bufnr("%")][posnlen]),'~'.expand("<slnum>"))
12436     call winrestview(a:posndict[bufnr("%")][posnlen])
12437     call remove(a:posndict[bufnr("%")],posnlen)
12438"     call Decho("after  pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12439    endif
12440   endif
12441  endif
12442"  call Dret("s:RestorePosn")
12443endfun
12444
12445" ---------------------------------------------------------------------
12446" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
12447fun! s:SaveWinVars()
12448"  call Dfunc("s:SaveWinVars() win#".winnr())
12449  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
12450  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
12451  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
12452  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
12453  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
12454  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
12455  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
12456  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
12457  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
12458  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
12459  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
12460  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
12461  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
12462  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
12463  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
12464  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
12465  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
12466  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
12467"  call Dret("s:SaveWinVars")
12468endfun
12469
12470" ---------------------------------------------------------------------
12471" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
12472"   To allow separate windows to have their own activities, such as
12473"   Explore **/pattern, several variables have been made window-oriented.
12474"   However, when the user splits a browser window (ex: ctrl-w s), these
12475"   variables are not inherited by the new window.  SetBufWinVars() and
12476"   UseBufWinVars() get around that.
12477fun! s:SetBufWinVars()
12478"  call Dfunc("s:SetBufWinVars() win#".winnr())
12479  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
12480  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
12481  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
12482  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
12483  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
12484  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
12485  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
12486  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
12487  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
12488  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
12489"  call Dret("s:SetBufWinVars")
12490endfun
12491
12492" ---------------------------------------------------------------------
12493" s:SetRexDir: set directory for :Rexplore {{{2
12494fun! s:SetRexDir(islocal,dirname)
12495"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
12496  let w:netrw_rexdir         = a:dirname
12497  let w:netrw_rexlocal       = a:islocal
12498  let s:rexposn_{bufnr("%")} = winsaveview()
12499"  call Decho("setting w:netrw_rexdir  =".w:netrw_rexdir,'~'.expand("<slnum>"))
12500"  call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>"))
12501"  call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
12502"  call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>"))
12503"  call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
12504endfun
12505
12506" ---------------------------------------------------------------------
12507" s:ShowLink: used to modify thin and tree listings to show links {{{2
12508fun! s:ShowLink()
12509" "  call Dfunc("s:ShowLink()")
12510" "  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
12511" "  call Decho(printf("line#%4d: %s",line("."),getline(".")),'~'.expand("<slnum>"))
12512  if exists("b:netrw_curdir")
12513   norm! $?\a
12514   let fname   = b:netrw_curdir.'/'.s:NetrwGetWord()
12515   let resname = resolve(fname)
12516" "   call Decho("fname         <".fname.">",'~'.expand("<slnum>"))
12517" "   call Decho("resname       <".resname.">",'~'.expand("<slnum>"))
12518" "   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
12519   if resname =~ '^\M'.b:netrw_curdir.'/'
12520    let dirlen  = strlen(b:netrw_curdir)
12521    let resname = strpart(resname,dirlen+1)
12522" "    call Decho("resname<".resname.">  (b:netrw_curdir elided)",'~'.expand("<slnum>"))
12523   endif
12524   let modline = getline(".")."\t --> ".resname
12525" "   call Decho("fname  <".fname.">",'~'.expand("<slnum>"))
12526" "   call Decho("modline<".modline.">",'~'.expand("<slnum>"))
12527   setl noro ma
12528   call setline(".",modline)
12529   setl ro noma nomod
12530  endif
12531" "  call Dret("s:ShowLink".((exists("fname")? ' : '.fname : 'n/a')))
12532endfun
12533
12534" ---------------------------------------------------------------------
12535" s:ShowStyle: {{{2
12536fun! s:ShowStyle()
12537  if !exists("w:netrw_liststyle")
12538   let liststyle= g:netrw_liststyle
12539  else
12540   let liststyle= w:netrw_liststyle
12541  endif
12542  if     liststyle == s:THINLIST
12543   return s:THINLIST.":thin"
12544  elseif liststyle == s:LONGLIST
12545   return s:LONGLIST.":long"
12546  elseif liststyle == s:WIDELIST
12547   return s:WIDELIST.":wide"
12548  elseif liststyle == s:TREELIST
12549   return s:TREELIST.":tree"
12550  else
12551   return 'n/a'
12552  endif
12553endfun
12554
12555" ---------------------------------------------------------------------
12556" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
12557"           Solution from Nicolai Weibull, vim docs (:help strlen()),
12558"           Tony Mechelynck, and my own invention.
12559fun! s:Strlen(x)
12560"  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
12561
12562  if v:version >= 703 && exists("*strdisplaywidth")
12563   let ret= strdisplaywidth(a:x)
12564
12565  elseif type(g:Align_xstrlen) == 1
12566   " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
12567   exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
12568
12569  elseif g:Align_xstrlen == 1
12570   " number of codepoints (Latin a + combining circumflex is two codepoints)
12571   " (comment from TM, solution from NW)
12572   let ret= strlen(substitute(a:x,'.','c','g'))
12573
12574  elseif g:Align_xstrlen == 2
12575   " number of spacing codepoints (Latin a + combining circumflex is one spacing
12576   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
12577   " (comment from TM, solution from TM)
12578   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
12579
12580  elseif g:Align_xstrlen == 3
12581   " virtual length (counting, for instance, tabs as anything between 1 and
12582   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
12583   " preceded by lam, one otherwise, etc.)
12584   " (comment from TM, solution from me)
12585   let modkeep= &l:mod
12586   exe "norm! o\<esc>"
12587   call setline(line("."),a:x)
12588   let ret= virtcol("$") - 1
12589   d
12590   NetrwKeepj norm! k
12591   let &l:mod= modkeep
12592
12593  else
12594   " at least give a decent default
12595    let ret= strlen(a:x)
12596  endif
12597"  "" call Dret("s:Strlen ".ret)
12598  return ret
12599endfun
12600
12601" ---------------------------------------------------------------------
12602" s:ShellEscape: shellescape(), or special windows handling {{{2
12603fun! s:ShellEscape(s, ...)
12604  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
12605    return printf('"%s"', substitute(a:s, '"', '""', 'g'))
12606  endif
12607  let f = a:0 > 0 ? a:1 : 0
12608  return shellescape(a:s, f)
12609endfun
12610
12611" ---------------------------------------------------------------------
12612" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
12613fun! s:TreeListMove(dir)
12614"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
12615  let curline      = getline('.')
12616  let prvline      = (line(".") > 1)?         getline(line(".")-1) : ''
12617  let nxtline      = (line(".") < line("$"))? getline(line(".")+1) : ''
12618  let curindent    = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
12619  let indentm1     = substitute(curindent,'^'.s:treedepthstring,'','')
12620  let treedepthchr = substitute(s:treedepthstring,' ','','g')
12621  let stopline     = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
12622"  call Decho("prvline  <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
12623"  call Decho("curline  <".curline."> #".line(".")    , '~'.expand("<slnum>"))
12624"  call Decho("nxtline  <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
12625"  call Decho("curindent<".curindent.">"              , '~'.expand("<slnum>"))
12626"  call Decho("indentm1 <".indentm1.">"               , '~'.expand("<slnum>"))
12627  "  COMBAK : need to handle when on a directory
12628  "  COMBAK : need to handle ]] and ][.  In general, needs work!!!
12629  if curline !~ '/$'
12630   if     a:dir == '[[' && prvline != ''
12631    NetrwKeepj norm! 0
12632    let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
12633"    call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
12634   elseif a:dir == '[]' && nxtline != ''
12635    NetrwKeepj norm! 0
12636"    call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>"))
12637    let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
12638    if nl != 0
12639     NetrwKeepj norm! k
12640    else
12641     NetrwKeepj norm! G
12642    endif
12643"    call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
12644   endif
12645  endif
12646
12647"  call Dret("s:TreeListMove")
12648endfun
12649
12650" ---------------------------------------------------------------------
12651" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
12652"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
12653"                      can't be called except via emenu.  But due to locale, that menu line may not be called
12654"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
12655fun! s:UpdateBuffersMenu()
12656"  call Dfunc("s:UpdateBuffersMenu()")
12657  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
12658   try
12659    sil emenu Buffers.Refresh\ menu
12660   catch /^Vim\%((\a\+)\)\=:E/
12661    let v:errmsg= ""
12662    sil NetrwKeepj call s:NetrwBMShow()
12663   endtry
12664  endif
12665"  call Dret("s:UpdateBuffersMenu")
12666endfun
12667
12668" ---------------------------------------------------------------------
12669" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
12670"              Matching function to s:SetBufWinVars()
12671fun! s:UseBufWinVars()
12672"  call Dfunc("s:UseBufWinVars()")
12673  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
12674  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
12675  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
12676  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
12677  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
12678  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
12679  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
12680  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
12681  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
12682  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
12683"  call Dret("s:UseBufWinVars")
12684endfun
12685
12686" ---------------------------------------------------------------------
12687" s:UserMaps: supports user-defined UserMaps {{{2
12688"               * calls a user-supplied funcref(islocal,curdir)
12689"               * interprets result
12690"             See netrw#UserMaps()
12691fun! s:UserMaps(islocal,funcname)
12692"  call Dfunc("s:UserMaps(islocal=".a:islocal.",funcname<".a:funcname.">)")
12693
12694  if !exists("b:netrw_curdir")
12695   let b:netrw_curdir= getcwd()
12696  endif
12697  let Funcref = function(a:funcname)
12698  let result  = Funcref(a:islocal)
12699
12700  if     type(result) == 1
12701   " if result from user's funcref is a string...
12702"   call Decho("result string from user funcref<".result.">",'~'.expand("<slnum>"))
12703   if result == "refresh"
12704"    call Decho("refreshing display",'~'.expand("<slnum>"))
12705    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12706   elseif result != ""
12707"    call Decho("executing result<".result.">",'~'.expand("<slnum>"))
12708    exe result
12709   endif
12710
12711  elseif type(result) == 3
12712   " if result from user's funcref is a List...
12713"   call Decho("result List from user funcref<".string(result).">",'~'.expand("<slnum>"))
12714   for action in result
12715    if action == "refresh"
12716"     call Decho("refreshing display",'~'.expand("<slnum>"))
12717     call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12718    elseif action != ""
12719"     call Decho("executing action<".action.">",'~'.expand("<slnum>"))
12720     exe action
12721    endif
12722   endfor
12723  endif
12724
12725"  call Dret("s:UserMaps")
12726endfun
12727
12728" ==========================
12729" Settings Restoration: {{{1
12730" ==========================
12731let &cpo= s:keepcpo
12732unlet s:keepcpo
12733
12734" ===============
12735" Modelines: {{{1
12736" ===============
12737" vim:ts=8 fdm=marker
12738