xref: /vim-8.2.3635/runtime/autoload/netrw.vim (revision ea2d8d25)
1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		Jan 07, 2020
4" Version:	168
5" Maintainer:	Charles E Campbell <[email protected]>
6" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
7" Copyright:    Copyright (C) 2016 Charles E. Campbell {{{1
8"               Permission is hereby granted to use and distribute this code,
9"               with or without modifications, provided that this copyright
10"               notice is copied with it. Like anything else that's free,
11"               netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
12"               *as is* and come with no warranty of any kind, either
13"               expressed or implied. By using this plugin, you agree that
14"               in no event will the copyright holder be liable for any damages
15"               resulting from the use of this software.
16"
17" Note: the code here was started in 1999 under a much earlier version of vim.  The directory browsing
18"       code was written using vim v6, which did not have Lists (Lists were first offered with vim-v7).
19"
20"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
21"
22"  But be doers of the Word, and not only hearers, deluding your own selves {{{1
23"  (James 1:22 RSV)
24" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
25" Load Once: {{{1
26if &cp || exists("g:loaded_netrw")
27  finish
28endif
29
30" Check that vim has patches that netrw requires.
31" Patches needed for v7.4: 1557, and 213.
32" (netrw will benefit from vim's having patch#656, too)
33let s:needspatches=[1557,213]
34if exists("s:needspatches")
35 for ptch in s:needspatches
36  if v:version < 704 || (v:version == 704 && !has("patch".ptch))
37   if !exists("s:needpatch{ptch}")
38    unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch#".ptch
39   endif
40   let s:needpatch{ptch}= 1
41   finish
42  endif
43 endfor
44endif
45
46let g:loaded_netrw = "v168"
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
90   " (default) netrw creates a one-line window to show error/warning
91   " messages (reliably displayed)
92
93   " record current window number
94   let s:winBeforeErr= winnr()
95"   call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>"))
96
97   " getting messages out reliably is just plain difficult!
98   " This attempt splits the current window, creating a one line window.
99   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
100"    call Decho("write to NetrwMessage buffer",'~'.expand("<slnum>"))
101    exe bufwinnr("NetrwMessage")."wincmd w"
102"    call Decho("setl ma noro",'~'.expand("<slnum>"))
103    setl ma noro
104    if type(a:msg) == 3
105     for msg in a:msg
106      NetrwKeepj call setline(line("$")+1,level.msg)
107     endfor
108    else
109     NetrwKeepj call setline(line("$")+1,level.a:msg)
110    endif
111    NetrwKeepj $
112   else
113"    call Decho("create a NetrwMessage buffer window",'~'.expand("<slnum>"))
114    bo 1split
115    sil! call s:NetrwEnew()
116    sil! NetrwKeepj call s:NetrwOptionsSafe(1)
117    setl bt=nofile
118    NetrwKeepj file NetrwMessage
119"    call Decho("setl ma noro",'~'.expand("<slnum>"))
120    setl ma noro
121    if type(a:msg) == 3
122     for msg in a:msg
123      NetrwKeepj call setline(line("$")+1,level.msg)
124     endfor
125    else
126     NetrwKeepj call setline(line("$"),level.a:msg)
127    endif
128    NetrwKeepj $
129   endif
130"   call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr(),'~'.expand("<slnum>"))
131   if &fo !~ '[ta]'
132    syn clear
133    syn match netrwMesgNote	"^\*\*note\*\*"
134    syn match netrwMesgWarning	"^\*\*warning\*\*"
135    syn match netrwMesgError	"^\*\*error\*\*"
136    hi link netrwMesgWarning WarningMsg
137    hi link netrwMesgError   Error
138   endif
139"   call Decho("setl noma ro bh=wipe",'~'.expand("<slnum>"))
140   setl ro nomod noma bh=wipe
141
142  else
143   " (optional) netrw will show messages using echomsg.  Even if the
144   " message doesn't appear, at least it'll be recallable via :messages
145"   redraw!
146   if a:level == s:WARNING
147    echohl WarningMsg
148   elseif a:level == s:ERROR
149    echohl Error
150   endif
151
152   if type(a:msg) == 3
153     for msg in a:msg
154      unsilent echomsg level.msg
155     endfor
156   else
157    unsilent echomsg level.a:msg
158   endif
159
160"   call Decho("echomsg ***netrw*** ".a:msg,'~'.expand("<slnum>"))
161   echohl None
162  endif
163
164"  call Dret("netrw#ErrorMsg")
165endfun
166
167" ---------------------------------------------------------------------
168" s:NetrwInit: initializes variables if they haven't been defined {{{2
169"            Loosely,  varname = value.
170fun s:NetrwInit(varname,value)
171" call Decho("varname<".a:varname."> value=".a:value,'~'.expand("<slnum>"))
172  if !exists(a:varname)
173   if type(a:value) == 0
174    exe "let ".a:varname."=".a:value
175   elseif type(a:value) == 1 && a:value =~ '^[{[]'
176    exe "let ".a:varname."=".a:value
177   elseif type(a:value) == 1
178    exe "let ".a:varname."="."'".a:value."'"
179   else
180    exe "let ".a:varname."=".a:value
181   endif
182  endif
183endfun
184
185" ---------------------------------------------------------------------
186"  Netrw Constants: {{{2
187call s:NetrwInit("g:netrw_dirhistcnt",0)
188if !exists("s:LONGLIST")
189 call s:NetrwInit("s:THINLIST",0)
190 call s:NetrwInit("s:LONGLIST",1)
191 call s:NetrwInit("s:WIDELIST",2)
192 call s:NetrwInit("s:TREELIST",3)
193 call s:NetrwInit("s:MAXLIST" ,4)
194endif
195
196" ---------------------------------------------------------------------
197" Default option values: {{{2
198let g:netrw_localcopycmdopt    = ""
199let g:netrw_localcopydircmdopt = ""
200let g:netrw_localmkdiropt      = ""
201let g:netrw_localmovecmdopt    = ""
202let g:netrw_localrmdiropt      = ""
203
204" ---------------------------------------------------------------------
205" Default values for netrw's global protocol variables {{{2
206call s:NetrwInit("g:netrw_use_errorwindow",1)
207
208if !exists("g:netrw_dav_cmd")
209 if executable("cadaver")
210  let g:netrw_dav_cmd	= "cadaver"
211 elseif executable("curl")
212  let g:netrw_dav_cmd	= "curl"
213 else
214  let g:netrw_dav_cmd   = ""
215 endif
216endif
217if !exists("g:netrw_fetch_cmd")
218 if executable("fetch")
219  let g:netrw_fetch_cmd	= "fetch -o"
220 else
221  let g:netrw_fetch_cmd	= ""
222 endif
223endif
224if !exists("g:netrw_file_cmd")
225 if executable("elinks")
226  call s:NetrwInit("g:netrw_file_cmd","elinks")
227 elseif executable("links")
228  call s:NetrwInit("g:netrw_file_cmd","links")
229 endif
230endif
231if !exists("g:netrw_ftp_cmd")
232  let g:netrw_ftp_cmd	= "ftp"
233endif
234let s:netrw_ftp_cmd= g:netrw_ftp_cmd
235if !exists("g:netrw_ftp_options")
236 let g:netrw_ftp_options= "-i -n"
237endif
238if !exists("g:netrw_http_cmd")
239 if executable("wget")
240  let g:netrw_http_cmd	= "wget"
241  call s:NetrwInit("g:netrw_http_xcmd","-q -O")
242 elseif executable("curl")
243  let g:netrw_http_cmd	= "curl"
244  call s:NetrwInit("g:netrw_http_xcmd","-L -o")
245 elseif executable("elinks")
246  let g:netrw_http_cmd = "elinks"
247  call s:NetrwInit("g:netrw_http_xcmd","-source >")
248 elseif executable("fetch")
249  let g:netrw_http_cmd	= "fetch"
250  call s:NetrwInit("g:netrw_http_xcmd","-o")
251 elseif executable("links")
252  let g:netrw_http_cmd = "links"
253  call s:NetrwInit("g:netrw_http_xcmd","-http.extra-header ".shellescape("Accept-Encoding: identity", 1)." -source >")
254 else
255  let g:netrw_http_cmd	= ""
256 endif
257endif
258call s:NetrwInit("g:netrw_http_put_cmd","curl -T")
259call s:NetrwInit("g:netrw_keepj","keepj")
260call s:NetrwInit("g:netrw_rcp_cmd"  , "rcp")
261call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
262call s:NetrwInit("g:netrw_rsync_sep", "/")
263if !exists("g:netrw_scp_cmd")
264 if executable("scp")
265  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
266 elseif executable("pscp")
267  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable('c:\private.ppk')
268   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -i c:\private.ppk')
269  else
270   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
271  endif
272 else
273  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
274 endif
275endif
276
277call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
278call s:NetrwInit("g:netrw_ssh_cmd"  , "ssh")
279
280if (has("win32") || has("win95") || has("win64") || has("win16"))
281  \ && exists("g:netrw_use_nt_rcp")
282  \ && g:netrw_use_nt_rcp
283  \ && executable( $SystemRoot .'/system32/rcp.exe')
284 let s:netrw_has_nt_rcp = 1
285 let s:netrw_rcpmode    = '-b'
286else
287 let s:netrw_has_nt_rcp = 0
288 let s:netrw_rcpmode    = ''
289endif
290
291" ---------------------------------------------------------------------
292" Default values for netrw's global variables {{{2
293" Cygwin Detection ------- {{{3
294if !exists("g:netrw_cygwin")
295 if has("win32") || has("win95") || has("win64") || has("win16")
296  if  has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
297   let g:netrw_cygwin= 1
298  else
299   let g:netrw_cygwin= 0
300  endif
301 else
302  let g:netrw_cygwin= 0
303 endif
304endif
305" Default values - a-c ---------- {{{3
306call s:NetrwInit("g:netrw_alto"        , &sb)
307call s:NetrwInit("g:netrw_altv"        , &spr)
308call s:NetrwInit("g:netrw_banner"      , 1)
309call s:NetrwInit("g:netrw_browse_split", 0)
310call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro nornu")
311call s:NetrwInit("g:netrw_chgwin"      , -1)
312call s:NetrwInit("g:netrw_compress"    , "gzip")
313call s:NetrwInit("g:netrw_ctags"       , "ctags")
314if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
315 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
316 let g:netrw_cursor= g:netrw_cursorline
317endif
318call s:NetrwInit("g:netrw_cursor"      , 2)
319let s:netrw_usercul = &cursorline
320let s:netrw_usercuc = &cursorcolumn
321call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
322" Default values - d-g ---------- {{{3
323call s:NetrwInit("s:didstarstar",0)
324call s:NetrwInit("g:netrw_dirhistcnt"      , 0)
325call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }')
326call s:NetrwInit("g:netrw_dirhistmax"       , 10)
327call s:NetrwInit("g:netrw_errorlvl"  , s:NOTE)
328call s:NetrwInit("g:netrw_fastbrowse"       , 1)
329call 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$')
330if !exists("g:netrw_ftp_list_cmd")
331 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
332  let g:netrw_ftp_list_cmd     = "ls -lF"
333  let g:netrw_ftp_timelist_cmd = "ls -tlF"
334  let g:netrw_ftp_sizelist_cmd = "ls -slF"
335 else
336  let g:netrw_ftp_list_cmd     = "dir"
337  let g:netrw_ftp_timelist_cmd = "dir"
338  let g:netrw_ftp_sizelist_cmd = "dir"
339 endif
340endif
341call s:NetrwInit("g:netrw_ftpmode",'binary')
342" Default values - h-lh ---------- {{{3
343call s:NetrwInit("g:netrw_hide",1)
344if !exists("g:netrw_ignorenetrc")
345 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
346  let g:netrw_ignorenetrc= 1
347 else
348  let g:netrw_ignorenetrc= 0
349 endif
350endif
351call s:NetrwInit("g:netrw_keepdir",1)
352if !exists("g:netrw_list_cmd")
353 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
354  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
355   " provide a pscp-based listing command
356   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
357  endif
358  if exists("g:netrw_list_cmd_options")
359   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
360  else
361   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
362  endif
363 elseif executable(g:netrw_ssh_cmd)
364  " provide a scp-based default listing command
365  if exists("g:netrw_list_cmd_options")
366   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
367  else
368   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
369  endif
370 else
371"  call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
372  let g:netrw_list_cmd= ""
373 endif
374endif
375call s:NetrwInit("g:netrw_list_hide","")
376" Default values - lh-lz ---------- {{{3
377if exists("g:netrw_local_copycmd")
378 let g:netrw_localcopycmd= g:netrw_local_copycmd
379 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_copycmd is deprecated in favor of g:netrw_localcopycmd",84)
380endif
381if !exists("g:netrw_localcmdshell")
382 let g:netrw_localcmdshell= ""
383endif
384if !exists("g:netrw_localcopycmd")
385 if has("win32") || has("win95") || has("win64") || has("win16")
386  if g:netrw_cygwin
387   let g:netrw_localcopycmd= "cp"
388  else
389   let g:netrw_localcopycmd   = expand("$COMSPEC")
390   let g:netrw_localcopycmdopt= " /c copy"
391  endif
392 elseif has("unix") || has("macunix")
393  let g:netrw_localcopycmd= "cp"
394 else
395  let g:netrw_localcopycmd= ""
396 endif
397endif
398if !exists("g:netrw_localcopydircmd")
399 if has("win32") || has("win95") || has("win64") || has("win16")
400  if g:netrw_cygwin
401   let g:netrw_localcopydircmd   = "cp"
402   let g:netrw_localcopydircmdopt= " -R"
403  else
404   let g:netrw_localcopydircmd   = expand("$COMSPEC")
405   let g:netrw_localcopydircmdopt= " /c xcopy /e /c /h /i /k"
406  endif
407 elseif has("unix")
408  let g:netrw_localcopydircmd   = "cp"
409  let g:netrw_localcopydircmdopt= " -R"
410 elseif has("macunix")
411  let g:netrw_localcopydircmd   = "cp"
412  let g:netrw_localcopydircmdopt= " -R"
413 else
414  let g:netrw_localcopydircmd= ""
415 endif
416endif
417if exists("g:netrw_local_mkdir")
418 let g:netrw_localmkdir= g:netrw_local_mkdir
419 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
420endif
421if has("win32") || has("win95") || has("win64") || has("win16")
422  if g:netrw_cygwin
423   call s:NetrwInit("g:netrw_localmkdir","mkdir")
424  else
425   let g:netrw_localmkdir   = expand("$COMSPEC")
426   let g:netrw_localmkdiropt= " /c mkdir"
427  endif
428else
429 call s:NetrwInit("g:netrw_localmkdir","mkdir")
430endif
431call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
432if exists("g:netrw_local_movecmd")
433 let g:netrw_localmovecmd= g:netrw_local_movecmd
434 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
435endif
436if !exists("g:netrw_localmovecmd")
437 if has("win32") || has("win95") || has("win64") || has("win16")
438  if g:netrw_cygwin
439   let g:netrw_localmovecmd= "mv"
440  else
441   let g:netrw_localmovecmd   = expand("$COMSPEC")
442   let g:netrw_localmovecmdopt= " /c move"
443  endif
444 elseif has("unix") || has("macunix")
445  let g:netrw_localmovecmd= "mv"
446 else
447  let g:netrw_localmovecmd= ""
448 endif
449endif
450" following serves as an example for how to insert a version&patch specific test
451"if v:version < 704 || (v:version == 704 && !has("patch1107"))
452"endif
453call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
454" sanity checks
455if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
456 let g:netrw_liststyle= s:THINLIST
457endif
458if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
459 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
460endif
461" Default values - m-r ---------- {{{3
462call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
463call s:NetrwInit("g:netrw_maxfilenamelen", 32)
464call s:NetrwInit("g:netrw_menu"          , 1)
465call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
466call s:NetrwInit("g:netrw_mousemaps"     , (exists("+mouse") && &mouse =~# '[anh]'))
467call s:NetrwInit("g:netrw_retmap"        , 0)
468if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
469 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
470elseif has("win32") || has("win95") || has("win64") || has("win16")
471 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
472else
473 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
474endif
475call s:NetrwInit("g:netrw_preview"       , 0)
476call s:NetrwInit("g:netrw_scpport"       , "-P")
477call s:NetrwInit("g:netrw_servername"    , "NETRWSERVER")
478call s:NetrwInit("g:netrw_sshport"       , "-p")
479call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
480call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
481call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
482call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
483" Default values - q-s ---------- {{{3
484call s:NetrwInit("g:netrw_quickhelp",0)
485let s:QuickHelp= ["-:go up dir  D:delete  R:rename  s:sort-by  x:special",
486   \              "(create new)  %:file  d:directory",
487   \              "(windows split&open) o:horz  v:vert  p:preview",
488   \              "i:style  qf:file info  O:obtain  r:reverse",
489   \              "(marks)  mf:mark file  mt:set target  mm:move  mc:copy",
490   \              "(bookmarks)  mb:make  mB:delete  qb:list  gb:go to",
491   \              "(history)  qb:list  u:go up  U:go down",
492   \              "(targets)  mt:target Tb:use bookmark  Th:use history"]
493" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
494call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
495if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
496 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
497else
498 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
499endif
500call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
501call s:NetrwInit("g:netrw_sort_options"  , "")
502call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
503if !exists("g:netrw_sort_sequence")
504 if has("unix")
505  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
506 else
507  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
508 endif
509endif
510call s:NetrwInit("g:netrw_special_syntax"   , 0)
511call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
512call s:NetrwInit("g:netrw_suppress_gx_mesg",  1)
513call s:NetrwInit("g:netrw_use_noswf"        , 1)
514call s:NetrwInit("g:netrw_sizestyle"        ,"b")
515" Default values - t-w ---------- {{{3
516call s:NetrwInit("g:netrw_timefmt","%c")
517if !exists("g:netrw_xstrlen")
518 if exists("g:Align_xstrlen")
519  let g:netrw_xstrlen= g:Align_xstrlen
520 elseif exists("g:drawit_xstrlen")
521  let g:netrw_xstrlen= g:drawit_xstrlen
522 elseif &enc == "latin1" || !has("multi_byte")
523  let g:netrw_xstrlen= 0
524 else
525  let g:netrw_xstrlen= 1
526 endif
527endif
528call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
529call s:NetrwInit("g:netrw_win95ftp",1)
530call s:NetrwInit("g:netrw_winsize",50)
531call s:NetrwInit("g:netrw_wiw",1)
532if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
533" ---------------------------------------------------------------------
534" Default values for netrw's script variables: {{{2
535call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
536if has("win32") || has("win95") || has("win64") || has("win16")
537 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
538else
539 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
540endif
541call s:NetrwInit("g:netrw_menu_escape",'.&? \')
542call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
543call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
544if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
545 let s:treedepthstring= "│ "
546else
547 let s:treedepthstring= "| "
548endif
549call s:NetrwInit("s:netrw_posn",'{}')
550
551" BufEnter event ignored by decho when following variable is true
552"  Has a side effect that doau BufReadPost doesn't work, so
553"  files read by network transfer aren't appropriately highlighted.
554"let g:decho_bufenter = 1	"Decho
555
556" ======================
557"  Netrw Initialization: {{{1
558" ======================
559if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
560" call Decho("installed beval events",'~'.expand("<slnum>"))
561 let &l:bexpr = "netrw#BalloonHelp()"
562 au FileType netrw	setl beval
563 au WinLeave *		if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
564 au VimEnter * 		let s:initbeval= &beval
565"else " Decho
566" if v:version < 700           | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>"))     | endif
567" if !has("balloon_eval")      | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>"))        | endif
568" if exists("s:initbeval")     | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>"))                | endif
569" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>"))            | endif
570" if !has("syntax")            | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
571" if exists("g:syntax_on")     | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>"))                | endif
572endif
573au WinEnter *	if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
574
575if g:netrw_keepj =~# "keepj"
576 com! -nargs=*	NetrwKeepj	keepj <args>
577else
578 let g:netrw_keepj= ""
579 com! -nargs=*	NetrwKeepj	<args>
580endif
581
582" ==============================
583"  Netrw Utility Functions: {{{1
584" ==============================
585
586" ---------------------------------------------------------------------
587" netrw#BalloonHelp: {{{2
588if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
589" call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
590 fun! netrw#BalloonHelp()
591   if &ft != "netrw"
592    return ""
593   endif
594   if !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
595    let mesg= ""
596   elseif     v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
597    let mesg = "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
598   elseif     getline(v:beval_lnum) =~ '^"\s*/'
599    let mesg = "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
600   elseif     v:beval_text == "Sorted" || v:beval_text == "by"
601    let mesg = 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
602   elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
603    let mesg = "S: edit sorting sequence"
604   elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
605    let mesg = "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
606   elseif v:beval_text == "Quick" || v:beval_text == "Help"
607    let mesg = "Help: press <F1>"
608   elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
609    let mesg = "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
610   else
611    let mesg= ""
612   endif
613   return mesg
614 endfun
615"else " Decho
616" if v:version < 700            |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
617" if !has("balloon_eval")       |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>"))       |endif
618" if !has("syntax")             |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>"))                  |endif
619" if !exists("g:syntax_on")     |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>"))                  |endif
620" if  exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>"))           |endif
621endif
622
623" ------------------------------------------------------------------------
624" netrw#Explore: launch the local browser in the directory of the current file {{{2
625"          indx:  == -1: Nexplore
626"                 == -2: Pexplore
627"                 ==  +: this is overloaded:
628"                      * If Nexplore/Pexplore is in use, then this refers to the
629"                        indx'th item in the w:netrw_explore_list[] of items which
630"                        matched the */pattern **/pattern *//pattern **//pattern
631"                      * If Hexplore or Vexplore, then this will override
632"                        g:netrw_winsize to specify the qty of rows or columns the
633"                        newly split window should have.
634"          dosplit==0: the window will be split iff the current file has been modified and hidden not set
635"          dosplit==1: the window will be split before running the local browser
636"          style == 0: Explore     style == 1: Explore!
637"                == 2: Hexplore    style == 3: Hexplore!
638"                == 4: Vexplore    style == 5: Vexplore!
639"                == 6: Texplore
640fun! netrw#Explore(indx,dosplit,style,...)
641"  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)
642"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
643  if !exists("b:netrw_curdir")
644   let b:netrw_curdir= getcwd()
645"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
646  endif
647
648  " record current file for Rexplore's benefit
649  if &ft != "netrw"
650   let w:netrw_rexfile= expand("%:p")
651  endif
652
653  " record current directory
654  let curdir     = simplify(b:netrw_curdir)
655  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
656  if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
657   let curdir= substitute(curdir,'\','/','g')
658  endif
659"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">",'~'.expand("<slnum>"))
660
661  " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
662  " will end up with backslashes here.  Solution: strip off backslashes that precede white space and
663  " try Explore again.
664  if a:0 > 0
665"   call Decho('considering retry: a:1<'.a:1.'>: '.
666     \ ((a:1 =~ "\\\s")?                   'has backslash whitespace' : 'does not have backslash whitespace').', '.
667     \ ((filereadable(s:NetrwFile(a:1)))?  'is readable'              : 'is not readable').', '.
668     \ ((isdirectory(s:NetrwFile(a:1))))?  'is a directory'           : 'is not a directory',
669     \ '~'.expand("<slnum>"))
670   if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
671"    call Decho("re-trying Explore with <".substitute(a:1,'\\\(\s\)','\1','g').">",'~'.expand("<slnum>"))
672    call netrw#Explore(a:indx,a:dosplit,a:style,substitute(a:1,'\\\(\s\)','\1','g'))
673"    call Dret("netrw#Explore : returning from retry")
674    return
675"   else " Decho
676"    call Decho("retry not needed",'~'.expand("<slnum>"))
677   endif
678  endif
679
680  " save registers
681  if has("clipboard")
682"   call Decho("(netrw#Explore) save @* and @+",'~'.expand("<slnum>"))
683   sil! let keepregstar = @*
684   sil! let keepregplus = @+
685  endif
686  sil! let keepregslash= @/
687
688  " if   dosplit
689  " -or- file has been modified AND file not hidden when abandoned
690  " -or- Texplore used
691  if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
692"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified",'~'.expand("<slnum>"))
693   call s:SaveWinVars()
694   let winsz= g:netrw_winsize
695   if a:indx > 0
696    let winsz= a:indx
697   endif
698
699   if a:style == 0      " Explore, Sexplore
700"    call Decho("style=0: Explore or Sexplore",'~'.expand("<slnum>"))
701    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
702    if winsz == 0|let winsz= ""|endif
703    exe "noswapfile ".winsz."wincmd s"
704"    call Decho("exe noswapfile ".winsz."wincmd s",'~'.expand("<slnum>"))
705
706   elseif a:style == 1  "Explore!, Sexplore!
707"    call Decho("style=1: Explore! or Sexplore!",'~'.expand("<slnum>"))
708    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
709    if winsz == 0|let winsz= ""|endif
710    exe "keepalt noswapfile ".winsz."wincmd v"
711"    call Decho("exe keepalt noswapfile ".winsz."wincmd v",'~'.expand("<slnum>"))
712
713   elseif a:style == 2  " Hexplore
714"    call Decho("style=2: Hexplore",'~'.expand("<slnum>"))
715    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
716    if winsz == 0|let winsz= ""|endif
717    exe "keepalt noswapfile bel ".winsz."wincmd s"
718"    call Decho("exe keepalt noswapfile bel ".winsz."wincmd s",'~'.expand("<slnum>"))
719
720   elseif a:style == 3  " Hexplore!
721"    call Decho("style=3: Hexplore!",'~'.expand("<slnum>"))
722    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
723    if winsz == 0|let winsz= ""|endif
724    exe "keepalt noswapfile abo ".winsz."wincmd s"
725"    call Decho("exe keepalt noswapfile abo ".winsz."wincmd s",'~'.expand("<slnum>"))
726
727   elseif a:style == 4  " Vexplore
728"    call Decho("style=4: Vexplore",'~'.expand("<slnum>"))
729    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
730    if winsz == 0|let winsz= ""|endif
731    exe "keepalt noswapfile lefta ".winsz."wincmd v"
732"    call Decho("exe keepalt noswapfile lefta ".winsz."wincmd v",'~'.expand("<slnum>"))
733
734   elseif a:style == 5  " Vexplore!
735"    call Decho("style=5: Vexplore!",'~'.expand("<slnum>"))
736    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
737    if winsz == 0|let winsz= ""|endif
738    exe "keepalt noswapfile rightb ".winsz."wincmd v"
739"    call Decho("exe keepalt noswapfile rightb ".winsz."wincmd v",'~'.expand("<slnum>"))
740
741   elseif a:style == 6  " Texplore
742    call s:SaveBufVars()
743"    call Decho("style  = 6: Texplore",'~'.expand("<slnum>"))
744    exe "keepalt tabnew ".fnameescape(curdir)
745"    call Decho("exe keepalt tabnew ".fnameescape(curdir),'~'.expand("<slnum>"))
746    call s:RestoreBufVars()
747   endif
748   call s:RestoreWinVars()
749"  else " Decho
750"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6",'~'.expand("<slnum>"))
751  endif
752  NetrwKeepj norm! 0
753
754  if a:0 > 0
755"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">",'~'.expand("<slnum>"))
756   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
757"    call Decho("..case a:1<".a:1.">: starts with ~ and unix or cygwin",'~'.expand("<slnum>"))
758    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
759"    call Decho("..using dirname<".dirname.">  (case: ~ && unix||cygwin)",'~'.expand("<slnum>"))
760   elseif a:1 == '.'
761"    call Decho("..case a:1<".a:1.">: matches .",'~'.expand("<slnum>"))
762    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
763    if dirname !~ '/$'
764     let dirname= dirname."/"
765    endif
766"    call Decho("..using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")",'~'.expand("<slnum>"))
767   elseif a:1 =~ '\$'
768"    call Decho("..case a:1<".a:1.">: matches ending $",'~'.expand("<slnum>"))
769    let dirname= simplify(expand(a:1))
770"    call Decho("..using user-specified dirname<".dirname."> with $env-var",'~'.expand("<slnum>"))
771   elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
772"    call Decho("..case a:1<".a:1.">: other, not pattern or filepattern",'~'.expand("<slnum>"))
773    let dirname= simplify(a:1)
774"    call Decho("..using user-specified dirname<".dirname.">",'~'.expand("<slnum>"))
775   else
776"    call Decho("..case a:1: pattern or filepattern",'~'.expand("<slnum>"))
777    let dirname= a:1
778   endif
779  else
780   " clear explore
781"   call Decho("case a:0=".a:0.": clearing Explore list",'~'.expand("<slnum>"))
782   call s:NetrwClearExplore()
783"   call Dret("netrw#Explore : cleared list")
784   return
785  endif
786
787"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
788  if dirname =~ '\.\./\=$'
789   let dirname= simplify(fnamemodify(dirname,':p:h'))
790  elseif dirname =~ '\.\.' || dirname == '.'
791   let dirname= simplify(fnamemodify(dirname,':p'))
792  endif
793"  call Decho("dirname<".dirname.">  (after simplify)",'~'.expand("<slnum>"))
794
795  if dirname =~ '^\*//'
796   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
797"   call Decho("case starpat=1: Explore *//pattern",'~'.expand("<slnum>"))
798   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
799   let starpat= 1
800"   call Decho("..Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
801   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
802
803  elseif dirname =~ '^\*\*//'
804   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
805"   call Decho("case starpat=2: Explore **//pattern",'~'.expand("<slnum>"))
806   let pattern= substitute(dirname,'^\*\*//','','')
807   let starpat= 2
808"   call Decho("..Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
809
810  elseif dirname =~ '/\*\*/'
811   " handle .../**/.../filepat
812"   call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
813   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
814   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
815    let b:netrw_curdir = prefixdir
816   else
817    let b:netrw_curdir= getcwd().'/'.prefixdir
818   endif
819   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
820   let starpat= 4
821"   call Decho("..pwd<".getcwd()."> dirname<".dirname.">",'~'.expand("<slnum>"))
822"   call Decho("..case Explore ../**/../filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
823
824  elseif dirname =~ '^\*/'
825   " case starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
826   let starpat= 3
827"   call Decho("case starpat=3: Explore */filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
828
829  elseif dirname=~ '^\*\*/'
830   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
831   let starpat= 4
832"   call Decho("case starpat=4: Explore **/filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
833
834  else
835   let starpat= 0
836"   call Decho("case starpat=0: default",'~'.expand("<slnum>"))
837  endif
838
839  if starpat == 0 && a:indx >= 0
840   " [Explore Hexplore Vexplore Sexplore] [dirname]
841"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname.">, handles Explore Hexplore Vexplore Sexplore",'~'.expand("<slnum>"))
842   if dirname == ""
843    let dirname= curfiledir
844"    call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>"))
845   endif
846   if dirname =~# '^scp://' || dirname =~ '^ftp://'
847    call netrw#Nread(2,dirname)
848   else
849    if dirname == ""
850     let dirname= getcwd()
851    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
852     " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
853     " depending on whether backslashes have been converted to forward slashes by earlier code).
854     if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
855      let dirname= b:netrw_curdir."/".dirname
856     endif
857    elseif dirname !~ '^/'
858     let dirname= b:netrw_curdir."/".dirname
859    endif
860"    call Decho("..calling LocalBrowseCheck(dirname<".dirname.">)",'~'.expand("<slnum>"))
861    call netrw#LocalBrowseCheck(dirname)
862"    call Decho(" modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
863"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
864   endif
865   if exists("w:netrw_bannercnt")
866    " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
867    " If one wants to return the same place in the netrw window, use :Rex instead.
868    exe w:netrw_bannercnt
869   endif
870
871"   call Decho("curdir<".curdir.">",'~'.expand("<slnum>"))
872   " ---------------------------------------------------------------------
873   " Jan 24, 2013: not sure why the following was present.  See P08-Ingelrest
874"   if has("win32") || has("win95") || has("win64") || has("win16")
875"    NetrwKeepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
876"   else
877"    NetrwKeepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
878"   endif
879   " ---------------------------------------------------------------------
880
881  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
882  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
883  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
884  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
885  elseif a:indx <= 0
886   " Nexplore, Pexplore, Explore: handle starpat
887"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx,'~'.expand("<slnum>"))
888   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
889"    call Decho("..set up <s-up> and <s-down> maps",'~'.expand("<slnum>"))
890    let s:didstarstar= 1
891    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
892    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
893   endif
894
895   if has("path_extra")
896"    call Decho("..starpat=".starpat.": has +path_extra",'~'.expand("<slnum>"))
897    if !exists("w:netrw_explore_indx")
898     let w:netrw_explore_indx= 0
899    endif
900
901    let indx = a:indx
902"    call Decho("..starpat=".starpat.": set indx= [a:indx=".indx."]",'~'.expand("<slnum>"))
903
904    if indx == -1
905     " Nexplore
906"     call Decho("..case Nexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
907     if !exists("w:netrw_explore_list") " sanity check
908      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
909      if has("clipboard")
910"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
911       if @* != keepregstar | sil! let @* = keepregstar | endif
912       if @+ != keepregplus | sil! let @+ = keepregplus | endif
913      endif
914      sil! let @/ = keepregslash
915"      call Dret("netrw#Explore")
916      return
917     endif
918     let indx= w:netrw_explore_indx
919     if indx < 0                        | let indx= 0                           | endif
920     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
921     let curfile= w:netrw_explore_list[indx]
922"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
923     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
924      let indx= indx + 1
925"      call Decho("....indx=".indx." (Nexplore while loop)",'~'.expand("<slnum>"))
926     endwhile
927     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
928"     call Decho("....Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
929
930    elseif indx == -2
931     " Pexplore
932"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
933     if !exists("w:netrw_explore_list") " sanity check
934      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
935      if has("clipboard")
936"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
937       if @* != keepregstar | sil! let @* = keepregstar | endif
938       if @+ != keepregplus | sil! let @+ = keepregplus | endif
939      endif
940      sil! let @/ = keepregslash
941"      call Dret("netrw#Explore")
942      return
943     endif
944     let indx= w:netrw_explore_indx
945     if indx < 0                        | let indx= 0                           | endif
946     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
947     let curfile= w:netrw_explore_list[indx]
948"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
949     while indx >= 0 && curfile == w:netrw_explore_list[indx]
950      let indx= indx - 1
951"      call Decho("....indx=".indx." (Pexplore while loop)",'~'.expand("<slnum>"))
952     endwhile
953     if indx < 0                        | let indx= 0                           | endif
954"     call Decho("....Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
955
956    else
957     " Explore -- initialize
958     " build list of files to Explore with Nexplore/Pexplore
959"     call Decho("..starpat=".starpat.": case Explore: initialize (indx=".indx.")",'~'.expand("<slnum>"))
960     NetrwKeepj keepalt call s:NetrwClearExplore()
961     let w:netrw_explore_indx= 0
962     if !exists("b:netrw_curdir")
963      let b:netrw_curdir= getcwd()
964     endif
965"     call Decho("....starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
966
967     " switch on starpat to build the w:netrw_explore_list of files
968     if starpat == 1
969      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
970"      call Decho("..case starpat=".starpat.": build *//pattern list  (curdir-only srch for files containing pattern)  &hls=".&hls,'~'.expand("<slnum>"))
971"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
972      try
973       exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
974      catch /^Vim\%((\a\+)\)\=:E480/
975       keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
976"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
977       return
978      endtry
979      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
980      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
981
982     elseif starpat == 2
983      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
984"      call Decho("..case starpat=".starpat.": build **//pattern list  (recursive descent files containing pattern)",'~'.expand("<slnum>"))
985"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
986      try
987       exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
988      catch /^Vim\%((\a\+)\)\=:E480/
989       keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
990       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
991       if has("clipboard")
992"        call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
993        if @* != keepregstar | sil! let @* = keepregstar | endif
994        if @+ != keepregplus | sil! let @+ = keepregplus | endif
995       endif
996       sil! let @/ = keepregslash
997"       call Dret("netrw#Explore : no files matched pattern")
998       return
999      endtry
1000      let s:netrw_curdir       = b:netrw_curdir
1001      let w:netrw_explore_list = getqflist()
1002      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
1003      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1004
1005     elseif starpat == 3
1006      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
1007"      call Decho("..case starpat=".starpat.": build */filepat list  (curdir-only srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1008      let filepat= substitute(dirname,'^\*/','','')
1009      let filepat= substitute(filepat,'^[%#<]','\\&','')
1010"      call Decho("....b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
1011"      call Decho("....filepat<".filepat.">",'~'.expand("<slnum>"))
1012      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
1013      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
1014
1015     elseif starpat == 4
1016      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
1017"      call Decho("..case starpat=".starpat.": build **/filepat list  (recursive descent srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1018      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
1019      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
1020     endif " switch on starpat to build w:netrw_explore_list
1021
1022     let w:netrw_explore_listlen = len(w:netrw_explore_list)
1023"     call Decho("....w:netrw_explore_list<".string(w:netrw_explore_list).">",'~'.expand("<slnum>"))
1024"     call Decho("....w:netrw_explore_listlen=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1025
1026     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1027      keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1028      if has("clipboard")
1029"       call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1030        if @* != keepregstar | sil! let @* = keepregstar | endif
1031        if @+ != keepregplus | sil! let @+ = keepregplus | endif
1032      endif
1033      sil! let @/ = keepregslash
1034"      call Dret("netrw#Explore : no files matched")
1035      return
1036     endif
1037    endif  " if indx ... endif
1038
1039    " NetrwStatusLine support - for exploring support
1040    let w:netrw_explore_indx= indx
1041"    call Decho("....w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1042
1043    " wrap the indx around, but issue a note
1044    if indx >= w:netrw_explore_listlen || indx < 0
1045"     call Decho("....wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")",'~'.expand("<slnum>"))
1046     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1047     let w:netrw_explore_indx= indx
1048     keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
1049    endif
1050
1051    exe "let dirfile= w:netrw_explore_list[".indx."]"
1052"    call Decho("....dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">",'~'.expand("<slnum>"))
1053    let newdir= substitute(dirfile,'/[^/]*$','','e')
1054"    call Decho("....newdir<".newdir.">",'~'.expand("<slnum>"))
1055
1056"    call Decho("....calling LocalBrowseCheck(newdir<".newdir.">)",'~'.expand("<slnum>"))
1057    call netrw#LocalBrowseCheck(newdir)
1058    if !exists("w:netrw_liststyle")
1059     let w:netrw_liststyle= g:netrw_liststyle
1060    endif
1061    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1062     keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1063    else
1064     keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1065    endif
1066    let w:netrw_explore_mtchcnt = indx + 1
1067    let w:netrw_explore_bufnr   = bufnr("%")
1068    let w:netrw_explore_line    = line(".")
1069    keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
1070"    call Decho("....explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line,'~'.expand("<slnum>"))
1071
1072   else
1073"    call Decho("..your vim does not have +path_extra",'~'.expand("<slnum>"))
1074    if !exists("g:netrw_quiet")
1075     keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1076    endif
1077    if has("clipboard")
1078"     call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1079      if @* != keepregstar | sil! let @* = keepregstar | endif
1080      if @+ != keepregplus | sil! let @+ = keepregplus | endif
1081    endif
1082    sil! let @/ = keepregslash
1083"    call Dret("netrw#Explore : missing +path_extra")
1084    return
1085   endif
1086
1087  else
1088"   call Decho("..default case: Explore newdir<".dirname.">",'~'.expand("<slnum>"))
1089   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1090    sil! unlet w:netrw_treedict
1091    sil! unlet w:netrw_treetop
1092   endif
1093   let newdir= dirname
1094   if !exists("b:netrw_curdir")
1095    NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1096   else
1097    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
1098   endif
1099  endif
1100
1101  " visual display of **/ **// */ Exploration files
1102"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"),'~'.expand("<slnum>"))
1103"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">",'~'.expand("<slnum>"))
1104  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
1105"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"),'~'.expand("<slnum>"))
1106   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1107    " only update match list when current directory isn't the same as before
1108"    call Decho("only update match list when current directory not the same as before",'~'.expand("<slnum>"))
1109    let s:explore_prvdir = b:netrw_curdir
1110    let s:explore_match  = ""
1111    let dirlen           = strlen(b:netrw_curdir)
1112    if b:netrw_curdir !~ '/$'
1113     let dirlen= dirlen + 1
1114    endif
1115    let prvfname= ""
1116    for fname in w:netrw_explore_list
1117"     call Decho("fname<".fname.">",'~'.expand("<slnum>"))
1118     if fname =~ '^'.b:netrw_curdir
1119      if s:explore_match == ""
1120       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1121      else
1122       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1123      endif
1124     elseif fname !~ '^/' && fname != prvfname
1125      if s:explore_match == ""
1126       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1127      else
1128       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1129      endif
1130     endif
1131     let prvfname= fname
1132    endfor
1133"    call Decho("explore_match<".s:explore_match.">",'~'.expand("<slnum>"))
1134    if has("syntax") && exists("g:syntax_on") && g:syntax_on
1135     exe "2match netrwMarkFile /".s:explore_match."/"
1136    endif
1137   endif
1138   echo "<s-up>==Pexplore  <s-down>==Nexplore"
1139  else
1140   2match none
1141   if exists("s:explore_match")  | unlet s:explore_match  | endif
1142   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
1143   echo " "
1144"   call Decho("cleared explore match list",'~'.expand("<slnum>"))
1145  endif
1146
1147  " since Explore may be used to initialize netrw's browser,
1148  " there's no danger of a late FocusGained event on initialization.
1149  " Consequently, set s:netrw_events to 2.
1150  let s:netrw_events= 2
1151  if has("clipboard")
1152"   call Decho("(netrw#Explore) restore @* and @+",'~'.expand("<slnum>"))
1153   if @* != keepregstar | sil! let @* = keepregstar | endif
1154   if @+ != keepregplus | sil! let @+ = keepregplus | endif
1155  endif
1156  sil! let @/ = keepregslash
1157"  call Dret("netrw#Explore : @/<".@/.">")
1158endfun
1159
1160" ---------------------------------------------------------------------
1161" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
1162fun! netrw#Lexplore(count,rightside,...)
1163"  call Dfunc("netrw#Lexplore(count=".a:count." rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
1164  let curwin= winnr()
1165
1166  if a:0 > 0 && a:1 != ""
1167   " if a netrw window is already on the left-side of the tab
1168   " and a directory has been specified, explore with that
1169   " directory.
1170"   call Decho("case has input argument(s) (a:1<".a:1.">)")
1171   let a1 = expand(a:1)
1172"   call Decho("a:1<".a:1.">  curwin#".curwin,'~'.expand("<slnum>"))
1173   exe "1wincmd w"
1174   if &ft == "netrw"
1175"    call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
1176    exe "Explore ".fnameescape(a1)
1177    exe curwin."wincmd w"
1178    if exists("t:netrw_lexposn")
1179"     call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
1180     unlet t:netrw_lexposn
1181    endif
1182"    call Dret("netrw#Lexplore")
1183    return
1184   endif
1185   exe curwin."wincmd w"
1186  else
1187   let a1= ""
1188"   call Decho("no input arguments")
1189  endif
1190
1191  if exists("t:netrw_lexbufnr")
1192   " check if t:netrw_lexbufnr refers to a netrw window
1193   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1194"   call Decho("lexwinnr= bufwinnr(t:netrw_lexbufnr#".t:netrw_lexbufnr.")=".lexwinnr)
1195  else
1196   let lexwinnr= 0
1197"   call Decho("t:netrw_lexbufnr doesn't exist")
1198  endif
1199"  call Decho("lexwinnr=".lexwinnr,'~'.expand("<slnum>"))
1200
1201  if lexwinnr > 0
1202   " close down netrw explorer window
1203"   call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
1204   exe lexwinnr."wincmd w"
1205   let g:netrw_winsize = -winwidth(0)
1206   let t:netrw_lexposn = winsaveview()
1207"   call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1208"   call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
1209   close
1210   if lexwinnr < curwin
1211    let curwin= curwin - 1
1212   endif
1213   if lexwinnr != curwin
1214    exe curwin."wincmd w"
1215   endif
1216   unlet t:netrw_lexbufnr
1217"   call Decho("unlet t:netrw_lexbufnr")
1218
1219  else
1220   " open netrw explorer window
1221"   call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
1222   exe "1wincmd w"
1223   let keep_altv    = g:netrw_altv
1224   let g:netrw_altv = 0
1225   if a:count != 0
1226    let netrw_winsize   = g:netrw_winsize
1227    let g:netrw_winsize = a:count
1228   endif
1229   let curfile= expand("%")
1230"   call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
1231   exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1232"   call Decho("new buf#".bufnr("%")." win#".winnr())
1233   if a:0 > 0 && a1 != ""
1234"    call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
1235    call netrw#Explore(0,0,0,a1)
1236    exe "Explore ".fnameescape(a1)
1237   elseif curfile =~ '^\a\{3,}://'
1238"    call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
1239    call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
1240   else
1241"    call Decho("case 3: Explore .",'~'.expand("<slnum>"))
1242    call netrw#Explore(0,0,0,".")
1243   endif
1244   if a:count != 0
1245    let g:netrw_winsize = netrw_winsize
1246   endif
1247   setlocal winfixwidth
1248   let g:netrw_altv     = keep_altv
1249   let t:netrw_lexbufnr = bufnr("%")
1250"   call Decho("let t:netrw_lexbufnr=".t:netrw_lexbufnr)
1251"   call Decho("t:netrw_lexposn".(exists("t:netrw_lexposn")? string(t:netrw_lexposn) : " n/a"))
1252   if exists("t:netrw_lexposn")
1253"    call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1254"    call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1255    call winrestview(t:netrw_lexposn)
1256    unlet t:netrw_lexposn
1257   endif
1258  endif
1259
1260  " set up default window for editing via <cr>
1261  if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
1262   if a:rightside
1263    let g:netrw_chgwin= 1
1264   else
1265    let g:netrw_chgwin= 2
1266   endif
1267"   call Decho("let g:netrw_chgwin=".g:netrw_chgwin)
1268  endif
1269
1270"  call Dret("netrw#Lexplore")
1271endfun
1272
1273" ---------------------------------------------------------------------
1274" netrw#Clean: remove netrw {{{2
1275" supports :NetrwClean  -- remove netrw from first directory on runtimepath
1276"          :NetrwClean! -- remove netrw from all directories on runtimepath
1277fun! netrw#Clean(sys)
1278"  call Dfunc("netrw#Clean(sys=".a:sys.")")
1279
1280  if a:sys
1281   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
1282  else
1283   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
1284  endif
1285"  call Decho("choice=".choice,'~'.expand("<slnum>"))
1286  let diddel= 0
1287  let diddir= ""
1288
1289  if choice == 1
1290   for dir in split(&rtp,',')
1291    if filereadable(dir."/plugin/netrwPlugin.vim")
1292"     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1293     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
1294     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1295     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
1296     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
1297     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
1298     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
1299     let diddir= dir
1300     let diddel= diddel + 1
1301     if !a:sys|break|endif
1302    endif
1303   endfor
1304  endif
1305
1306   echohl WarningMsg
1307  if diddel == 0
1308   echomsg "netrw is either not installed or not removable"
1309  elseif diddel == 1
1310   echomsg "removed one copy of netrw from <".diddir.">"
1311  else
1312   echomsg "removed ".diddel." copies of netrw"
1313  endif
1314   echohl None
1315
1316"  call Dret("netrw#Clean")
1317endfun
1318
1319" ---------------------------------------------------------------------
1320" netrw#MakeTgt: make a target out of the directory name provided {{{2
1321fun! netrw#MakeTgt(dname)
1322"  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1323   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
1324  let svpos               = winsaveview()
1325"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1326  let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
1327"  call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
1328  if s:netrwmftgt_islocal
1329   let netrwmftgt= simplify(a:dname)
1330  else
1331   let netrwmftgt= a:dname
1332  endif
1333  if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
1334   " re-selected target, so just clear it
1335   unlet s:netrwmftgt s:netrwmftgt_islocal
1336  else
1337   let s:netrwmftgt= netrwmftgt
1338  endif
1339  if g:netrw_fastbrowse <= 1
1340   call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
1341  endif
1342"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
1343  call winrestview(svpos)
1344"  call Dret("netrw#MakeTgt")
1345endfun
1346
1347" ---------------------------------------------------------------------
1348" netrw#Obtain: {{{2
1349"   netrw#Obtain(islocal,fname[,tgtdirectory])
1350"     islocal=0  obtain from remote source
1351"            =1  obtain from local source
1352"     fname  :   a filename or a list of filenames
1353"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
1354fun! netrw#Obtain(islocal,fname,...)
1355"  call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
1356  " NetrwStatusLine support - for obtaining support
1357
1358  if type(a:fname) == 1
1359   let fnamelist= [ a:fname ]
1360  elseif type(a:fname) == 3
1361   let fnamelist= a:fname
1362  else
1363   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1364"   call Dret("netrw#Obtain")
1365   return
1366  endif
1367"  call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
1368  if a:0 > 0
1369   let tgtdir= a:1
1370  else
1371   let tgtdir= getcwd()
1372  endif
1373"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
1374
1375  if exists("b:netrw_islocal") && b:netrw_islocal
1376   " obtain a file from local b:netrw_curdir to (local) tgtdir
1377"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1378   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1379    let topath= s:ComposePath(tgtdir,"")
1380    if (has("win32") || has("win95") || has("win64") || has("win16"))
1381     " transfer files one at time
1382"     call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1383     for fname in fnamelist
1384"      call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1385      call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1386      if v:shell_error != 0
1387       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1388"       call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1389       return
1390      endif
1391     endfor
1392    else
1393     " transfer files with one command
1394"     call Decho("transfer files with one command",'~'.expand("<slnum>"))
1395     let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1396"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1397     call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".filelist." ".s:ShellEscape(topath))
1398     if v:shell_error != 0
1399      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1400"      call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1401      return
1402     endif
1403    endif
1404   elseif !exists("b:netrw_curdir")
1405    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
1406   else
1407    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
1408   endif
1409
1410  else
1411   " obtain files from remote b:netrw_curdir to local tgtdir
1412"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1413   if type(a:fname) == 1
1414    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
1415   endif
1416   call s:NetrwMethod(b:netrw_curdir)
1417
1418   if b:netrw_method == 4
1419    " obtain file using scp
1420"    call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1421    if exists("g:netrw_port") && g:netrw_port != ""
1422     let useport= " ".g:netrw_scpport." ".g:netrw_port
1423    else
1424     let useport= ""
1425    endif
1426    if b:netrw_fname =~ '/'
1427     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1428    else
1429     let path= ""
1430    endif
1431    let filelist= join(map(deepcopy(fnamelist),'escape(s:ShellEscape(g:netrw_machine.":".path.v:val,1)," ")'))
1432    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
1433
1434   elseif b:netrw_method == 2
1435    " obtain file using ftp + .netrc
1436"     call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1437     call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1438     let tmpbufnr= bufnr("%")
1439     setl ff=unix
1440     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1441      NetrwKeepj put =g:netrw_ftpmode
1442"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1443     endif
1444
1445     if exists("b:netrw_fname") && b:netrw_fname != ""
1446      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1447"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1448     endif
1449
1450     if exists("g:netrw_ftpextracmd")
1451      NetrwKeepj put =g:netrw_ftpextracmd
1452"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1453     endif
1454     for fname in fnamelist
1455      call setline(line("$")+1,'get "'.fname.'"')
1456"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1457     endfor
1458     if exists("g:netrw_port") && g:netrw_port != ""
1459      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1460     else
1461      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1462     endif
1463     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1464     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1465      let debugkeep= &debug
1466      setl debug=msg
1467      call netrw#ErrorMsg(s:ERROR,getline(1),4)
1468      let &debug= debugkeep
1469     endif
1470
1471   elseif b:netrw_method == 3
1472    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1473"    call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1474    call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1475    let tmpbufnr= bufnr("%")
1476    setl ff=unix
1477
1478    if exists("g:netrw_port") && g:netrw_port != ""
1479     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1480"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1481    else
1482     NetrwKeepj put ='open '.g:netrw_machine
1483"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1484    endif
1485
1486    if exists("g:netrw_uid") && g:netrw_uid != ""
1487     if exists("g:netrw_ftp") && g:netrw_ftp == 1
1488      NetrwKeepj put =g:netrw_uid
1489"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1490      if exists("s:netrw_passwd") && s:netrw_passwd != ""
1491       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1492      endif
1493"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1494     elseif exists("s:netrw_passwd")
1495      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1496"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1497     endif
1498    endif
1499
1500    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1501     NetrwKeepj put =g:netrw_ftpmode
1502"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1503    endif
1504
1505    if exists("b:netrw_fname") && b:netrw_fname != ""
1506     NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1507"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1508    endif
1509
1510    if exists("g:netrw_ftpextracmd")
1511     NetrwKeepj put =g:netrw_ftpextracmd
1512"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1513    endif
1514
1515    if exists("g:netrw_ftpextracmd")
1516     NetrwKeepj put =g:netrw_ftpextracmd
1517"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1518    endif
1519    for fname in fnamelist
1520     NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1521    endfor
1522"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1523
1524    " perform ftp:
1525    " -i       : turns off interactive prompting from ftp
1526    " -n  unix : DON'T use <.netrc>, even though it exists
1527    " -n  win32: quit being obnoxious about password
1528    "  Note: using "_dd to delete to the black hole register; avoids messing up @@
1529    NetrwKeepj norm! 1G"_dd
1530    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1531    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1532    if getline(1) !~ "^$"
1533"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1534     if !exists("g:netrw_quiet")
1535      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1536     endif
1537    endif
1538
1539   elseif b:netrw_method == 9
1540    " obtain file using sftp
1541"    call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1542    if a:fname =~ '/'
1543     let localfile= substitute(a:fname,'^.*/','','')
1544    else
1545     let localfile= a:fname
1546    endif
1547    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))
1548
1549   elseif !exists("b:netrw_method") || b:netrw_method < 0
1550    " probably a badly formed url; protocol not recognized
1551"    call Dret("netrw#Obtain : unsupported method")
1552    return
1553
1554   else
1555    " protocol recognized but not supported for Obtain (yet?)
1556    if !exists("g:netrw_quiet")
1557     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1558    endif
1559"    call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1560    return
1561   endif
1562
1563   " restore status line
1564   if type(a:fname) == 1 && exists("s:netrw_users_stl")
1565    NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
1566   endif
1567
1568  endif
1569
1570  " cleanup
1571  if exists("tmpbufnr")
1572   if bufnr("%") != tmpbufnr
1573    exe tmpbufnr."bw!"
1574   else
1575    q!
1576   endif
1577  endif
1578
1579"  call Dret("netrw#Obtain")
1580endfun
1581
1582" ---------------------------------------------------------------------
1583" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1584fun! netrw#Nread(mode,fname)
1585"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
1586  let svpos= winsaveview()
1587"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1588  call netrw#NetRead(a:mode,a:fname)
1589"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1590  call winrestview(svpos)
1591
1592  if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
1593   if exists("w:netrw_bannercnt")
1594    " start with cursor just after the banner
1595    exe w:netrw_bannercnt
1596   endif
1597  endif
1598"  call Dret("netrw#Nread")
1599endfun
1600
1601" ------------------------------------------------------------------------
1602" s:NetrwOptionsSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1603"             Options get restored by s:NetrwOptionsRestore()
1604"
1605"             Option handling:
1606"              * save user's options                                     (s:NetrwOptionsSave)
1607"              * set netrw-safe options                                  (s:NetrwOptionsSafe)
1608"                - change an option only when user option != safe option (s:netrwSetSafeSetting)
1609"              * restore user's options                                  (s:netrwOPtionsRestore)
1610"                - restore a user option when != safe option             (s:NetrwRestoreSetting)
1611"             vt: (variable type) normally its either "w:" or "s:"
1612fun! s:NetrwOptionsSave(vt)
1613"  call Dfunc("s:NetrwOptionsSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1614"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1615"  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>"))
1616
1617  if !exists("{a:vt}netrw_optionsave")
1618   let {a:vt}netrw_optionsave= 1
1619  else
1620"   call Dret("s:NetrwOptionsSave : options already saved")
1621   return
1622  endif
1623"  call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
1624
1625  " Save current settings and current directory
1626"  call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
1627  let s:yykeep          = @@
1628  if exists("&l:acd")|let {a:vt}netrw_acdkeep  = &l:acd|endif
1629  let {a:vt}netrw_aikeep    = &l:ai
1630  let {a:vt}netrw_awkeep    = &l:aw
1631  let {a:vt}netrw_bhkeep    = &l:bh
1632  let {a:vt}netrw_blkeep    = &l:bl
1633  let {a:vt}netrw_btkeep    = &l:bt
1634  let {a:vt}netrw_bombkeep  = &l:bomb
1635  let {a:vt}netrw_cedit     = &cedit
1636  let {a:vt}netrw_cikeep    = &l:ci
1637  let {a:vt}netrw_cinkeep   = &l:cin
1638  let {a:vt}netrw_cinokeep  = &l:cino
1639  let {a:vt}netrw_comkeep   = &l:com
1640  let {a:vt}netrw_cpokeep   = &l:cpo
1641  let {a:vt}netrw_diffkeep  = &l:diff
1642  let {a:vt}netrw_fenkeep   = &l:fen
1643  if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
1644   let {a:vt}netrw_ffkeep    = &l:ff
1645  endif
1646  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
1647  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
1648  let {a:vt}netrw_hidkeep   = &l:hidden
1649  let {a:vt}netrw_imkeep    = &l:im
1650  let {a:vt}netrw_iskkeep   = &l:isk
1651  let {a:vt}netrw_lskeep    = &l:ls
1652  let {a:vt}netrw_makeep    = &l:ma
1653  let {a:vt}netrw_magickeep = &l:magic
1654  let {a:vt}netrw_modkeep   = &l:mod
1655  let {a:vt}netrw_nukeep    = &l:nu
1656  let {a:vt}netrw_rnukeep   = &l:rnu
1657  let {a:vt}netrw_repkeep   = &l:report
1658  let {a:vt}netrw_rokeep    = &l:ro
1659  let {a:vt}netrw_selkeep   = &l:sel
1660  let {a:vt}netrw_spellkeep = &l:spell
1661  if !g:netrw_use_noswf
1662   let {a:vt}netrw_swfkeep  = &l:swf
1663  endif
1664  let {a:vt}netrw_tskeep    = &l:ts
1665  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
1666  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
1667  let {a:vt}netrw_wrapkeep  = &l:wrap
1668  let {a:vt}netrw_writekeep = &l:write
1669
1670  " save a few selected netrw-related variables
1671"  call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
1672  if g:netrw_keepdir
1673   let {a:vt}netrw_dirkeep  = getcwd()
1674"   call Decho("saving to ".a:vt."netrw_dirkeep<".{a:vt}netrw_dirkeep.">",'~'.expand("<slnum>"))
1675  endif
1676  if has("clipboard")
1677   sil! let {a:vt}netrw_starkeep = @*
1678   sil! let {a:vt}netrw_pluskeep = @+
1679  endif
1680  sil! let {a:vt}netrw_slashkeep= @/
1681
1682"  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>"))
1683"  call Dret("s:NetrwOptionsSave : tab#".tabpagenr()." win#".winnr())
1684endfun
1685
1686" ---------------------------------------------------------------------
1687" s:NetrwOptionsSafe: sets options to help netrw do its job {{{2
1688"                     Use  s:NetrwSaveOptions() to save user settings
1689"                     Use  s:NetrwOptionsRestore() to restore user settings
1690fun! s:NetrwOptionsSafe(islocal)
1691"  call Dfunc("s:NetrwOptionsSafe(islocal=".a:islocal.") win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1692"  call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1693"  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>"))
1694  if exists("+acd") | call s:NetrwSetSafeSetting("&l:acd",0)|endif
1695  call s:NetrwSetSafeSetting("&l:ai",0)
1696  call s:NetrwSetSafeSetting("&l:aw",0)
1697  call s:NetrwSetSafeSetting("&l:bl",0)
1698  call s:NetrwSetSafeSetting("&l:bomb",0)
1699  if a:islocal
1700   call s:NetrwSetSafeSetting("&l:bt","nofile")
1701  else
1702   call s:NetrwSetSafeSetting("&l:bt","acwrite")
1703  endif
1704  call s:NetrwSetSafeSetting("&l:ci",0)
1705  call s:NetrwSetSafeSetting("&l:cin",0)
1706  call s:NetrwSetSafeSetting("&l:bh","hide")
1707  call s:NetrwSetSafeSetting("&l:cino","")
1708  call s:NetrwSetSafeSetting("&l:com","")
1709  if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif
1710  if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif
1711  setl fo=nroql2
1712  call s:NetrwSetSafeSetting("&l:hid",0)
1713  call s:NetrwSetSafeSetting("&l:im",0)
1714  setl isk+=@ isk+=* isk+=/
1715  call s:NetrwSetSafeSetting("&l:magic",1)
1716  if g:netrw_use_noswf
1717   call s:NetrwSetSafeSetting("swf",0)
1718  endif
1719  call s:NetrwSetSafeSetting("&l:report",10000)
1720  call s:NetrwSetSafeSetting("&l:sel","inclusive")
1721  call s:NetrwSetSafeSetting("&l:spell",0)
1722  call s:NetrwSetSafeSetting("&l:tw",0)
1723  call s:NetrwSetSafeSetting("&l:wig","")
1724  setl cedit&
1725  call s:NetrwCursor()
1726
1727  " allow the user to override safe options
1728"  call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
1729  if &ft == "netrw"
1730"   call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1731   keepalt NetrwKeepj doau FileType netrw
1732  endif
1733
1734"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1735"  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>"))
1736"  call Dret("s:NetrwOptionsSafe")
1737endfun
1738
1739" ---------------------------------------------------------------------
1740" s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2
1741fun! s:NetrwOptionsRestore(vt)
1742"  call Dfunc("s:NetrwOptionsRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
1743"  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>"))
1744  if !exists("{a:vt}netrw_optionsave")
1745"   call Decho("case ".a:vt."netrw_optionsave : doesn't exist",'~'.expand("<slnum>"))
1746"   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>"))
1747"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1748"   call Dret("s:NetrwOptionsRestore : ".a:vt."netrw_optionsave doesn't exist")
1749   return
1750  endif
1751  unlet {a:vt}netrw_optionsave
1752
1753  if exists("+acd")
1754   if exists("{a:vt}netrw_acdkeep")
1755"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1756    let curdir = getcwd()
1757    let &l:acd = {a:vt}netrw_acdkeep
1758    unlet {a:vt}netrw_acdkeep
1759    if &l:acd
1760     call s:NetrwLcd(curdir)
1761    endif
1762   endif
1763  endif
1764  call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai")
1765  call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw")
1766  call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl")
1767  call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt")
1768  call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb")
1769  call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit")
1770  call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci")
1771  call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin")
1772  call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino")
1773  call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com")
1774  call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo")
1775  call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff")
1776  call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen")
1777  if exists("g:netrw_ffkeep") && g:netrw_ffkeep
1778   call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff")
1779  endif
1780  call s:NetrwRestoreSetting(a:vt."netrw_fokeep","&l:fo")
1781  call s:NetrwRestoreSetting(a:vt."netrw_gdkeep","&l:gd")
1782  call s:NetrwRestoreSetting(a:vt."netrw_hidkeep","&l:hidden")
1783  call s:NetrwRestoreSetting(a:vt."netrw_imkeep","&l:im")
1784  call s:NetrwRestoreSetting(a:vt."netrw_iskkeep","&l:isk")
1785  call s:NetrwRestoreSetting(a:vt."netrw_lskeep","&l:ls")
1786  call s:NetrwRestoreSetting(a:vt."netrw_makeep","&l:ma")
1787  call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic")
1788  call s:NetrwRestoreSetting(a:vt."netrw_modkeep","&l:mod")
1789  call s:NetrwRestoreSetting(a:vt."netrw_nukeep","&l:nu")
1790  call s:NetrwRestoreSetting(a:vt."netrw_rnukeep","&l:rnu")
1791  call s:NetrwRestoreSetting(a:vt."netrw_repkeep","&l:report")
1792  call s:NetrwRestoreSetting(a:vt."netrw_rokeep","&l:ro")
1793  call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
1794  call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell")
1795  call s:NetrwRestoreSetting(a:vt."netrw_twkeep","&l:tw")
1796  call s:NetrwRestoreSetting(a:vt."netrw_wigkeep","&l:wig")
1797  call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep","&l:wrap")
1798  call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write")
1799  call s:NetrwRestoreSetting("s:yykeep","@@")
1800  " former problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1801  " Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces
1802  "        rather than by appending a tab which previously was using "&ts" to set the desired spacing.  (Sep 28, 2018)
1803  call s:NetrwRestoreSetting(a:vt."netrw_tskeep","&l:ts")
1804
1805  if exists("{a:vt}netrw_swfkeep")
1806   if &directory == ""
1807    " user hasn't specified a swapfile directory;
1808    " netrw will temporarily set the swapfile directory
1809    " to the current directory as returned by getcwd().
1810    let &l:directory= getcwd()
1811    sil! let &l:swf = {a:vt}netrw_swfkeep
1812    setl directory=
1813    unlet {a:vt}netrw_swfkeep
1814   elseif &l:swf != {a:vt}netrw_swfkeep
1815    if !g:netrw_use_noswf
1816     " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1817     sil! let &l:swf= {a:vt}netrw_swfkeep
1818    endif
1819    unlet {a:vt}netrw_swfkeep
1820   endif
1821  endif
1822  if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
1823   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1824   if exists("{a:vt}netrw_dirkeep")
1825    call s:NetrwLcd(dirkeep)
1826    unlet {a:vt}netrw_dirkeep
1827   endif
1828  endif
1829  if has("clipboard")
1830"   call Decho("has clipboard",'~'.expand("<slnum>"))
1831   call s:NetrwRestoreSetting(a:vt."netrw_starkeep","@*")
1832   call s:NetrwRestoreSetting(a:vt."netrw_pluskeep","@+")
1833  endif
1834  call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/")
1835
1836"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1837"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
1838"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1839"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
1840"  call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
1841  " Moved the filetype detect here from NetrwGetFile() because remote files
1842  " were having their filetype detect-generated settings overwritten by
1843  " NetrwOptionRestore.
1844  if &ft != "netrw"
1845"   call Decho("filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1846   filetype detect
1847  endif
1848"  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>"))
1849"  call Dret("s:NetrwOptionsRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
1850endfun
1851
1852" ---------------------------------------------------------------------
1853" s:NetrwSetSafeSetting: sets an option to a safe setting {{{2
1854"                        but only when the options' value and the safe setting differ
1855"                        Doing this means that netrw will not come up as having changed a
1856"                        setting last when it really didn't actually change it.
1857"
1858"                        Called from s:NetrwOptionsSafe
1859"                          ex. call s:NetrwSetSafeSetting("&l:sel","inclusive")
1860fun! s:NetrwSetSafeSetting(setting,safesetting)
1861"  call Dfunc("s:NetrwSetSafeSetting(setting<".a:setting."> safesetting<".a:safesetting.">)")
1862
1863  if a:setting =~ '^&'
1864"   call Decho("fyi: a:setting starts with &")
1865   exe "let settingval= ".a:setting
1866"   call Decho("fyi: settingval<".settingval.">")
1867
1868   if settingval != a:safesetting
1869"    call Decho("set setting<".a:setting."> to option value<".a:safesetting.">")
1870    if type(a:safesetting) == 0
1871     exe "let ".a:setting."=".a:safesetting
1872    elseif type(a:safesetting) == 1
1873     exe "let ".a:setting."= '".a:safesetting."'"
1874    else
1875     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:setting." with a safesetting of type#".type(a:safesetting),105)
1876    endif
1877   endif
1878  endif
1879
1880"  call Dret("s:NetrwSetSafeSetting")
1881endfun
1882
1883" ------------------------------------------------------------------------
1884" s:NetrwRestoreSetting: restores specified setting using associated keepvar, {{{2
1885"                        but only if the setting value differs from the associated keepvar.
1886"                        Doing this means that netrw will not come up as having changed a
1887"                        setting last when it really didn't actually change it.
1888"
1889"                        Used by s:NetrwOptionsRestore() to restore each netrw-senstive setting
1890"                        keepvars are set up by s:NetrwOptionsSave
1891fun! s:NetrwRestoreSetting(keepvar,setting)
1892"""  call Dfunc("s:NetrwRestoreSetting(a:keepvar<".a:keepvar."> a:setting<".a:setting.">)")
1893
1894  " typically called from s:NetrwOptionsRestore
1895  "   call s:NetrwRestoreSettings(keep-option-variable-name,'associated-option')
1896  "   ex. call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
1897  "  Restores option (if different) from a keepvar
1898  if exists(a:keepvar)
1899   exe "let keepvarval= ".a:keepvar
1900   exe "let setting= ".a:setting
1901
1902""   call Decho("fyi: a:keepvar<".a:keepvar."> exists")
1903""   call Decho("fyi: keepvarval=".keepvarval)
1904""   call Decho("fyi: a:setting<".a:setting."> setting<".setting.">")
1905
1906   if setting != keepvarval
1907""    call Decho("restore setting<".a:setting."> (currently=".setting.") to keepvarval<".keepvarval.">")
1908    if type(a:setting) == 0
1909     exe "let ".a:setting."= ".keepvarval
1910    elseif type(a:setting) == 1
1911     exe "let ".a:setting."= '".keepvarval."'"
1912    else
1913     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105)
1914    endif
1915   endif
1916
1917   exe "unlet ".a:keepvar
1918  endif
1919
1920""  call Dret("s:NetrwRestoreSetting")
1921endfun
1922
1923" ---------------------------------------------------------------------
1924" NetrwStatusLine: {{{2
1925fun! NetrwStatusLine()
1926
1927" vvv NetrwStatusLine() debugging vvv
1928"  let g:stlmsg=""
1929"  if !exists("w:netrw_explore_bufnr")
1930"   let g:stlmsg="!X<explore_bufnr>"
1931"  elseif w:netrw_explore_bufnr != bufnr("%")
1932"   let g:stlmsg="explore_bufnr!=".bufnr("%")
1933"  endif
1934"  if !exists("w:netrw_explore_line")
1935"   let g:stlmsg=" !X<explore_line>"
1936"  elseif w:netrw_explore_line != line(".")
1937"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1938"  endif
1939"  if !exists("w:netrw_explore_list")
1940"   let g:stlmsg=" !X<explore_list>"
1941"  endif
1942" ^^^ NetrwStatusLine() debugging ^^^
1943
1944  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")
1945   " restore user's status line
1946   let &stl        = s:netrw_users_stl
1947   let &laststatus = s:netrw_users_ls
1948   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1949   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1950   return ""
1951  else
1952   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
1953  endif
1954endfun
1955
1956" ===============================
1957"  Netrw Transfer Functions: {{{1
1958" ===============================
1959
1960" ------------------------------------------------------------------------
1961" netrw#NetRead: responsible for reading a file over the net {{{2
1962"   mode: =0 read remote file and insert before current line
1963"         =1 read remote file and insert after current line
1964"         =2 replace with remote file
1965"         =3 obtain file, but leave in temporary format
1966fun! netrw#NetRead(mode,...)
1967"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
1968
1969  " NetRead: save options {{{3
1970  call s:NetrwOptionsSave("w:")
1971  call s:NetrwOptionsSafe(0)
1972  call s:RestoreCursorline()
1973  " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
1974  " However, this setting is not wanted for a remote editing session.  The buffer should be "nofile", still.
1975  setl bl
1976"  call Decho("buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
1977
1978  " NetRead: interpret mode into a readcmd {{{3
1979  if     a:mode == 0 " read remote file before current line
1980   let readcmd = "0r"
1981  elseif a:mode == 1 " read file after current line
1982   let readcmd = "r"
1983  elseif a:mode == 2 " replace with remote file
1984   let readcmd = "%r"
1985  elseif a:mode == 3 " skip read of file (leave as temporary)
1986   let readcmd = "t"
1987  else
1988   exe a:mode
1989   let readcmd = "r"
1990  endif
1991  let ichoice = (a:0 == 0)? 0 : 1
1992"  call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
1993
1994  " NetRead: get temporary filename {{{3
1995  let tmpfile= s:GetTempfile("")
1996  if tmpfile == ""
1997"   call Dret("netrw#NetRead : unable to get a tempfile!")
1998   return
1999  endif
2000
2001  while ichoice <= a:0
2002
2003   " attempt to repeat with previous host-file-etc
2004   if exists("b:netrw_lastfile") && a:0 == 0
2005"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2006    let choice = b:netrw_lastfile
2007    let ichoice= ichoice + 1
2008
2009   else
2010    exe "let choice= a:" . ichoice
2011"    call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
2012
2013    if match(choice,"?") == 0
2014     " give help
2015     echomsg 'NetRead Usage:'
2016     echomsg ':Nread machine:path                         uses rcp'
2017     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
2018     echomsg ':Nread "machine id password path"           uses ftp'
2019     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
2020     echomsg ':Nread fetch://machine/path                 uses fetch'
2021     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2022     echomsg ':Nread http://[user@]machine/path           uses http  wget'
2023     echomsg ':Nread file:///path           		  uses elinks'
2024     echomsg ':Nread https://[user@]machine/path          uses http  wget'
2025     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
2026     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
2027     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
2028     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
2029     sleep 4
2030     break
2031
2032    elseif match(choice,'^"') != -1
2033     " Reconstruct Choice if choice starts with '"'
2034"     call Decho("reconstructing choice",'~'.expand("<slnum>"))
2035     if match(choice,'"$') != -1
2036      " case "..."
2037      let choice= strpart(choice,1,strlen(choice)-2)
2038     else
2039       "  case "... ... ..."
2040      let choice      = strpart(choice,1,strlen(choice)-1)
2041      let wholechoice = ""
2042
2043      while match(choice,'"$') == -1
2044       let wholechoice = wholechoice . " " . choice
2045       let ichoice     = ichoice + 1
2046       if ichoice > a:0
2047       	if !exists("g:netrw_quiet")
2048	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
2049	endif
2050"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
2051        return
2052       endif
2053       let choice= a:{ichoice}
2054      endwhile
2055      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2056     endif
2057    endif
2058   endif
2059
2060"   call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
2061   let ichoice= ichoice + 1
2062
2063   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
2064   call s:NetrwMethod(choice)
2065   if !exists("b:netrw_method") || b:netrw_method < 0
2066"    call Dret("netrw#NetRead : unsupported method")
2067    return
2068   endif
2069   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
2070
2071   " Check whether or not NetrwBrowse() should be handling this request
2072"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
2073   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
2074"    call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
2075    NetrwKeepj call s:NetrwBrowse(0,choice)
2076"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
2077    return
2078   endif
2079
2080   " ============
2081   " NetRead: Perform Protocol-Based Read {{{3
2082   " ===========================
2083   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2084    echo "(netrw) Processing your read request..."
2085   endif
2086
2087   ".........................................
2088   " NetRead: (rcp)  NetRead Method #1 {{{3
2089   if  b:netrw_method == 1 " read with rcp
2090"    call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
2091   " ER: nothing done with g:netrw_uid yet?
2092   " ER: on Win2K" rcp machine[.user]:file tmpfile
2093   " ER: when machine contains '.' adding .user is required (use $USERNAME)
2094   " ER: the tmpfile is full path: rcp sees C:\... as host C
2095   if s:netrw_has_nt_rcp == 1
2096    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2097     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2098    else
2099     " Any way needed it machine contains a '.'
2100     let uid_machine = g:netrw_machine .'.'. $USERNAME
2101    endif
2102   else
2103    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2104     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2105    else
2106     let uid_machine = g:netrw_machine
2107    endif
2108   endif
2109   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))
2110   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2111   let b:netrw_lastfile = choice
2112
2113   ".........................................
2114   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
2115   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
2116"     call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2117     let netrw_fname= b:netrw_fname
2118     NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2119     let filtbuf= bufnr("%")
2120     setl ff=unix
2121     NetrwKeepj put =g:netrw_ftpmode
2122"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2123     if exists("g:netrw_ftpextracmd")
2124      NetrwKeepj put =g:netrw_ftpextracmd
2125"      call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2126     endif
2127     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2128"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2129     if exists("g:netrw_port") && g:netrw_port != ""
2130      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2131     else
2132      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2133     endif
2134     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2135     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2136      let debugkeep = &debug
2137      setl debug=msg
2138      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2139      let &debug    = debugkeep
2140     endif
2141     call s:SaveBufVars()
2142     keepj bd!
2143     if bufname("%") == "" && getline("$") == "" && line('$') == 1
2144      " needed when one sources a file in a nolbl setting window via ftp
2145      q!
2146     endif
2147     call s:RestoreBufVars()
2148     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2149     let b:netrw_lastfile = choice
2150
2151   ".........................................
2152   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
2153   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
2154    " Construct execution string (four lines) which will be passed through filter
2155"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2156    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2157    NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2158    let filtbuf= bufnr("%")
2159    setl ff=unix
2160    if exists("g:netrw_port") && g:netrw_port != ""
2161     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2162"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2163    else
2164     NetrwKeepj put ='open '.g:netrw_machine
2165"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2166    endif
2167
2168    if exists("g:netrw_uid") && g:netrw_uid != ""
2169     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2170      NetrwKeepj put =g:netrw_uid
2171"       call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2172      if exists("s:netrw_passwd")
2173       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2174      endif
2175"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2176     elseif exists("s:netrw_passwd")
2177      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2178"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2179     endif
2180    endif
2181
2182    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2183     NetrwKeepj put =g:netrw_ftpmode
2184"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2185    endif
2186    if exists("g:netrw_ftpextracmd")
2187     NetrwKeepj put =g:netrw_ftpextracmd
2188"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2189    endif
2190    NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2191"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2192
2193    " perform ftp:
2194    " -i       : turns off interactive prompting from ftp
2195    " -n  unix : DON'T use <.netrc>, even though it exists
2196    " -n  win32: quit being obnoxious about password
2197    NetrwKeepj norm! 1G"_dd
2198    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2199    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2200    if getline(1) !~ "^$"
2201"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2202     if !exists("g:netrw_quiet")
2203      call netrw#ErrorMsg(s:ERROR,getline(1),5)
2204     endif
2205    endif
2206    call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2207    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2208    let b:netrw_lastfile = choice
2209
2210   ".........................................
2211   " NetRead: (scp) NetRead Method #4 {{{3
2212   elseif     b:netrw_method  == 4	" read with scp
2213"    call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2214    if exists("g:netrw_port") && g:netrw_port != ""
2215     let useport= " ".g:netrw_scpport." ".g:netrw_port
2216    else
2217     let useport= ""
2218    endif
2219    " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2220    " This is workaround to avoid mis-handle windows local-path:
2221    if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
2222      let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2223    else
2224      let tmpfile_get = tmpfile
2225    endif
2226    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))
2227    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2228    let b:netrw_lastfile = choice
2229
2230   ".........................................
2231   " NetRead: (http) NetRead Method #5 (wget) {{{3
2232   elseif     b:netrw_method  == 5
2233"    call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2234    if g:netrw_http_cmd == ""
2235     if !exists("g:netrw_quiet")
2236      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2237     endif
2238"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2239     return
2240    endif
2241
2242    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2243     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2244"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2245     if exists("g:netrw_http_xcmd")
2246      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))
2247     else
2248      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))
2249     endif
2250     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2251
2252    else
2253     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2254"     call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2255     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2256     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2257"     call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2258"     call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2259     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))
2260     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2261"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2262     exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2263    endif
2264    let b:netrw_lastfile = choice
2265"    call Decho("setl ro",'~'.expand("<slnum>"))
2266    setl ro nomod
2267
2268   ".........................................
2269   " NetRead: (dav) NetRead Method #6 {{{3
2270   elseif     b:netrw_method  == 6
2271"    call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2272
2273    if !executable(g:netrw_dav_cmd)
2274     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2275"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2276     return
2277    endif
2278    if g:netrw_dav_cmd =~ "curl"
2279     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2280    else
2281     " Construct execution string (four lines) which will be passed through filter
2282     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2283     new
2284     setl ff=unix
2285     if exists("g:netrw_port") && g:netrw_port != ""
2286      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2287     else
2288      NetrwKeepj put ='open '.g:netrw_machine
2289     endif
2290     if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2291      NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2292     endif
2293     NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2294     NetrwKeepj put ='quit'
2295
2296     " perform cadaver operation:
2297     NetrwKeepj norm! 1G"_dd
2298     call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2299     keepj bd!
2300    endif
2301    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2302    let b:netrw_lastfile = choice
2303
2304   ".........................................
2305   " NetRead: (rsync) NetRead Method #7 {{{3
2306   elseif     b:netrw_method  == 7
2307"    call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2308    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))
2309    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2310    let b:netrw_lastfile = choice
2311
2312   ".........................................
2313   " NetRead: (fetch) NetRead Method #8 {{{3
2314   "    fetch://[user@]host[:http]/path
2315   elseif     b:netrw_method  == 8
2316"    call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2317    if g:netrw_fetch_cmd == ""
2318     if !exists("g:netrw_quiet")
2319      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2320     endif
2321"     call Dret("NetRead")
2322     return
2323    endif
2324    if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2325     let netrw_option= "http"
2326    else
2327     let netrw_option= "ftp"
2328    endif
2329"    call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2330
2331    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2332     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))
2333    else
2334     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))
2335    endif
2336
2337    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2338    let b:netrw_lastfile = choice
2339"    call Decho("setl ro",'~'.expand("<slnum>"))
2340    setl ro nomod
2341
2342   ".........................................
2343   " NetRead: (sftp) NetRead Method #9 {{{3
2344   elseif     b:netrw_method  == 9
2345"    call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2346    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2347    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2348    let b:netrw_lastfile = choice
2349
2350   ".........................................
2351   " NetRead: (file) NetRead Method #10 {{{3
2352  elseif      b:netrw_method == 10 && exists("g:netrw_file_cmd")
2353"   "    call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2354   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2355   let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2356   let b:netrw_lastfile = choice
2357
2358   ".........................................
2359   " NetRead: Complain {{{3
2360   else
2361    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
2362   endif
2363  endwhile
2364
2365  " NetRead: cleanup {{{3
2366  if exists("b:netrw_method")
2367"   call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2368   unlet b:netrw_method
2369   unlet b:netrw_fname
2370  endif
2371  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
2372"   call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2373   NetrwKeepj call s:NetrwDelete(tmpfile)
2374  endif
2375  NetrwKeepj call s:NetrwOptionsRestore("w:")
2376
2377"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
2378endfun
2379
2380" ------------------------------------------------------------------------
2381" netrw#NetWrite: responsible for writing a file over the net {{{2
2382fun! netrw#NetWrite(...) range
2383"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
2384
2385  " NetWrite: option handling {{{3
2386  let mod= 0
2387  call s:NetrwOptionsSave("w:")
2388  call s:NetrwOptionsSafe(0)
2389
2390  " NetWrite: Get Temporary Filename {{{3
2391  let tmpfile= s:GetTempfile("")
2392  if tmpfile == ""
2393"   call Dret("netrw#NetWrite : unable to get a tempfile!")
2394   return
2395  endif
2396
2397  if a:0 == 0
2398   let ichoice = 0
2399  else
2400   let ichoice = 1
2401  endif
2402
2403  let curbufname= expand("%")
2404"  call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
2405  if &binary
2406   " For binary writes, always write entire file.
2407   " (line numbers don't really make sense for that).
2408   " Also supports the writing of tar and zip files.
2409"   call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2410   exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2411  elseif g:netrw_cygwin
2412   " write (selected portion of) file to temporary
2413   let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2414"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2415   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
2416  else
2417   " write (selected portion of) file to temporary
2418"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2419   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2420  endif
2421
2422  if curbufname == ""
2423   " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2424   " on the temporary file's name.  Deletion of the temporary file during
2425   " cleanup then causes an error message.
2426   0file!
2427  endif
2428
2429  " NetWrite: while choice loop: {{{3
2430  while ichoice <= a:0
2431
2432   " Process arguments: {{{4
2433   " attempt to repeat with previous host-file-etc
2434   if exists("b:netrw_lastfile") && a:0 == 0
2435"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2436    let choice = b:netrw_lastfile
2437    let ichoice= ichoice + 1
2438   else
2439    exe "let choice= a:" . ichoice
2440
2441    " Reconstruct Choice when choice starts with '"'
2442    if match(choice,"?") == 0
2443     echomsg 'NetWrite Usage:"'
2444     echomsg ':Nwrite machine:path                        uses rcp'
2445     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
2446     echomsg ':Nwrite "machine id password path"          uses ftp'
2447     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
2448     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
2449     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
2450     echomsg ':Nwrite rcp://machine/path                  uses rcp'
2451     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
2452     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2453     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
2454     sleep 4
2455     break
2456
2457    elseif match(choice,"^\"") != -1
2458     if match(choice,"\"$") != -1
2459       " case "..."
2460      let choice=strpart(choice,1,strlen(choice)-2)
2461     else
2462      "  case "... ... ..."
2463      let choice      = strpart(choice,1,strlen(choice)-1)
2464      let wholechoice = ""
2465
2466      while match(choice,"\"$") == -1
2467       let wholechoice= wholechoice . " " . choice
2468       let ichoice    = ichoice + 1
2469       if choice > a:0
2470       	if !exists("g:netrw_quiet")
2471	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2472	endif
2473"        call Dret("netrw#NetWrite")
2474        return
2475       endif
2476       let choice= a:{ichoice}
2477      endwhile
2478      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2479     endif
2480    endif
2481   endif
2482   let ichoice= ichoice + 1
2483"   call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
2484
2485   " Determine method of write (ftp, rcp, etc) {{{4
2486   NetrwKeepj call s:NetrwMethod(choice)
2487   if !exists("b:netrw_method") || b:netrw_method < 0
2488"    call Dfunc("netrw#NetWrite : unsupported method")
2489    return
2490   endif
2491
2492   " =============
2493   " NetWrite: Perform Protocol-Based Write {{{3
2494   " ============================
2495   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2496    echo "(netrw) Processing your write request..."
2497"    call Decho("Processing your write request...",'~'.expand("<slnum>"))
2498   endif
2499
2500   ".........................................
2501   " NetWrite: (rcp) NetWrite Method #1 {{{3
2502   if  b:netrw_method == 1
2503"    call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2504    if s:netrw_has_nt_rcp == 1
2505     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2506      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2507     else
2508      let uid_machine = g:netrw_machine .'.'. $USERNAME
2509     endif
2510    else
2511     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2512      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2513     else
2514      let uid_machine = g:netrw_machine
2515     endif
2516    endif
2517    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))
2518    let b:netrw_lastfile = choice
2519
2520   ".........................................
2521   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2522   elseif b:netrw_method == 2
2523"    call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2524    let netrw_fname = b:netrw_fname
2525
2526    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2527    let bhkeep      = &l:bh
2528    let curbuf      = bufnr("%")
2529    setl bh=hide
2530    keepj keepalt enew
2531
2532"    call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2533    setl ff=unix
2534    NetrwKeepj put =g:netrw_ftpmode
2535"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2536    if exists("g:netrw_ftpextracmd")
2537     NetrwKeepj put =g:netrw_ftpextracmd
2538"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2539    endif
2540    NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2541"    call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2542    if exists("g:netrw_port") && g:netrw_port != ""
2543     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2544    else
2545"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2546     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2547    endif
2548    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2549    if getline(1) !~ "^$"
2550     if !exists("g:netrw_quiet")
2551      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2552     endif
2553     let mod=1
2554    endif
2555
2556    " remove enew buffer (quietly)
2557    let filtbuf= bufnr("%")
2558    exe curbuf."b!"
2559    let &l:bh            = bhkeep
2560    exe filtbuf."bw!"
2561
2562    let b:netrw_lastfile = choice
2563
2564   ".........................................
2565   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2566   elseif b:netrw_method == 3
2567    " Construct execution string (three or more lines) which will be passed through filter
2568"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2569    let netrw_fname = b:netrw_fname
2570    let bhkeep      = &l:bh
2571
2572    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2573    let curbuf      = bufnr("%")
2574    setl bh=hide
2575    keepj keepalt enew
2576    setl ff=unix
2577
2578    if exists("g:netrw_port") && g:netrw_port != ""
2579     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2580"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2581    else
2582     NetrwKeepj put ='open '.g:netrw_machine
2583"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2584    endif
2585    if exists("g:netrw_uid") && g:netrw_uid != ""
2586     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2587      NetrwKeepj put =g:netrw_uid
2588"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2589      if exists("s:netrw_passwd") && s:netrw_passwd != ""
2590       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2591      endif
2592"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2593     elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2594      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2595"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2596     endif
2597    endif
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 put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2605"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2606    " save choice/id/password for future use
2607    let b:netrw_lastfile = choice
2608
2609    " perform ftp:
2610    " -i       : turns off interactive prompting from ftp
2611    " -n  unix : DON'T use <.netrc>, even though it exists
2612    " -n  win32: quit being obnoxious about password
2613    NetrwKeepj norm! 1G"_dd
2614    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2615    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2616    if getline(1) !~ "^$"
2617     if  !exists("g:netrw_quiet")
2618      call netrw#ErrorMsg(s:ERROR,getline(1),15)
2619     endif
2620     let mod=1
2621    endif
2622
2623    " remove enew buffer (quietly)
2624    let filtbuf= bufnr("%")
2625    exe curbuf."b!"
2626    let &l:bh= bhkeep
2627    exe filtbuf."bw!"
2628
2629   ".........................................
2630   " NetWrite: (scp) NetWrite Method #4 {{{3
2631   elseif     b:netrw_method == 4
2632"    call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2633    if exists("g:netrw_port") && g:netrw_port != ""
2634     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2635    else
2636     let useport= ""
2637    endif
2638    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2639    let b:netrw_lastfile = choice
2640
2641   ".........................................
2642   " NetWrite: (http) NetWrite Method #5 {{{3
2643   elseif     b:netrw_method == 5
2644"    call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2645    let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2646    if executable(curl)
2647     let url= g:netrw_choice
2648     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2649    elseif !exists("g:netrw_quiet")
2650     call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd.">".",16)
2651    endif
2652
2653   ".........................................
2654   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2655   elseif     b:netrw_method == 6
2656"    call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2657
2658    " Construct execution string (four lines) which will be passed through filter
2659    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2660    let bhkeep      = &l:bh
2661
2662    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2663    let curbuf      = bufnr("%")
2664    setl bh=hide
2665    keepj keepalt enew
2666
2667    setl ff=unix
2668    if exists("g:netrw_port") && g:netrw_port != ""
2669     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2670    else
2671     NetrwKeepj put ='open '.g:netrw_machine
2672    endif
2673    if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2674     NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2675    endif
2676    NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2677
2678    " perform cadaver operation:
2679    NetrwKeepj norm! 1G"_dd
2680    call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2681
2682    " remove enew buffer (quietly)
2683    let filtbuf= bufnr("%")
2684    exe curbuf."b!"
2685    let &l:bh            = bhkeep
2686    exe filtbuf."bw!"
2687
2688    let b:netrw_lastfile = choice
2689
2690   ".........................................
2691   " NetWrite: (rsync) NetWrite Method #7 {{{3
2692   elseif     b:netrw_method == 7
2693"    call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2694    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))
2695    let b:netrw_lastfile = choice
2696
2697   ".........................................
2698   " NetWrite: (sftp) NetWrite Method #9 {{{3
2699   elseif     b:netrw_method == 9
2700"    call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2701    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2702    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2703     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2704    else
2705     let uid_machine = g:netrw_machine
2706    endif
2707
2708    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2709    let bhkeep = &l:bh
2710    let curbuf = bufnr("%")
2711    setl bh=hide
2712    keepj keepalt enew
2713
2714    setl ff=unix
2715    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2716"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2717    let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2718    call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2719    let filtbuf= bufnr("%")
2720    exe curbuf."b!"
2721    let &l:bh            = bhkeep
2722    exe filtbuf."bw!"
2723    let b:netrw_lastfile = choice
2724
2725   ".........................................
2726   " NetWrite: Complain {{{3
2727   else
2728    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2729    let leavemod= 1
2730   endif
2731  endwhile
2732
2733  " NetWrite: Cleanup: {{{3
2734"  call Decho("cleanup",'~'.expand("<slnum>"))
2735  if s:FileReadable(tmpfile)
2736"   call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2737   call s:NetrwDelete(tmpfile)
2738  endif
2739  call s:NetrwOptionsRestore("w:")
2740
2741  if a:firstline == 1 && a:lastline == line("$")
2742   " restore modifiability; usually equivalent to set nomod
2743   let &mod= mod
2744"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2745  elseif !exists("leavemod")
2746   " indicate that the buffer has not been modified since last written
2747"   call Decho("set nomod",'~'.expand("<slnum>"))
2748   setl nomod
2749"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2750  endif
2751
2752"  call Dret("netrw#NetWrite")
2753endfun
2754
2755" ---------------------------------------------------------------------
2756" netrw#NetSource: source a remotely hosted vim script {{{2
2757" uses NetRead to get a copy of the file into a temporarily file,
2758"              then sources that file,
2759"              then removes that file.
2760fun! netrw#NetSource(...)
2761"  call Dfunc("netrw#NetSource() a:0=".a:0)
2762  if a:0 > 0 && a:1 == '?'
2763   " give help
2764   echomsg 'NetSource Usage:'
2765   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
2766   echomsg ':Nsource fetch://machine/path                 uses fetch'
2767   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2768   echomsg ':Nsource http[s]://[user@]machine/path        uses http  wget'
2769   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
2770   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
2771   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
2772   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2773   sleep 4
2774  else
2775   let i= 1
2776   while i <= a:0
2777    call netrw#NetRead(3,a:{i})
2778"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2779    if s:FileReadable(s:netrw_tmpfile)
2780"     call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2781     exe "so ".fnameescape(s:netrw_tmpfile)
2782"     call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2783     if delete(s:netrw_tmpfile)
2784      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2785     endif
2786     unlet s:netrw_tmpfile
2787    else
2788     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2789    endif
2790    let i= i + 1
2791   endwhile
2792  endif
2793"  call Dret("netrw#NetSource")
2794endfun
2795
2796" ---------------------------------------------------------------------
2797" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2798"                   (implements the :Ntree command)
2799fun! netrw#SetTreetop(iscmd,...)
2800"  call Dfunc("netrw#SetTreetop(iscmd=".a:iscmd." ".((a:0 > 0)? a:1 : "").") a:0=".a:0)
2801"  call Decho("w:netrw_treetop<".w:netrw_treetop.">")
2802
2803  " iscmd==0: netrw#SetTreetop called using gn mapping
2804  " iscmd==1: netrw#SetTreetop called using :Ntree from the command line
2805"  call Decho("(iscmd=".a:iscmd.": called using :Ntree from command line",'~'.expand("<slnum>"))
2806  " clear out the current tree
2807  if exists("w:netrw_treetop")
2808"   call Decho("clearing out current tree",'~'.expand("<slnum>"))
2809   let inittreetop= w:netrw_treetop
2810   unlet w:netrw_treetop
2811  endif
2812  if exists("w:netrw_treedict")
2813"   call Decho("freeing w:netrw_treedict",'~'.expand("<slnum>"))
2814   unlet w:netrw_treedict
2815  endif
2816"  call Decho("inittreetop<".(exists("inittreetop")? inittreetop : "n/a").">")
2817
2818  if (a:iscmd == 0 || a:1 == "") && exists("inittreetop")
2819   let treedir= s:NetrwTreePath(inittreetop)
2820"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2821  else
2822   if isdirectory(s:NetrwFile(a:1))
2823"    call Decho("a:1<".a:1."> is a directory",'~'.expand("<slnum>"))
2824    let treedir= a:1
2825   elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2826    let treedir= b:netrw_curdir."/".a:1
2827"    call Decho("a:1<".a:1."> is NOT a directory, using treedir<".treedir.">",'~'.expand("<slnum>"))
2828   else
2829    " normally the cursor is left in the message window.
2830    " However, here this results in the directory being listed in the message window, which is not wanted.
2831    let netrwbuf= bufnr("%")
2832    call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2833    exe bufwinnr(netrwbuf)."wincmd w"
2834    let treedir= "."
2835   endif
2836  endif
2837"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2838
2839  " determine if treedir is remote or local
2840  let islocal= expand("%") !~ '^\a\{3,}://'
2841"  call Decho("islocal=".islocal,'~'.expand("<slnum>"))
2842
2843  " browse the resulting directory
2844  if islocal
2845   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir))
2846  else
2847   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir))
2848  endif
2849
2850"  call Dret("netrw#SetTreetop")
2851endfun
2852
2853" ===========================================
2854" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
2855"    readcmd == %r : replace buffer with newly read file
2856"            == 0r : read file at top of buffer
2857"            == r  : read file after current line
2858"            == t  : leave file in temporary form (ie. don't read into buffer)
2859fun! s:NetrwGetFile(readcmd, tfile, method)
2860"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
2861
2862  " readcmd=='t': simply do nothing
2863  if a:readcmd == 't'
2864"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2865"   call Dret("NetrwGetFile : skip read of tfile<".a:tfile.">")
2866   return
2867  endif
2868
2869  " get name of remote filename (ie. url and all)
2870  let rfile= bufname("%")
2871"  call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
2872
2873  if exists("*NetReadFixup")
2874   " for the use of NetReadFixup (not otherwise used internally)
2875   let line2= line("$")
2876  endif
2877
2878  if a:readcmd[0] == '%'
2879  " get file into buffer
2880"   call Decho("get file into buffer",'~'.expand("<slnum>"))
2881
2882   " rename the current buffer to the temp file (ie. tfile)
2883   if g:netrw_cygwin
2884    let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2885   else
2886    let tfile= a:tfile
2887   endif
2888   call s:NetrwBufRename(tfile)
2889
2890   " edit temporary file (ie. read the temporary file in)
2891   if     rfile =~ '\.zip$'
2892"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2893    call zip#Browse(tfile)
2894   elseif rfile =~ '\.tar$'
2895"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2896    call tar#Browse(tfile)
2897   elseif rfile =~ '\.tar\.gz$'
2898"    call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2899    call tar#Browse(tfile)
2900   elseif rfile =~ '\.tar\.bz2$'
2901"    call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2902    call tar#Browse(tfile)
2903   elseif rfile =~ '\.tar\.xz$'
2904"    call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2905    call tar#Browse(tfile)
2906   elseif rfile =~ '\.txz$'
2907"    call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2908    call tar#Browse(tfile)
2909   else
2910"    call Decho("edit temporary file",'~'.expand("<slnum>"))
2911    NetrwKeepj e!
2912   endif
2913
2914   " rename buffer back to remote filename
2915   call s:NetrwBufRename(rfile)
2916
2917   " Detect filetype of local version of remote file.
2918   " Note that isk must not include a "/" for scripts.vim
2919   " to process this detection correctly.
2920"   call Decho("detect filetype of local version of remote file",'~'.expand("<slnum>"))
2921   let iskkeep= &l:isk
2922   setl isk-=/
2923   let &l:isk= iskkeep
2924"   call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
2925   let line1 = 1
2926   let line2 = line("$")
2927
2928  elseif !&ma
2929   " attempting to read a file after the current line in the file, but the buffer is not modifiable
2930   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2931"   call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2932   return
2933
2934  elseif s:FileReadable(a:tfile)
2935   " read file after current line
2936"   call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2937   let curline = line(".")
2938   let lastline= line("$")
2939"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline,'~'.expand("<slnum>"))
2940   exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2941   let line1= curline + 1
2942   let line2= line("$") - lastline + 1
2943
2944  else
2945   " not readable
2946"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2947"   call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2948   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2949"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2950   return
2951  endif
2952
2953  " User-provided (ie. optional) fix-it-up command
2954  if exists("*NetReadFixup")
2955"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2956   NetrwKeepj call NetReadFixup(a:method, line1, line2)
2957"  else " Decho
2958"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2959  endif
2960
2961  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
2962   " update the Buffers menu
2963   NetrwKeepj call s:UpdateBuffersMenu()
2964  endif
2965
2966"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
2967
2968 " make sure file is being displayed
2969"  redraw!
2970
2971"  call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2972"  call Dret("NetrwGetFile")
2973endfun
2974
2975" ------------------------------------------------------------------------
2976" s:NetrwMethod:  determine method of transfer {{{2
2977" Input:
2978"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
2979" Output:
2980"  b:netrw_method= 1: rcp
2981"                  2: ftp + <.netrc>
2982"	           3: ftp + machine, id, password, and [path]filename
2983"	           4: scp
2984"	           5: http[s] (wget)
2985"	           6: dav
2986"	           7: rsync
2987"	           8: fetch
2988"	           9: sftp
2989"	          10: file
2990"  g:netrw_machine= hostname
2991"  b:netrw_fname  = filename
2992"  g:netrw_port   = optional port number (for ftp)
2993"  g:netrw_choice = copy of input url (choice)
2994fun! s:NetrwMethod(choice)
2995"   call Dfunc("s:NetrwMethod(a:choice<".a:choice.">)")
2996
2997   " sanity check: choice should have at least three slashes in it
2998   if strlen(substitute(a:choice,'[^/]','','g')) < 3
2999    call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
3000    let b:netrw_method = -1
3001"    call Dret("s:NetrwMethod : incorrect url format<".a:choice.">")
3002    return
3003   endif
3004
3005   " record current g:netrw_machine, if any
3006   " curmachine used if protocol == ftp and no .netrc
3007   if exists("g:netrw_machine")
3008    let curmachine= g:netrw_machine
3009"    call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
3010   else
3011    let curmachine= "N O T A HOST"
3012   endif
3013   if exists("g:netrw_port")
3014    let netrw_port= g:netrw_port
3015   endif
3016
3017   " insure that netrw_ftp_cmd starts off every method determination
3018   " with the current g:netrw_ftp_cmd
3019   let s:netrw_ftp_cmd= g:netrw_ftp_cmd
3020
3021  " initialization
3022  let b:netrw_method  = 0
3023  let g:netrw_machine = ""
3024  let b:netrw_fname   = ""
3025  let g:netrw_port    = ""
3026  let g:netrw_choice  = a:choice
3027
3028  " Patterns:
3029  " mipf     : a:machine a:id password filename	     Use ftp
3030  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
3031  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
3032  " rcpurm   : rcp://[user@]host/filename	     Use rcp
3033  " rcphf    : [user@]host:filename		     Use rcp
3034  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
3035  " httpurm  : http[s]://[user@]host/filename	     Use wget
3036  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
3037  " rsyncurm : rsync://host[:port]/path              Use rsync
3038  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
3039  " sftpurm  : sftp://[user@]host/filename  Use scp
3040  " fileurm  : file://[user@]host/filename	     Use elinks or links
3041  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
3042  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
3043  let ftpurm   = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
3044  let rcpurm   = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
3045  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
3046  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
3047  let httpurm  = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
3048  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
3049  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
3050  let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
3051  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
3052  let fileurm  = '^file\=://\(.*\)$'
3053
3054"  call Decho("determine method:",'~'.expand("<slnum>"))
3055  " Determine Method
3056  " Method#1: rcp://user@hostname/...path-to-file {{{3
3057  if match(a:choice,rcpurm) == 0
3058"   call Decho("rcp://...",'~'.expand("<slnum>"))
3059   let b:netrw_method  = 1
3060   let userid          = substitute(a:choice,rcpurm,'\1',"")
3061   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
3062   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
3063   if userid != ""
3064    let g:netrw_uid= userid
3065   endif
3066
3067  " Method#4: scp://user@hostname/...path-to-file {{{3
3068  elseif match(a:choice,scpurm) == 0
3069"   call Decho("scp://...",'~'.expand("<slnum>"))
3070   let b:netrw_method  = 4
3071   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
3072   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
3073   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
3074
3075  " Method#5: http[s]://user@hostname/...path-to-file {{{3
3076  elseif match(a:choice,httpurm) == 0
3077"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3078   let b:netrw_method = 5
3079   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
3080   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
3081   let b:netrw_http   = (a:choice =~ '^https:')? "https" : "http"
3082
3083  " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
3084  elseif match(a:choice,davurm) == 0
3085"   call Decho("dav://...",'~'.expand("<slnum>"))
3086   let b:netrw_method= 6
3087   if a:choice =~ 'davs:'
3088    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
3089   else
3090    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
3091   endif
3092   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
3093
3094   " Method#7: rsync://user@hostname/...path-to-file {{{3
3095  elseif match(a:choice,rsyncurm) == 0
3096"   call Decho("rsync://...",'~'.expand("<slnum>"))
3097   let b:netrw_method = 7
3098   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
3099   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
3100
3101   " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
3102  elseif match(a:choice,ftpurm) == 0
3103"   call Decho("ftp://...",'~'.expand("<slnum>"))
3104   let userid	      = substitute(a:choice,ftpurm,'\2',"")
3105   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
3106   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
3107   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
3108"   call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3109   if userid != ""
3110    let g:netrw_uid= userid
3111   endif
3112
3113   if curmachine != g:netrw_machine
3114    if exists("s:netrw_hup[".g:netrw_machine."]")
3115     call NetUserPass("ftp:".g:netrw_machine)
3116    elseif exists("s:netrw_passwd")
3117     " if there's a change in hostname, require password re-entry
3118     unlet s:netrw_passwd
3119    endif
3120    if exists("netrw_port")
3121     unlet netrw_port
3122    endif
3123   endif
3124
3125   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3126    let b:netrw_method = 3
3127   else
3128    let host= substitute(g:netrw_machine,'\..*$','','')
3129    if exists("s:netrw_hup[host]")
3130     call NetUserPass("ftp:".host)
3131
3132    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~# '-[sS]:'
3133"     call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3134"     call Decho("          g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3135     if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
3136      let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3137"      call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3138     endif
3139     let b:netrw_method= 2
3140    elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3141"     call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3142     let b:netrw_method= 2
3143    else
3144     if !exists("g:netrw_uid") || g:netrw_uid == ""
3145      call NetUserPass()
3146     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3147      call NetUserPass(g:netrw_uid)
3148    " else just use current g:netrw_uid and s:netrw_passwd
3149     endif
3150     let b:netrw_method= 3
3151    endif
3152   endif
3153
3154  " Method#8: fetch {{{3
3155  elseif match(a:choice,fetchurm) == 0
3156"   call Decho("fetch://...",'~'.expand("<slnum>"))
3157   let b:netrw_method = 8
3158   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3159   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3160   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3161   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
3162
3163   " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
3164  elseif match(a:choice,mipf) == 0
3165"   call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
3166   let b:netrw_method  = 3
3167   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3168   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
3169   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
3170   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
3171   call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
3172
3173  " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3174  elseif match(a:choice,mf) == 0
3175"   call Decho("(ftp) host file",'~'.expand("<slnum>"))
3176   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3177    let b:netrw_method  = 3
3178    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3179    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3180
3181   elseif s:FileReadable(expand("$HOME/.netrc"))
3182    let b:netrw_method  = 2
3183    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3184    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3185   endif
3186
3187  " Method#9: sftp://user@hostname/...path-to-file {{{3
3188  elseif match(a:choice,sftpurm) == 0
3189"   call Decho("sftp://...",'~'.expand("<slnum>"))
3190   let b:netrw_method = 9
3191   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3192   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
3193
3194  " Method#1: Issue an rcp: hostname:filename"  (this one should be last) {{{3
3195  elseif match(a:choice,rcphf) == 0
3196"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3197   let b:netrw_method  = 1
3198   let userid          = substitute(a:choice,rcphf,'\2',"")
3199   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3200   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
3201"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3202"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3203"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3204"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3205   if userid != ""
3206    let g:netrw_uid= userid
3207   endif
3208
3209   " Method#10: file://user@hostname/...path-to-file {{{3
3210  elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
3211"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3212   let b:netrw_method = 10
3213   let b:netrw_fname  = substitute(a:choice,fileurm,'\1',"")
3214"   call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
3215
3216  " Cannot Determine Method {{{3
3217  else
3218   if !exists("g:netrw_quiet")
3219    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3220   endif
3221   let b:netrw_method  = -1
3222  endif
3223  "}}}3
3224
3225  if g:netrw_port != ""
3226   " remove any leading [:#] from port number
3227   let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
3228  elseif exists("netrw_port")
3229   " retain port number as implicit for subsequent ftp operations
3230   let g:netrw_port= netrw_port
3231  endif
3232
3233"  call Decho("a:choice       <".a:choice.">",'~'.expand("<slnum>"))
3234"  call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3235"  call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3236"  call Decho("g:netrw_port   <".g:netrw_port.">",'~'.expand("<slnum>"))
3237"  if exists("g:netrw_uid")		"Decho
3238"   call Decho("g:netrw_uid    <".g:netrw_uid.">",'~'.expand("<slnum>"))
3239"  endif					"Decho
3240"  if exists("s:netrw_passwd")		"Decho
3241"   call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3242"  endif					"Decho
3243"  call Decho("b:netrw_fname  <".b:netrw_fname.">",'~'.expand("<slnum>"))
3244"  call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
3245endfun
3246
3247" ------------------------------------------------------------------------
3248" NetReadFixup: this sort of function is typically written by the user {{{2
3249"               to handle extra junk that their system's ftp dumps
3250"               into the transfer.  This function is provided as an
3251"               example and as a fix for a Windows 95 problem: in my
3252"               experience, win95's ftp always dumped four blank lines
3253"               at the end of the transfer.
3254if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
3255 fun! NetReadFixup(method, line1, line2)
3256"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
3257
3258   " sanity checks -- attempt to convert inputs to integers
3259   let method = a:method + 0
3260   let line1  = a:line1 + 0
3261   let line2  = a:line2 + 0
3262   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
3263"    call Dret("NetReadFixup")
3264    return
3265   endif
3266
3267   if method == 3   " ftp (no <.netrc>)
3268    let fourblanklines= line2 - 3
3269    if fourblanklines >= line1
3270     exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
3271     call histdel("/",-1)
3272    endif
3273   endif
3274
3275"   call Dret("NetReadFixup")
3276 endfun
3277endif
3278
3279" ---------------------------------------------------------------------
3280" NetUserPass: set username and password for subsequent ftp transfer {{{2
3281"   Usage:  :call NetUserPass()		               -- will prompt for userid and password
3282"	    :call NetUserPass("uid")	               -- will prompt for password
3283"	    :call NetUserPass("uid","password")        -- sets global userid and password
3284"	    :call NetUserPass("ftp:host")              -- looks up userid and password using hup dictionary
3285"	    :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
3286fun! NetUserPass(...)
3287
3288" call Dfunc("NetUserPass() a:0=".a:0)
3289
3290 if !exists('s:netrw_hup')
3291  let s:netrw_hup= {}
3292 endif
3293
3294 if a:0 == 0
3295  " case: no input arguments
3296
3297  " change host and username if not previously entered; get new password
3298  if !exists("g:netrw_machine")
3299   let g:netrw_machine= input('Enter hostname: ')
3300  endif
3301  if !exists("g:netrw_uid") || g:netrw_uid == ""
3302   " get username (user-id) via prompt
3303   let g:netrw_uid= input('Enter username: ')
3304  endif
3305  " get password via prompting
3306  let s:netrw_passwd= inputsecret("Enter Password: ")
3307
3308  " set up hup database
3309  let host = substitute(g:netrw_machine,'\..*$','','')
3310  if !exists('s:netrw_hup[host]')
3311   let s:netrw_hup[host]= {}
3312  endif
3313  let s:netrw_hup[host].uid    = g:netrw_uid
3314  let s:netrw_hup[host].passwd = s:netrw_passwd
3315
3316 elseif a:0 == 1
3317  " case: one input argument
3318
3319  if a:1 =~ '^ftp:'
3320   " get host from ftp:... url
3321   " access userid and password from hup (host-user-passwd) dictionary
3322"   call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3323   let host = substitute(a:1,'^ftp:','','')
3324   let host = substitute(host,'\..*','','')
3325   if exists("s:netrw_hup[host]")
3326    let g:netrw_uid    = s:netrw_hup[host].uid
3327    let s:netrw_passwd = s:netrw_hup[host].passwd
3328"    call Decho("get s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3329"    call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3330   else
3331    let g:netrw_uid    = input("Enter UserId: ")
3332    let s:netrw_passwd = inputsecret("Enter Password: ")
3333   endif
3334
3335  else
3336   " case: one input argument, not an url.  Using it as a new user-id.
3337"   call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3338   if exists("g:netrw_machine")
3339    if g:netrw_machine =~ '[0-9.]\+'
3340     let host= g:netrw_machine
3341    else
3342     let host= substitute(g:netrw_machine,'\..*$','','')
3343    endif
3344   else
3345    let g:netrw_machine= input('Enter hostname: ')
3346   endif
3347   let g:netrw_uid = a:1
3348"   call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3349   if exists("g:netrw_passwd")
3350    " ask for password if one not previously entered
3351    let s:netrw_passwd= g:netrw_passwd
3352   else
3353    let s:netrw_passwd = inputsecret("Enter Password: ")
3354   endif
3355  endif
3356
3357"  call Decho("host<".host.">",'~'.expand("<slnum>"))
3358  if exists("host")
3359   if !exists('s:netrw_hup[host]')
3360    let s:netrw_hup[host]= {}
3361   endif
3362   let s:netrw_hup[host].uid    = g:netrw_uid
3363   let s:netrw_hup[host].passwd = s:netrw_passwd
3364  endif
3365
3366 elseif a:0 == 2
3367  let g:netrw_uid    = a:1
3368  let s:netrw_passwd = a:2
3369
3370 elseif a:0 == 3
3371  " enter hostname, user-id, and password into the hup dictionary
3372  let host = substitute(a:1,'^\a\+:','','')
3373  let host = substitute(host,'\..*$','','')
3374  if !exists('s:netrw_hup[host]')
3375   let s:netrw_hup[host]= {}
3376  endif
3377  let s:netrw_hup[host].uid    = a:2
3378  let s:netrw_hup[host].passwd = a:3
3379  let g:netrw_uid              = s:netrw_hup[host].uid
3380  let s:netrw_passwd           = s:netrw_hup[host].passwd
3381"  call Decho("set s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3382"  call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3383 endif
3384
3385" call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
3386endfun
3387
3388" =================================
3389"  Shared Browsing Support:    {{{1
3390" =================================
3391
3392" ---------------------------------------------------------------------
3393" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3394fun! s:ExplorePatHls(pattern)
3395"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
3396  let repat= substitute(a:pattern,'^**/\{1,2}','','')
3397"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3398  let repat= escape(repat,'][.\')
3399"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3400  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
3401"  call Dret("s:ExplorePatHls repat<".repat.">")
3402  return repat
3403endfun
3404
3405" ---------------------------------------------------------------------
3406"  s:NetrwBookHistHandler: {{{2
3407"    0: (user: <mb>)   bookmark current directory
3408"    1: (user: <gb>)   change to the bookmarked directory
3409"    2: (user: <qb>)   list bookmarks
3410"    3: (browsing)     records current directory history
3411"    4: (user: <u>)    go up   (previous) directory, using history
3412"    5: (user: <U>)    go down (next)     directory, using history
3413"    6: (user: <mB>)   delete bookmark
3414fun! s:NetrwBookHistHandler(chg,curdir)
3415"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhistcnt." histmax=".g:netrw_dirhistmax)
3416  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3417"   "  call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3418   return
3419  endif
3420
3421  let ykeep    = @@
3422  let curbufnr = bufnr("%")
3423
3424  if a:chg == 0
3425   " bookmark the current directory
3426"   call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3427   if exists("s:netrwmarkfilelist_{curbufnr}")
3428    call s:NetrwBookmark(0)
3429    echo "bookmarked marked files"
3430   else
3431    call s:MakeBookmark(a:curdir)
3432    echo "bookmarked the current directory"
3433   endif
3434
3435  elseif a:chg == 1
3436   " change to the bookmarked directory
3437"   call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3438   if exists("g:netrw_bookmarklist[v:count-1]")
3439"    call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3440    exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3441   else
3442    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3443   endif
3444
3445  elseif a:chg == 2
3446"   redraw!
3447   let didwork= 0
3448   " list user's bookmarks
3449"   call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3450   if exists("g:netrw_bookmarklist")
3451"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3452    let cnt= 1
3453    for bmd in g:netrw_bookmarklist
3454"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3455     echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3456     let didwork = 1
3457     let cnt     = cnt + 1
3458    endfor
3459   endif
3460
3461   " list directory history
3462   " Note: history is saved only when PerformListing is done;
3463   "       ie. when netrw can re-use a netrw buffer, the current directory is not saved in the history.
3464   let cnt     = g:netrw_dirhistcnt
3465   let first   = 1
3466   let histcnt = 0
3467   if g:netrw_dirhistmax > 0
3468    while ( first || cnt != g:netrw_dirhistcnt )
3469"    call Decho("first=".first." cnt=".cnt." dirhistcnt=".g:netrw_dirhistcnt,'~'.expand("<slnum>"))
3470     if exists("g:netrw_dirhist_{cnt}")
3471"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3472      echo printf("Netrw  History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3473      let didwork= 1
3474     endif
3475     let histcnt = histcnt + 1
3476     let first   = 0
3477     let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3478     if cnt < 0
3479      let cnt= cnt + g:netrw_dirhistmax
3480     endif
3481    endwhile
3482   else
3483    let g:netrw_dirhistcnt= 0
3484   endif
3485   if didwork
3486    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3487   endif
3488
3489  elseif a:chg == 3
3490   " saves most recently visited directories (when they differ)
3491"   call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3492   if !exists("g:netrw_dirhistcnt") || !exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") || g:netrw_dirhist_{g:netrw_dirhistcnt} != a:curdir
3493    if g:netrw_dirhistmax > 0
3494     let g:netrw_dirhistcnt                   = ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3495     let g:netrw_dirhist_{g:netrw_dirhistcnt} = a:curdir
3496    endif
3497"    call Decho("save dirhist#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3498   endif
3499
3500  elseif a:chg == 4
3501   " u: change to the previous directory stored on the history list
3502"   call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
3503   if g:netrw_dirhistmax > 0
3504    let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - v:count1 ) % g:netrw_dirhistmax
3505    if g:netrw_dirhistcnt < 0
3506     let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3507    endif
3508   else
3509    let g:netrw_dirhistcnt= 0
3510   endif
3511   if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3512"    call Decho("changedir u#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3513    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3514     setl ma noro
3515"     call Decho("setl ma noro",'~'.expand("<slnum>"))
3516     sil! NetrwKeepj %d _
3517     setl nomod
3518"     call Decho("setl nomod",'~'.expand("<slnum>"))
3519"     call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3520    endif
3521"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3522    exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3523   else
3524    if g:netrw_dirhistmax > 0
3525     let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + v:count1 ) % g:netrw_dirhistmax
3526    else
3527     let g:netrw_dirhistcnt= 0
3528    endif
3529    echo "Sorry, no predecessor directory exists yet"
3530   endif
3531
3532  elseif a:chg == 5
3533   " U: change to the subsequent directory stored on the history list
3534"   call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3535   if g:netrw_dirhistmax > 0
3536    let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3537    if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3538"    call Decho("changedir U#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3539     if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3540"      call Decho("setl ma noro",'~'.expand("<slnum>"))
3541      setl ma noro
3542      sil! NetrwKeepj %d _
3543"      call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3544"      call Decho("setl nomod",'~'.expand("<slnum>"))
3545      setl nomod
3546"      call Decho("(set nomod)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3547     endif
3548"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3549     exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3550    else
3551     let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - 1 ) % g:netrw_dirhistmax
3552     if g:netrw_dirhistcnt < 0
3553      let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3554     endif
3555     echo "Sorry, no successor directory exists yet"
3556    endif
3557   else
3558    let g:netrw_dirhistcnt= 0
3559    echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
3560   endif
3561
3562  elseif a:chg == 6
3563"   call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3564   if exists("s:netrwmarkfilelist_{curbufnr}")
3565    call s:NetrwBookmark(1)
3566    echo "removed marked files from bookmarks"
3567   else
3568    " delete the v:count'th bookmark
3569    let iremove = v:count
3570    let dremove = g:netrw_bookmarklist[iremove - 1]
3571"    call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3572    call s:MergeBookmarks()
3573"    call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3574    NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3575    echo "removed ".dremove." from g:netrw_bookmarklist"
3576"    call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3577   endif
3578"   call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3579  endif
3580  call s:NetrwBookmarkMenu()
3581  call s:NetrwTgtMenu()
3582  let @@= ykeep
3583"  call Dret("s:NetrwBookHistHandler")
3584endfun
3585
3586" ---------------------------------------------------------------------
3587" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
3588"  Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
3589"                      Sister function: s:NetrwBookHistSave()
3590fun! s:NetrwBookHistRead()
3591"  call Dfunc("s:NetrwBookHistRead()")
3592  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3593"   call Dret("s:NetrwBookHistRead - nothing read (suppressed due to dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a").")")
3594   return
3595  endif
3596  let ykeep= @@
3597
3598  " read bookmarks
3599  if !exists("s:netrw_initbookhist")
3600   let home    = s:NetrwHome()
3601   let savefile= home."/.netrwbook"
3602   if filereadable(s:NetrwFile(savefile))
3603"    call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3604    exe "keepalt NetrwKeepj so ".savefile
3605   endif
3606
3607   " read history
3608   if g:netrw_dirhistmax > 0
3609    let savefile= home."/.netrwhist"
3610    if filereadable(s:NetrwFile(savefile))
3611"    call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3612     exe "keepalt NetrwKeepj so ".savefile
3613    endif
3614    let s:netrw_initbookhist= 1
3615    au VimLeave * call s:NetrwBookHistSave()
3616   endif
3617  endif
3618
3619  let @@= ykeep
3620"  call Decho("dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a"),'~'.expand("<slnum>"))
3621"  call Decho("dirhistcnt=".(exists("g:netrw_dirhistcnt")? g:netrw_dirhistcnt : "n/a"),'~'.expand("<slnum>"))
3622"  call Dret("s:NetrwBookHistRead")
3623endfun
3624
3625" ---------------------------------------------------------------------
3626" s:NetrwBookHistSave: this function saves bookmarks and history to files {{{2
3627"                      Sister function: s:NetrwBookHistRead()
3628"                      I used to do this via viminfo but that appears to
3629"                      be unreliable for long-term storage
3630"                      If g:netrw_dirhistmax is <= 0, no history or bookmarks
3631"                      will be saved.
3632"                      (s:NetrwBookHistHandler(3,...) used to record history)
3633fun! s:NetrwBookHistSave()
3634"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt)
3635  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3636"   call Dret("s:NetrwBookHistSave : nothing saved (dirhistmax=".g:netrw_dirhistmax.")")
3637   return
3638  endif
3639
3640  let savefile= s:NetrwHome()."/.netrwhist"
3641"  call Decho("savefile<".savefile.">",'~'.expand("<slnum>"))
3642  1split
3643  call s:NetrwEnew()
3644"  call Decho("case g:netrw_use_noswf=".g:netrw_use_noswf.(exists("+acd")? " +acd" : " -acd"),'~'.expand("<slnum>"))
3645  if g:netrw_use_noswf
3646   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
3647  else
3648   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
3649  endif
3650  setl nocin noai noci magic nospell nohid wig= noaw
3651  setl ma noro write
3652  if exists("+acd") | setl noacd | endif
3653  sil! NetrwKeepj keepalt %d _
3654
3655  " rename enew'd file: .netrwhist -- no attempt to merge
3656  " record dirhistmax and current dirhistcnt
3657  " save history
3658"  call Decho("saving history: dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt." lastline=".line("$"),'~'.expand("<slnum>"))
3659  sil! keepalt file .netrwhist
3660  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
3661  call setline(2,"let g:netrw_dirhistcnt =".g:netrw_dirhistcnt)
3662  if g:netrw_dirhistmax > 0
3663   let lastline = line("$")
3664   let cnt      = g:netrw_dirhistcnt
3665   let first    = 1
3666   while ( first || cnt != g:netrw_dirhistcnt )
3667    let lastline= lastline + 1
3668    if exists("g:netrw_dirhist_{cnt}")
3669     call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3670"     call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("<slnum>"))
3671    endif
3672    let first   = 0
3673    let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3674    if cnt < 0
3675     let cnt= cnt + g:netrw_dirhistmax
3676    endif
3677   endwhile
3678   exe "sil! w! ".savefile
3679"   call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
3680  endif
3681
3682  " save bookmarks
3683  sil NetrwKeepj %d _
3684  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
3685"   call Decho("saving bookmarks",'~'.expand("<slnum>"))
3686   " merge and write .netrwbook
3687   let savefile= s:NetrwHome()."/.netrwbook"
3688
3689   if filereadable(s:NetrwFile(savefile))
3690    let booklist= deepcopy(g:netrw_bookmarklist)
3691    exe "sil NetrwKeepj keepalt so ".savefile
3692    for bdm in booklist
3693     if index(g:netrw_bookmarklist,bdm) == -1
3694      call add(g:netrw_bookmarklist,bdm)
3695     endif
3696    endfor
3697    call sort(g:netrw_bookmarklist)
3698   endif
3699
3700   " construct and save .netrwbook
3701   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3702   exe "sil! w! ".savefile
3703"   call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
3704  endif
3705
3706  " cleanup -- remove buffer used to construct history
3707  let bgone= bufnr("%")
3708  q!
3709  exe "keepalt ".bgone."bwipe!"
3710
3711"  call Dret("s:NetrwBookHistSave")
3712endfun
3713
3714" ---------------------------------------------------------------------
3715" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3716"  list of the contents of a local or remote directory.  It is assumed that the
3717"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3718"  with the requested remote hostname first.
3719"    Often called via:  Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
3720fun! s:NetrwBrowse(islocal,dirname)
3721  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
3722"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
3723"  call Decho("fyi: modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
3724"  call Decho("fyi: tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3725"  call Dredir("ls!","s:NetrwBrowse")
3726
3727  " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3728  " This is useful when one edits a local file, then :e ., then :Rex
3729  if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
3730   let w:netrw_rexfile= bufname("#")
3731"   call Decho("setting w:netrw_rexfile<".w:netrw_rexfile."> win#".winnr(),'~'.expand("<slnum>"))
3732  endif
3733
3734  " s:NetrwBrowse : initialize history {{{3
3735  if !exists("s:netrw_initbookhist")
3736   NetrwKeepj call s:NetrwBookHistRead()
3737  endif
3738
3739  " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
3740  if a:dirname !~ '^\a\{3,}://'
3741   let dirname= simplify(a:dirname)
3742"   call Decho("simplified dirname<".dirname.">")
3743  else
3744   let dirname= a:dirname
3745  endif
3746
3747  " repoint t:netrw_lexbufnr if appropriate
3748  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
3749"   call Decho("set repointlexbufnr to true!")
3750   let repointlexbufnr= 1
3751  endif
3752
3753  " s:NetrwBrowse : sanity checks: {{{3
3754  if exists("s:netrw_skipbrowse")
3755   unlet s:netrw_skipbrowse
3756"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("<slnum>"))
3757"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed")
3758   return
3759  endif
3760  if !exists("*shellescape")
3761   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3762"   call Dret("s:NetrwBrowse : missing shellescape()")
3763   return
3764  endif
3765  if !exists("*fnameescape")
3766   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3767"   call Dret("s:NetrwBrowse : missing fnameescape()")
3768   return
3769  endif
3770
3771  " s:NetrwBrowse : save options: {{{3
3772  call s:NetrwOptionsSave("w:")
3773
3774  " s:NetrwBrowse : re-instate any marked files {{{3
3775  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3776   if exists("s:netrwmarkfilelist_{bufnr('%')}")
3777"    call Decho("clearing marked files",'~'.expand("<slnum>"))
3778    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3779   endif
3780  endif
3781
3782  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
3783   " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3784"   call Decho("handle w:netrw_acdkeep:",'~'.expand("<slnum>"))
3785"   call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("<slnum>"))
3786   if s:NetrwLcd(dirname)
3787"    call Dret("s:NetrwBrowse : lcd failure")
3788    return
3789   endif
3790   "   call s:NetrwOptionsSafe() " tst952 failed with this enabled.
3791"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
3792
3793  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
3794   " s:NetrwBrowse :  remote regular file handler {{{3
3795"   call Decho("handle remote regular file: dirname<".dirname.">",'~'.expand("<slnum>"))
3796   if bufname(dirname) != ""
3797"    call Decho("edit buf#".bufname(dirname)." in win#".winnr(),'~'.expand("<slnum>"))
3798    exe "NetrwKeepj b ".bufname(dirname)
3799   else
3800    " attempt transfer of remote regular file
3801"    call Decho("attempt transfer as regular file<".dirname.">",'~'.expand("<slnum>"))
3802
3803    " remove any filetype indicator from end of dirname, except for the
3804    " "this is a directory" indicator (/).
3805    " There shouldn't be one of those here, anyway.
3806    let path= substitute(dirname,'[*=@|]\r\=$','','e')
3807"    call Decho("new path<".path.">",'~'.expand("<slnum>"))
3808    call s:RemotePathAnalysis(dirname)
3809
3810    " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3811    call s:NetrwEnew(dirname)
3812    call s:NetrwOptionsSafe(a:islocal)
3813    setl ma noro
3814"    call Decho("setl ma noro",'~'.expand("<slnum>"))
3815    let b:netrw_curdir = dirname
3816    let url            = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3817    call s:NetrwBufRename(url)
3818    exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3819    sil call netrw#NetRead(2,url)
3820    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3821"    call Decho("url<".url.">",'~'.expand("<slnum>"))
3822"    call Decho("s:path<".s:path.">",'~'.expand("<slnum>"))
3823"    call Decho("s:fname<".s:fname.">",'~'.expand("<slnum>"))
3824    if s:path =~ '.bz2'
3825     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3826    elseif s:path =~ '.gz'
3827     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3828    elseif s:path =~ '.gz'
3829     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3830    else
3831     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3832    endif
3833   endif
3834
3835   " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3836   call s:SetBufWinVars()
3837   call s:NetrwOptionsRestore("w:")
3838"   call Decho("setl ma nomod",'~'.expand("<slnum>"))
3839   setl ma nomod noro
3840"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3841
3842"   call Dret("s:NetrwBrowse : file<".s:fname.">")
3843   return
3844  endif
3845
3846  " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
3847  call s:UseBufWinVars()
3848
3849  " set up some variables {{{3
3850  let b:netrw_browser_active = 1
3851  let dirname                = dirname
3852  let s:last_sort_by         = g:netrw_sort_by
3853
3854  " set up menu {{{3
3855  NetrwKeepj call s:NetrwMenu(1)
3856
3857  " get/set-up buffer {{{3
3858"  call Decho("saving position across a buffer refresh",'~'.expand("<slnum>"))
3859  let svpos  = winsaveview()
3860"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3861  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
3862
3863  " maintain markfile highlighting
3864  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3865   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3866" "   call Decho("bufnr(%)=".bufnr('%'),'~'.expand("<slnum>"))
3867" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
3868    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3869   else
3870" "   call Decho("2match none",'~'.expand("<slnum>"))
3871    2match none
3872   endif
3873  endif
3874  if reusing && line("$") > 1
3875   call s:NetrwOptionsRestore("w:")
3876"   call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3877   setl noma nomod nowrap
3878"   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>"))
3879"   call Dret("s:NetrwBrowse : re-using not-cleared buffer")
3880   return
3881  endif
3882
3883  " set b:netrw_curdir to the new directory name {{{3
3884"  call Decho("set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")",'~'.expand("<slnum>"))
3885  let b:netrw_curdir= dirname
3886  if b:netrw_curdir =~ '[/\\]$'
3887   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
3888  endif
3889  if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
3890   let b:netrw_curdir= b:netrw_curdir."/"
3891  endif
3892  if b:netrw_curdir == ''
3893   if has("amiga")
3894    " On the Amiga, the empty string connotes the current directory
3895    let b:netrw_curdir= getcwd()
3896   else
3897    " under unix, when the root directory is encountered, the result
3898    " from the preceding substitute is an empty string.
3899    let b:netrw_curdir= '/'
3900   endif
3901  endif
3902  if !a:islocal && b:netrw_curdir !~ '/$'
3903   let b:netrw_curdir= b:netrw_curdir.'/'
3904  endif
3905"  call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
3906
3907  " ------------
3908  " (local only) {{{3
3909  " ------------
3910  if a:islocal
3911"   call Decho("local only:",'~'.expand("<slnum>"))
3912
3913   " Set up ShellCmdPost handling.  Append current buffer to browselist
3914   call s:LocalFastBrowser()
3915
3916  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3917   if !g:netrw_keepdir
3918"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
3919"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("<slnum>"))
3920    if !exists("&l:acd") || !&l:acd
3921     if s:NetrwLcd(b:netrw_curdir)
3922"      call Dret("s:NetrwBrowse : lcd failure")
3923      return
3924     endif
3925    endif
3926   endif
3927
3928  " --------------------------------
3929  " remote handling: {{{3
3930  " --------------------------------
3931  else
3932"   call Decho("remote only:",'~'.expand("<slnum>"))
3933
3934   " analyze dirname and g:netrw_list_cmd {{{3
3935"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>"))
3936   if dirname =~# "^NetrwTreeListing\>"
3937    let dirname= b:netrw_curdir
3938"    call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>"))
3939   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3940    let dirname= substitute(b:netrw_curdir,'\\','/','g')
3941    if dirname !~ '/$'
3942     let dirname= dirname.'/'
3943    endif
3944    let b:netrw_curdir = dirname
3945"    call Decho("(liststyle is TREELIST) dirname<".dirname.">",'~'.expand("<slnum>"))
3946   else
3947    let dirname = substitute(dirname,'\\','/','g')
3948"    call Decho("(normal) dirname<".dirname.">",'~'.expand("<slnum>"))
3949   endif
3950
3951   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3952   if dirname !~ dirpat
3953    if !exists("g:netrw_quiet")
3954     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3955    endif
3956    NetrwKeepj call s:NetrwOptionsRestore("w:")
3957"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3958    setl noma nomod nowrap
3959"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3960"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
3961    return
3962   endif
3963   let b:netrw_curdir= dirname
3964"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("<slnum>"))
3965  endif  " (additional remote handling)
3966
3967  " -------------------------------
3968  " Perform Directory Listing: {{{3
3969  " -------------------------------
3970  NetrwKeepj call s:NetrwMaps(a:islocal)
3971  NetrwKeepj call s:NetrwCommands(a:islocal)
3972  NetrwKeepj call s:PerformListing(a:islocal)
3973
3974  " restore option(s)
3975  call s:NetrwOptionsRestore("w:")
3976"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3977
3978  " If there is a rexposn: restore position with rexposn
3979  " Otherwise            : set rexposn
3980  if exists("s:rexposn_".bufnr("%"))
3981"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
3982   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
3983   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
3984    NetrwKeepj exe w:netrw_bannercnt
3985   endif
3986  else
3987   NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
3988  endif
3989  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
3990   let &l:bexpr= "netrw#BalloonHelp()"
3991"   call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>"))
3992   setl beval
3993  endif
3994
3995  " repoint t:netrw_lexbufnr if appropriate
3996  if exists("repointlexbufnr")
3997   let t:netrw_lexbufnr= bufnr("%")
3998"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
3999  endif
4000
4001  " restore position
4002  if reusing
4003"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4004   call winrestview(svpos)
4005  endif
4006
4007  " The s:LocalBrowseRefresh() function is called by an autocmd
4008  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow or medium speed).
4009  " However, s:NetrwBrowse() causes the FocusGained event to fire the first time.
4010"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4011"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4012"  call Dret("s:NetrwBrowse : did PerformListing  ft<".&ft.">")
4013  return
4014endfun
4015
4016" ---------------------------------------------------------------------
4017" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
4018" may not apply correctly; ie. netrw's idea of the current directory may
4019" differ from vim's.  This function insures that netrw's idea of the current
4020" directory is used.
4021" Returns a path to the file specified by a:fname
4022fun! s:NetrwFile(fname)
4023"  "" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
4024"  "" call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
4025"  "" call Decho("g:netrw_cygwin   =".(exists("g:netrw_cygwin")?    g:netrw_cygwin    : 'n/a'),'~'.expand("<slnum>"))
4026"  "" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
4027"  "" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
4028
4029  " clean up any leading treedepthstring
4030  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4031   let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
4032"   "" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>"))
4033  else
4034   let fname= a:fname
4035  endif
4036
4037  if g:netrw_keepdir
4038   " vim's idea of the current directory possibly may differ from netrw's
4039   if !exists("b:netrw_curdir")
4040    let b:netrw_curdir= getcwd()
4041   endif
4042
4043   if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
4044    if fname =~ '^\' || fname =~ '^\a:\'
4045     " windows, but full path given
4046     let ret= fname
4047"     "" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4048    else
4049     " windows, relative path given
4050     let ret= s:ComposePath(b:netrw_curdir,fname)
4051"     "" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4052    endif
4053
4054   elseif fname =~ '^/'
4055    " not windows, full path given
4056    let ret= fname
4057"    "" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4058   else
4059    " not windows, relative path given
4060    let ret= s:ComposePath(b:netrw_curdir,fname)
4061"    "" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
4062   endif
4063  else
4064   " vim and netrw agree on the current directory
4065   let ret= fname
4066"   "" call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
4067"   "" call Decho("vim   directory: ".getcwd(),'~'.expand("<slnum>"))
4068"   "" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>"))
4069  endif
4070
4071"  "" call Dret("s:NetrwFile ".ret)
4072  return ret
4073endfun
4074
4075" ---------------------------------------------------------------------
4076" s:NetrwFileInfo: supports qf (query for file information) {{{2
4077fun! s:NetrwFileInfo(islocal,fname)
4078"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
4079  let ykeep= @@
4080  if a:islocal
4081   let lsopt= "-lsad"
4082   if g:netrw_sizestyle =~# 'H'
4083    let lsopt= "-lsadh"
4084   elseif g:netrw_sizestyle =~# 'h'
4085    let lsopt= "-lsadh --si"
4086   endif
4087   if (has("unix") || has("macunix")) && executable("/bin/ls")
4088
4089    if getline(".") == "../"
4090     echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
4091"     call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
4092
4093    elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
4094     echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
4095"     call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
4096
4097    elseif exists("b:netrw_curdir")
4098      echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
4099"      call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
4100
4101    else
4102"     call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
4103     echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
4104"     call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
4105    endif
4106   else
4107    " use vim functions to return information about file below cursor
4108"    call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
4109    if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
4110     let fname= substitute(a:fname,".$","","")
4111    else
4112     let fname= a:fname
4113    endif
4114    let t  = getftime(s:NetrwFile(fname))
4115    let sz = getfsize(s:NetrwFile(fname))
4116    if g:netrw_sizestyle =~# "[hH]"
4117     let sz= s:NetrwHumanReadable(sz)
4118    endif
4119    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
4120"    call Decho("fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
4121   endif
4122  else
4123   echo "sorry, \"qf\" not supported yet for remote files"
4124  endif
4125  let @@= ykeep
4126"  call Dret("s:NetrwFileInfo")
4127endfun
4128
4129" ---------------------------------------------------------------------
4130" s:NetrwFullPath: returns the full path to a directory and/or file {{{2
4131fun! s:NetrwFullPath(filename)
4132"  " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)")
4133  let filename= a:filename
4134  if filename !~ '^/'
4135   let filename= resolve(getcwd().'/'.filename)
4136  endif
4137  if filename != "/" && filename =~ '/$'
4138   let filename= substitute(filename,'/$','','')
4139  endif
4140"  " call Dret("s:NetrwFullPath <".filename.">")
4141  return filename
4142endfun
4143
4144" ---------------------------------------------------------------------
4145" s:NetrwGetBuffer: [get a new|find an old netrw] buffer for a netrw listing {{{2
4146"   returns 0=cleared buffer
4147"           1=re-used buffer (buffer not cleared)
4148fun! s:NetrwGetBuffer(islocal,dirname)
4149"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
4150"  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>"))
4151"  call Decho("netrwbuf dictionary=".(exists("s:netrwbuf")? string(s:netrwbuf) : 'n/a'),'~'.expand("<slnum>"))
4152"  call Dredir("ls!","s:NetrwGetBuffer")
4153  let dirname= a:dirname
4154
4155  " re-use buffer if possible {{{3
4156"  call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
4157  if !exists("s:netrwbuf")
4158"   call Decho("  s:netrwbuf initialized to {}",'~'.expand("<slnum>"))
4159   let s:netrwbuf= {}
4160  endif
4161"  call Decho("  s:netrwbuf         =".string(s:netrwbuf),'~'.expand("<slnum>"))
4162"  call Decho("  w:netrw_liststyle  =".(exists("w:netrw_liststyle")? w:netrw_liststyle : "n/a"),'~'.expand("<slnum>"))
4163
4164  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4165   let bufnum = -1
4166
4167   if !empty(s:netrwbuf) && has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4168    if has_key(s:netrwbuf,"NetrwTreeListing")
4169     let bufnum= s:netrwbuf["NetrwTreeListing"]
4170    else
4171     let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4172    endif
4173"    call Decho("  NetrwTreeListing: bufnum#".bufnum,'~'.expand("<slnum>"))
4174    if !bufexists(bufnum)
4175     call remove(s:netrwbuf,"NetrwTreeListing"])
4176     let bufnum= -1
4177    endif
4178   elseif bufnr("NetrwTreeListing") != -1
4179    let bufnum= bufnr("NetrwTreeListing")
4180"    call Decho("  NetrwTreeListing".": bufnum#".bufnum,'~'.expand("<slnum>"))
4181   else
4182"    call Decho("  did not find a NetrwTreeListing buffer",'~'.expand("<slnum>"))
4183     let bufnum= -1
4184   endif
4185
4186  elseif has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4187   let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4188"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum,'~'.expand("<slnum>"))
4189   if !bufexists(bufnum)
4190    call remove(s:netrwbuf,s:NetrwFullPath(dirname))
4191    let bufnum= -1
4192   endif
4193
4194  else
4195"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key",'~'.expand("<slnum>"))
4196   let bufnum= -1
4197  endif
4198"  call Decho("  bufnum#".bufnum,'~'.expand("<slnum>"))
4199
4200  " highjack the current buffer if
4201  "   it has the desired name
4202  "   it is empty
4203"  call Decho("deciding if I can highjack the current buffer#".bufnr("%"),'~'.expand("<slnum>"))
4204"  call Decho("..dirname<".dirname.">",'~'.expand("<slnum>"))
4205"  call Decho("..bufname<".bufname("%").">",'~'.expand("<slnum>"))
4206"  call Decho("..getline($)<".getline("$").">",'~'.expand("<slnum>"))
4207  if dirname == bufname("%") && line("$") == 1 && getline("%") == ""
4208"   call Dret("s:NetrwGetBuffer 0<cleared buffer> : highjacking buffer#".bufnr("%"))
4209   return 0
4210  endif
4211
4212  " get enew buffer and name it -or- re-use buffer {{{3
4213  if bufnum < 0      " get enew buffer and name it
4214"   call Decho("--get enew buffer and name it  (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4215   call s:NetrwEnew(dirname)
4216"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4217   " name the buffer
4218   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4219    " Got enew buffer; transform into a NetrwTreeListing
4220"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4221    let w:netrw_treebufnr = bufnr("%")
4222    call s:NetrwBufRename("NetrwTreeListing")
4223    if g:netrw_use_noswf
4224     setl nobl bt=nofile noswf
4225    else
4226     setl nobl bt=nofile
4227    endif
4228    nnoremap <silent> <buffer> [[       :sil call <SID>TreeListMove('[[')<cr>
4229    nnoremap <silent> <buffer> ]]       :sil call <SID>TreeListMove(']]')<cr>
4230    nnoremap <silent> <buffer> []       :sil call <SID>TreeListMove('[]')<cr>
4231    nnoremap <silent> <buffer> ][       :sil call <SID>TreeListMove('][')<cr>
4232"    call Decho("  tree listing bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
4233   else
4234    call s:NetrwBufRename(dirname)
4235    " enter the new buffer into the s:netrwbuf dictionary
4236    let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%")
4237"    call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>"))
4238"    call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
4239   endif
4240"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4241
4242  else " Re-use the buffer
4243"   call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4244   let eikeep= &ei
4245   setl ei=all
4246   if getline(2) =~# '^" Netrw Directory Listing'
4247"    call Decho("  getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>"))
4248    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4249   else
4250"    call Decho("  getline(2)<".getline(2).'> does not match "Netrw Directory Listing" : using b '.bufnum,'~'.expand("<slnum>"))
4251    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4252   endif
4253"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
4254   if bufname("%") == '.'
4255    call s:NetrwBufRename(getcwd())
4256   endif
4257   let &ei= eikeep
4258
4259   if line("$") <= 1 && getline(1) == ""
4260    " empty buffer
4261    NetrwKeepj call s:NetrwListSettings(a:islocal)
4262"    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>"))
4263"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4264"    call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4265    return 0
4266
4267   elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4268"    call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4269    NetrwKeepj call s:NetrwListSettings(a:islocal)
4270    sil NetrwKeepj %d _
4271"    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>"))
4272"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4273"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4274    return 0
4275
4276   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4277"    call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4278"    call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4279    setl ma
4280    sil NetrwKeepj %d _
4281    NetrwKeepj call s:NetrwListSettings(a:islocal)
4282"    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>"))
4283"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4284"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4285    return 0
4286
4287   else
4288"    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>"))
4289"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4290"    call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4291    return 1
4292   endif
4293  endif
4294
4295  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4296  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
4297  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
4298  "  med    1         D      H
4299  "  fast   2         H      H
4300"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
4301  let fname= expand("%")
4302  NetrwKeepj call s:NetrwListSettings(a:islocal)
4303  call s:NetrwBufRename(fname)
4304
4305  " delete all lines from buffer {{{3
4306"  call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4307"  call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4308  sil! keepalt NetrwKeepj %d _
4309
4310"  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>"))
4311"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4312"  call Dret("s:NetrwGetBuffer 0<cleared buffer>")
4313  return 0
4314endfun
4315
4316" ---------------------------------------------------------------------
4317" s:NetrwGetcwd: get the current directory. {{{2
4318"   Change backslashes to forward slashes, if any.
4319"   If doesc is true, escape certain troublesome characters
4320fun! s:NetrwGetcwd(doesc)
4321"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
4322  let curdir= substitute(getcwd(),'\\','/','ge')
4323  if curdir !~ '[\/]$'
4324   let curdir= curdir.'/'
4325  endif
4326  if a:doesc
4327   let curdir= fnameescape(curdir)
4328  endif
4329"  call Dret("NetrwGetcwd <".curdir.">")
4330  return curdir
4331endfun
4332
4333" ---------------------------------------------------------------------
4334"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4335fun! s:NetrwGetWord()
4336"  call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4337"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4338  let keepsol= &l:sol
4339  setl nosol
4340
4341  call s:UseBufWinVars()
4342
4343  " insure that w:netrw_liststyle is set up
4344  if !exists("w:netrw_liststyle")
4345   if exists("g:netrw_liststyle")
4346    let w:netrw_liststyle= g:netrw_liststyle
4347   else
4348    let w:netrw_liststyle= s:THINLIST
4349   endif
4350"   call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
4351  endif
4352
4353  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4354   " Active Banner support
4355"   call Decho("active banner handling",'~'.expand("<slnum>"))
4356   NetrwKeepj norm! 0
4357   let dirname= "./"
4358   let curline= getline('.')
4359
4360   if curline =~# '"\s*Sorted by\s'
4361    NetrwKeepj norm! "_s
4362    let s:netrw_skipbrowse= 1
4363    echo 'Pressing "s" also works'
4364
4365   elseif curline =~# '"\s*Sort sequence:'
4366    let s:netrw_skipbrowse= 1
4367    echo 'Press "S" to edit sorting sequence'
4368
4369   elseif curline =~# '"\s*Quick Help:'
4370    NetrwKeepj norm! ?
4371    let s:netrw_skipbrowse= 1
4372
4373   elseif curline =~# '"\s*\%(Hiding\|Showing\):'
4374    NetrwKeepj norm! a
4375    let s:netrw_skipbrowse= 1
4376    echo 'Pressing "a" also works'
4377
4378   elseif line("$") > w:netrw_bannercnt
4379    exe 'sil NetrwKeepj '.w:netrw_bannercnt
4380   endif
4381
4382  elseif w:netrw_liststyle == s:THINLIST
4383"   call Decho("thin column handling",'~'.expand("<slnum>"))
4384   NetrwKeepj norm! 0
4385   let dirname= substitute(getline('.'),'\t -->.*$','','')
4386
4387  elseif w:netrw_liststyle == s:LONGLIST
4388"   call Decho("long column handling",'~'.expand("<slnum>"))
4389   NetrwKeepj norm! 0
4390   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
4391
4392  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4393"   call Decho("treelist handling",'~'.expand("<slnum>"))
4394   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4395   let dirname= substitute(dirname,'\t -->.*$','','')
4396
4397  else
4398"   call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4399   let dirname= getline('.')
4400
4401   if !exists("b:netrw_cpf")
4402    let b:netrw_cpf= 0
4403    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
4404    call histdel("/",-1)
4405"   "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4406   endif
4407
4408"   call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4409   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4410"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4411"   call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4412   if filestart == 0
4413    NetrwKeepj norm! 0ma
4414   else
4415    call cursor(line("."),filestart+1)
4416    NetrwKeepj norm! ma
4417   endif
4418   let rega= @a
4419   let eofname= filestart + b:netrw_cpf + 1
4420   if eofname <= col("$")
4421    call cursor(line("."),filestart+b:netrw_cpf+1)
4422    NetrwKeepj norm! "ay`a
4423   else
4424    NetrwKeepj norm! "ay$
4425   endif
4426   let dirname = @a
4427   let @a      = rega
4428"   call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4429   let dirname= substitute(dirname,'\s\+$','','e')
4430"   call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4431  endif
4432
4433  " symlinks are indicated by a trailing "@".  Remove it before further processing.
4434  let dirname= substitute(dirname,"@$","","")
4435
4436  " executables are indicated by a trailing "*".  Remove it before further processing.
4437  let dirname= substitute(dirname,"\*$","","")
4438
4439  let &l:sol= keepsol
4440
4441"  call Dret("s:NetrwGetWord <".dirname.">")
4442  return dirname
4443endfun
4444
4445" ---------------------------------------------------------------------
4446" s:NetrwListSettings: make standard settings for making a netrw listing {{{2
4447"                      g:netrw_bufsettings will be used after the listing is produced.
4448"                      Called by s:NetrwGetBuffer()
4449fun! s:NetrwListSettings(islocal)
4450"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4451"  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>"))
4452  let fname= bufname("%")
4453"  "  call Decho("setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
4454  "              nobl noma nomod nonu noma nowrap ro   nornu  (std g:netrw_bufsettings)
4455  setl bt=nofile nobl ma         nonu      nowrap noro nornu
4456  call s:NetrwBufRename(fname)
4457  if g:netrw_use_noswf
4458   setl noswf
4459  endif
4460"  call Dredir("ls!","s:NetrwListSettings")
4461"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
4462  exe "setl ts=".(g:netrw_maxfilenamelen+1)
4463  setl isk+=.,~,-
4464  if g:netrw_fastbrowse > a:islocal
4465   setl bh=hide
4466  else
4467   setl bh=delete
4468  endif
4469"  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>"))
4470"  call Dret("s:NetrwListSettings")
4471endfun
4472
4473" ---------------------------------------------------------------------
4474"  s:NetrwListStyle: change list style (thin - long - wide - tree) {{{2
4475"  islocal=0: remote browsing
4476"         =1: local browsing
4477fun! s:NetrwListStyle(islocal)
4478"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
4479
4480  let ykeep             = @@
4481  let fname             = s:NetrwGetWord()
4482  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
4483  let svpos            = winsaveview()
4484"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4485  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
4486"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
4487"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>"))
4488"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
4489
4490  " repoint t:netrw_lexbufnr if appropriate
4491  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
4492"   call Decho("set repointlexbufnr to true!")
4493   let repointlexbufnr= 1
4494  endif
4495
4496  if w:netrw_liststyle == s:THINLIST
4497   " use one column listing
4498"   call Decho("use one column list",'~'.expand("<slnum>"))
4499   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4500
4501  elseif w:netrw_liststyle == s:LONGLIST
4502   " use long list
4503"   call Decho("use long list",'~'.expand("<slnum>"))
4504   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
4505
4506  elseif w:netrw_liststyle == s:WIDELIST
4507   " give wide list
4508"   call Decho("use wide list",'~'.expand("<slnum>"))
4509   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4510
4511  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4512"   call Decho("use tree list",'~'.expand("<slnum>"))
4513   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4514
4515  else
4516   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4517   let g:netrw_liststyle = s:THINLIST
4518   let w:netrw_liststyle = g:netrw_liststyle
4519   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
4520  endif
4521  setl ma noro
4522"  call Decho("setl ma noro",'~'.expand("<slnum>"))
4523
4524  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
4525"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4526  sil! NetrwKeepj %d _
4527  " following prevents tree listing buffer from being marked "modified"
4528"  call Decho("setl nomod",'~'.expand("<slnum>"))
4529  setl nomod
4530"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4531
4532  " refresh the listing
4533"  call Decho("refresh the listing",'~'.expand("<slnum>"))
4534  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4535  NetrwKeepj call s:NetrwCursor()
4536
4537  " repoint t:netrw_lexbufnr if appropriate
4538  if exists("repointlexbufnr")
4539   let t:netrw_lexbufnr= bufnr("%")
4540"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
4541  endif
4542
4543  " restore position; keep cursor on the filename
4544"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4545  NetrwKeepj call winrestview(svpos)
4546  let @@= ykeep
4547
4548"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
4549endfun
4550
4551" ---------------------------------------------------------------------
4552" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4553fun! s:NetrwBannerCtrl(islocal)
4554"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
4555
4556  let ykeep= @@
4557  " toggle the banner (enable/suppress)
4558  let g:netrw_banner= !g:netrw_banner
4559
4560  " refresh the listing
4561  let svpos= winsaveview()
4562"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4563  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4564
4565  " keep cursor on the filename
4566  if g:netrw_banner && exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt
4567   let fname= s:NetrwGetWord()
4568   sil NetrwKeepj $
4569   let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4570" "  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4571   if result <= 0 && exists("w:netrw_bannercnt")
4572    exe "NetrwKeepj ".w:netrw_bannercnt
4573   endif
4574  endif
4575  let @@= ykeep
4576"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
4577endfun
4578
4579" ---------------------------------------------------------------------
4580" s:NetrwBookmark: supports :NetrwMB[!] [file]s                 {{{2
4581"
4582"  No bang: enters files/directories into Netrw's bookmark system
4583"   No argument and in netrw buffer:
4584"     if there are marked files: bookmark marked files
4585"     otherwise                : bookmark file/directory under cursor
4586"   No argument and not in netrw buffer: bookmarks current open file
4587"   Has arguments: globs them individually and bookmarks them
4588"
4589"  With bang: deletes files/directories from Netrw's bookmark system
4590fun! s:NetrwBookmark(del,...)
4591"  call Dfunc("s:NetrwBookmark(del=".a:del.",...) a:0=".a:0)
4592  if a:0 == 0
4593   if &ft == "netrw"
4594    let curbufnr = bufnr("%")
4595
4596    if exists("s:netrwmarkfilelist_{curbufnr}")
4597     " for every filename in the marked list
4598"     call Decho("bookmark every filename in marked list",'~'.expand("<slnum>"))
4599     let svpos  = winsaveview()
4600"     call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4601     let islocal= expand("%") !~ '^\a\{3,}://'
4602     for fname in s:netrwmarkfilelist_{curbufnr}
4603      if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4604     endfor
4605     let curdir  = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4606     call s:NetrwUnmarkList(curbufnr,curdir)
4607     NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./'))
4608"     call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4609     NetrwKeepj call winrestview(svpos)
4610    else
4611     let fname= s:NetrwGetWord()
4612     if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4613    endif
4614
4615   else
4616    " bookmark currently open file
4617"    call Decho("bookmark currently open file",'~'.expand("<slnum>"))
4618    let fname= expand("%")
4619    if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4620   endif
4621
4622  else
4623   " bookmark specified files
4624   "  attempts to infer if working remote or local
4625   "  by deciding if the current file begins with an url
4626   "  Globbing cannot be done remotely.
4627   let islocal= expand("%") !~ '^\a\{3,}://'
4628"   call Decho("bookmark specified file".((a:0>1)? "s" : ""),'~'.expand("<slnum>"))
4629   let i = 1
4630   while i <= a:0
4631    if islocal
4632     if v:version > 704 || (v:version == 704 && has("patch656"))
4633      let mbfiles= glob(fnameescape(a:{i}),0,1,1)
4634     else
4635      let mbfiles= glob(fnameescape(a:{i}),0,1)
4636     endif
4637    else
4638     let mbfiles= [a:{i}]
4639    endif
4640"    call Decho("mbfiles".string(mbfiles),'~'.expand("<slnum>"))
4641    for mbfile in mbfiles
4642"     call Decho("mbfile<".mbfile.">",'~'.expand("<slnum>"))
4643     if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4644    endfor
4645    let i= i + 1
4646   endwhile
4647  endif
4648
4649  " update the menu
4650  call s:NetrwBookmarkMenu()
4651
4652"  call Dret("s:NetrwBookmark")
4653endfun
4654
4655" ---------------------------------------------------------------------
4656" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4657"                      .2.[cnt] for bookmarks, and
4658"                      .3.[cnt] for history
4659"                      (see s:NetrwMenu())
4660fun! s:NetrwBookmarkMenu()
4661  if !exists("s:netrw_menucnt")
4662   return
4663  endif
4664"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhistcnt." menucnt=".s:netrw_menucnt)
4665
4666  " the following test assures that gvim is running, has menus available, and has menus enabled.
4667  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
4668   if exists("g:NetrwTopLvlMenu")
4669"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4670    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4671    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4672   endif
4673   if !exists("s:netrw_initbookhist")
4674    call s:NetrwBookHistRead()
4675   endif
4676
4677   " show bookmarked places
4678   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4679    let cnt= 1
4680    for bmd in g:netrw_bookmarklist
4681"     call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd,'~'.expand("<slnum>"))
4682     let bmd= escape(bmd,g:netrw_menu_escape)
4683
4684     " show bookmarks for goto menu
4685     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
4686
4687     " show bookmarks for deletion menu
4688     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
4689     let cnt= cnt + 1
4690    endfor
4691
4692   endif
4693
4694   " show directory browsing history
4695   if g:netrw_dirhistmax > 0
4696    let cnt     = g:netrw_dirhistcnt
4697    let first   = 1
4698    let histcnt = 0
4699    while ( first || cnt != g:netrw_dirhistcnt )
4700     let histcnt  = histcnt + 1
4701     let priority = g:netrw_dirhistcnt + histcnt
4702     if exists("g:netrw_dirhist_{cnt}")
4703      let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4704"     call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir,'~'.expand("<slnum>"))
4705      exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
4706     endif
4707     let first = 0
4708     let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
4709     if cnt < 0
4710      let cnt= cnt + g:netrw_dirhistmax
4711     endif
4712    endwhile
4713   endif
4714
4715  endif
4716"  call Dret("NetrwBookmarkMenu")
4717endfun
4718
4719" ---------------------------------------------------------------------
4720"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4721"                       directory and a new directory name.  Also, if the
4722"                       "new directory name" is actually a file,
4723"                       NetrwBrowseChgDir() edits the file.
4724fun! s:NetrwBrowseChgDir(islocal,newdir,...)
4725"  call Dfunc("s:NetrwBrowseChgDir(islocal=".a:islocal."> newdir<".a:newdir.">) a:0=".a:0." curpos<".string(getpos("."))."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "").">")
4726"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4727
4728  let ykeep= @@
4729  if !exists("b:netrw_curdir")
4730   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4731   " and the current window is the NetrwMessage window.
4732   let @@= ykeep
4733"   call Decho("b:netrw_curdir doesn't exist!",'~'.expand("<slnum>"))
4734"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
4735"   call Dredir("ls!","s:NetrwBrowseChgDir")
4736"   call Dret("s:NetrwBrowseChgDir")
4737   return
4738  endif
4739"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
4740
4741  " NetrwBrowseChgDir: save options and initialize {{{3
4742"  call Decho("saving options",'~'.expand("<slnum>"))
4743  call s:SavePosn(s:netrw_posn)
4744  NetrwKeepj call s:NetrwOptionsSave("s:")
4745  NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
4746  if (has("win32") || has("win95") || has("win64") || has("win16"))
4747   let dirname = substitute(b:netrw_curdir,'\\','/','ge')
4748  else
4749   let dirname = b:netrw_curdir
4750  endif
4751  let newdir    = a:newdir
4752  let dolockout = 0
4753  let dorestore = 1
4754"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
4755"  call Decho("newdir<".newdir.">",'~'.expand("<slnum>"))
4756
4757  " ignore <cr>s when done in the banner
4758"  call Decho('(s:NetrwBrowseChgDir) ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("<slnum>"))
4759  if g:netrw_banner
4760"   call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>"))
4761   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4762    if getline(".") =~# 'Quick Help'
4763"     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>"))
4764     let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4765"     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>"))
4766     setl ma noro nowrap
4767     NetrwKeepj call setline(line('.'),'"   Quick Help: <F1>:help  '.s:QuickHelp[g:netrw_quickhelp])
4768     setl noma nomod nowrap
4769     NetrwKeepj call s:NetrwOptionsRestore("s:")
4770"     call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4771    endif
4772   endif
4773"  else " Decho
4774"   call Decho("g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("<slnum>"))
4775  endif
4776
4777  " set up o/s-dependent directory recognition pattern
4778  if has("amiga")
4779   let dirpat= '[\/:]$'
4780  else
4781   let dirpat= '[\/]$'
4782  endif
4783"  call Decho("set up o/s-dependent directory recognition pattern: dirname<".dirname.">  dirpat<".dirpat.">",'~'.expand("<slnum>"))
4784
4785  if dirname !~ dirpat
4786   " apparently vim is "recognizing" that it is in a directory and
4787   " is removing the trailing "/".  Bad idea, so let's put it back.
4788   let dirname= dirname.'/'
4789"   call Decho("adjusting dirname<".dirname.'>  (put trailing "/" back)','~'.expand("<slnum>"))
4790  endif
4791
4792"  call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>"))
4793  if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
4794   " ------------------------------
4795   " NetrwBrowseChgDir: edit a file {{{3
4796   " ------------------------------
4797"   call Decho('(s:NetrwBrowseChgDir) edit-a-file: case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>"))
4798
4799   " save position for benefit of Rexplore
4800   let s:rexposn_{bufnr("%")}= winsaveview()
4801"   call Decho("edit-a-file: saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
4802"   call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
4803"   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>"))
4804
4805   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4806"    call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("<slnum>"))
4807"    call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("<slnum>"))
4808    let dirname= s:NetrwTreeDir(a:islocal)
4809    "COMBAK : not working for a symlink -- but what about a regular file? a directory?
4810"    call Decho("COMBAK : not working for a symlink -- but what about a regular file? a directory?")
4811    " Feb 17, 2019: following if-else-endif restored -- wasn't editing a file in tree mode
4812    if dirname =~ '/$'
4813     let dirname= dirname.newdir
4814    else
4815     let dirname= dirname."/".newdir
4816    endif
4817"    call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>"))
4818"    call Decho("edit-a-file: tree listing",'~'.expand("<slnum>"))
4819   elseif newdir =~ '^\(/\|\a:\)'
4820"    call Decho("edit-a-file: handle an url or path starting with /: <".newdir.">",'~'.expand("<slnum>"))
4821    let dirname= newdir
4822   else
4823    let dirname= s:ComposePath(dirname,newdir)
4824   endif
4825"   call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>"))
4826   " this lets netrw#BrowseX avoid the edit
4827   if a:0 < 1
4828"    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>"))
4829    NetrwKeepj call s:NetrwOptionsRestore("s:")
4830    let curdir= b:netrw_curdir
4831    if !exists("s:didsplit")
4832"     call Decho("edit-a-file: s:didsplit does not exist; g:netrw_browse_split=".string(g:netrw_browse_split)." win#".winnr(),'~'.expand("<slnum>"))
4833     if type(g:netrw_browse_split) == 3
4834      " open file in server
4835      " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4836"      call Decho("edit-a-file: open file in server",'~'.expand("<slnum>"))
4837      call s:NetrwServerEdit(a:islocal,dirname)
4838"      call Dret("s:NetrwBrowseChgDir")
4839      return
4840     elseif g:netrw_browse_split == 1
4841      " horizontally splitting the window first
4842"      call Decho("edit-a-file: horizontally splitting window prior to edit",'~'.expand("<slnum>"))
4843      keepalt new
4844      if !&ea
4845       keepalt wincmd _
4846      endif
4847      call s:SetRexDir(a:islocal,curdir)
4848     elseif g:netrw_browse_split == 2
4849      " vertically splitting the window first
4850"      call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>"))
4851      keepalt rightb vert new
4852      if !&ea
4853       keepalt wincmd |
4854      endif
4855      call s:SetRexDir(a:islocal,curdir)
4856     elseif g:netrw_browse_split == 3
4857      " open file in new tab
4858"      call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>"))
4859      keepalt tabnew
4860      if !exists("b:netrw_curdir")
4861       let b:netrw_curdir= getcwd()
4862      endif
4863      call s:SetRexDir(a:islocal,curdir)
4864     elseif g:netrw_browse_split == 4
4865      " act like "P" (ie. open previous window)
4866"      call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>"))
4867      if s:NetrwPrevWinOpen(2) == 3
4868       let @@= ykeep
4869"       call Dret("s:NetrwBrowseChgDir")
4870       return
4871      endif
4872      call s:SetRexDir(a:islocal,curdir)
4873     else
4874      " handling a file, didn't split, so remove menu
4875"      call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>"))
4876      call s:NetrwMenu(0)
4877      " optional change to window
4878      if g:netrw_chgwin >= 1
4879"       call Decho("edit-a-file: changing window to #".g:netrw_chgwin,'~'.expand("<slnum>"))
4880       if winnr("$")+1 == g:netrw_chgwin
4881	" if g:netrw_chgwin is set to one more than the last window, then
4882	" vertically split the last window to make that window available.
4883	let curwin= winnr()
4884	exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4885	vs
4886	exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4887       endif
4888       exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4889      endif
4890      call s:SetRexDir(a:islocal,curdir)
4891     endif
4892    endif
4893
4894    " the point where netrw actually edits the (local) file
4895    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4896    " no keepalt to support  :e #  to return to a directory listing
4897    if a:islocal
4898"     call Decho("edit-a-file: edit local file: exe e! ".fnameescape(dirname),'~'.expand("<slnum>"))
4899     " some like c-^ to return to the last edited file
4900     " others like c-^ to return to the netrw buffer
4901     if exists("g:netrw_altfile") && g:netrw_altfile
4902      exe "NetrwKeepj keepalt e! ".fnameescape(dirname)
4903     else
4904      exe "NetrwKeepj e! ".fnameescape(dirname)
4905     endif
4906"     call Decho("edit-a-file: after e! ".dirname.": hidden=".&hidden." bufhidden<".&bufhidden."> mod=".&mod,'~'.expand("<slnum>"))
4907     call s:NetrwCursor()
4908     if &hidden || &bufhidden == "hide"
4909      " file came from vim's hidden storage.  Don't "restore" options with it.
4910      let dorestore= 0
4911     endif
4912    else
4913"     call Decho("edit-a-file: remote file: NetrwBrowse will edit it",'~'.expand("<slnum>"))
4914    endif
4915    let dolockout= 1
4916
4917    " handle g:Netrw_funcref -- call external-to-netrw functions
4918    "   This code will handle g:Netrw_funcref as an individual function reference
4919    "   or as a list of function references.  It will ignore anything that's not
4920    "   a function reference.  See  :help Funcref  for information about function references.
4921    if exists("g:Netrw_funcref")
4922"     call Decho("edit-a-file: handle optional Funcrefs",'~'.expand("<slnum>"))
4923     if type(g:Netrw_funcref) == 2
4924"      call Decho("edit-a-file: handling a g:Netrw_funcref",'~'.expand("<slnum>"))
4925      NetrwKeepj call g:Netrw_funcref()
4926     elseif type(g:Netrw_funcref) == 3
4927"      call Decho("edit-a-file: handling a list of g:Netrw_funcrefs",'~'.expand("<slnum>"))
4928      for Fncref in g:Netrw_funcref
4929       if type(FncRef) == 2
4930        NetrwKeepj call FncRef()
4931       endif
4932      endfor
4933     endif
4934    endif
4935   endif
4936
4937  elseif newdir =~ '^/'
4938   " ----------------------------------------------------
4939   " NetrwBrowseChgDir: just go to the new directory spec {{{3
4940   " ----------------------------------------------------
4941"   call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("<slnum>"))
4942   let dirname = newdir
4943   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4944   NetrwKeepj call s:NetrwOptionsRestore("s:")
4945   norm! m`
4946
4947  elseif newdir == './'
4948   " ---------------------------------------------
4949   " NetrwBrowseChgDir: refresh the directory list {{{3
4950   " ---------------------------------------------
4951"   call Decho('(s:NetrwBrowseChgDir)refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("<slnum>"))
4952   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4953   norm! m`
4954
4955  elseif newdir == '../'
4956   " --------------------------------------
4957   " NetrwBrowseChgDir: go up one directory {{{3
4958   " --------------------------------------
4959"   call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../"','~'.expand("<slnum>"))
4960
4961   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4962    " force a refresh
4963"    call Decho("go-up: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4964"    call Decho("go-up: setl noro ma",'~'.expand("<slnum>"))
4965    setl noro ma
4966    NetrwKeepj %d _
4967   endif
4968
4969   if has("amiga")
4970    " amiga
4971"    call Decho('go-up: case "go up one directory": newdir == "../" and amiga','~'.expand("<slnum>"))
4972    if a:islocal
4973     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
4974     let dirname= substitute(dirname,'/$','','')
4975    else
4976     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
4977    endif
4978"    call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4979
4980   elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
4981    " windows
4982    if a:islocal
4983     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4984     if dirname == ""
4985      let dirname= '/'
4986     endif
4987    else
4988     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4989    endif
4990    if dirname =~ '^\a:$'
4991     let dirname= dirname.'/'
4992    endif
4993"    call Decho("go-up: windows: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4994
4995   else
4996    " unix or cygwin
4997"    call Decho('(s:NetrwBrowseChgDir)go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("<slnum>"))
4998    if a:islocal
4999     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
5000     if dirname == ""
5001      let dirname= '/'
5002     endif
5003    else
5004     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
5005    endif
5006"    call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
5007   endif
5008   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5009   norm! m`
5010
5011  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5012   " --------------------------------------
5013   " NetrwBrowseChgDir: Handle Tree Listing {{{3
5014   " --------------------------------------
5015"   call Decho('(s:NetrwBrowseChgDir)tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("<slnum>"))
5016   " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
5017"   call Decho("tree-list: setl noro ma",'~'.expand("<slnum>"))
5018   setl noro ma
5019   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
5020"    call Decho("tree-list: clear buffer<".expand("%")."> with :%d  (force refresh)",'~'.expand("<slnum>"))
5021    NetrwKeepj %d _
5022   endif
5023   let treedir      = s:NetrwTreeDir(a:islocal)
5024"   call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>"))
5025   let s:treecurpos = winsaveview()
5026   let haskey       = 0
5027"   call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
5028
5029   " search treedict for tree dir as-is
5030"   call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("<slnum>"))
5031   if has_key(w:netrw_treedict,treedir)
5032"    call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>"))
5033    let haskey= 1
5034   else
5035"    call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
5036   endif
5037
5038   " search treedict for treedir with a [/@] appended
5039"   call Decho("tree-list: search treedict for treedir with a [/@] appended",'~'.expand("<slnum>"))
5040   if !haskey && treedir !~ '[/@]$'
5041    if has_key(w:netrw_treedict,treedir."/")
5042     let treedir= treedir."/"
5043"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
5044     let haskey = 1
5045    else
5046"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("<slnum>"))
5047    endif
5048   endif
5049
5050   " search treedict for treedir with any trailing / elided
5051"   call Decho("tree-list: search treedict for treedir with any trailing / elided",'~'.expand("<slnum>"))
5052   if !haskey && treedir =~ '/$'
5053    let treedir= substitute(treedir,'/$','','')
5054    if has_key(w:netrw_treedict,treedir)
5055"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
5056     let haskey = 1
5057    else
5058"     call Decho('(s:NetrwBrowseChgDir)tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
5059    endif
5060   endif
5061
5062"   call Decho("haskey=".haskey,'~'.expand("<slnum>"))
5063   if haskey
5064    " close tree listing for selected subdirectory
5065"    call Decho("tree-list: closing selected subdirectory<".dirname.">",'~'.expand("<slnum>"))
5066    call remove(w:netrw_treedict,treedir)
5067"    call Decho("tree-list: removed     entry<".treedir."> from treedict",'~'.expand("<slnum>"))
5068"    call Decho("tree-list: yielding treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
5069    let dirname= w:netrw_treetop
5070   else
5071    " go down one directory
5072    let dirname= substitute(treedir,'/*$','/','')
5073"    call Decho("tree-list: go down one dir: treedir<".treedir.">",'~'.expand("<slnum>"))
5074"    call Decho("tree-list: ...            : dirname<".dirname.">",'~'.expand("<slnum>"))
5075   endif
5076   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5077"   call Decho("setting s:treeforceredraw to true",'~'.expand("<slnum>"))
5078   let s:treeforceredraw = 1
5079
5080  else
5081   " ----------------------------------------
5082   " NetrwBrowseChgDir: Go down one directory {{{3
5083   " ----------------------------------------
5084   let dirname    = s:ComposePath(dirname,newdir)
5085"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("<slnum>"))
5086   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
5087   norm! m`
5088  endif
5089
5090 " --------------------------------------
5091 " NetrwBrowseChgDir: Restore and Cleanup {{{3
5092 " --------------------------------------
5093  if dorestore
5094   " dorestore is zero'd when a local file was hidden or bufhidden;
5095   " in such a case, we want to keep whatever settings it may have.
5096"   call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("<slnum>"))
5097   NetrwKeepj call s:NetrwOptionsRestore("s:")
5098"  else " Decho
5099"   call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>"))
5100  endif
5101  if dolockout && dorestore
5102"   call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>"))
5103   if filewritable(dirname)
5104"    call Decho("restore: doing modification lockout settings: ma nomod noro",'~'.expand("<slnum>"))
5105"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5106    setl ma noro nomod
5107"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5108   else
5109"    call Decho("restore: doing modification lockout settings: ma nomod ro",'~'.expand("<slnum>"))
5110"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5111    setl ma ro nomod
5112"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5113   endif
5114  endif
5115  call s:RestorePosn(s:netrw_posn)
5116  let @@= ykeep
5117
5118"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
5119  return dirname
5120endfun
5121
5122" ---------------------------------------------------------------------
5123" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
5124"    for thin, long, and wide: cursor placed just after banner
5125"    for tree, keeps cursor on current filename
5126fun! s:NetrwBrowseUpDir(islocal)
5127"  call Dfunc("s:NetrwBrowseUpDir(islocal=".a:islocal.")")
5128  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
5129   " this test needed because occasionally this function seems to be incorrectly called
5130   " when multiple leftmouse clicks are taken when atop the one line help in the banner.
5131   " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
5132   " directories.
5133"   call Dret("s:NetrwBrowseUpDir : cursor not in file area")
5134   return
5135  endif
5136
5137  norm! 0
5138  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5139"   call Decho("case: treestyle",'~'.expand("<slnum>"))
5140   let curline= getline(".")
5141   let swwline= winline() - 1
5142   if exists("w:netrw_treetop")
5143    let b:netrw_curdir= w:netrw_treetop
5144   elseif exists("b:netrw_curdir")
5145    let w:netrw_treetop= b:netrw_curdir
5146   else
5147    let w:netrw_treetop= getcwd()
5148    let b:netrw_curdir = w:netrw_treetop
5149   endif
5150   let curfile = getline(".")
5151   let curpath = s:NetrwTreePath(w:netrw_treetop)
5152   if a:islocal
5153    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5154   else
5155    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5156   endif
5157"   call Decho("looking for curfile<^".s:treedepthstring.curfile.">",'~'.expand("<slnum>"))
5158"   call Decho("having      curpath<".curpath.">",'~'.expand("<slnum>"))
5159   if w:netrw_treetop == '/'
5160     keepj call search('^\M'.curfile,"w")
5161   elseif curfile == '../'
5162     keepj call search('^\M'.curfile,"wb")
5163   else
5164"    call Decho("search(^\\M".s:treedepthstring.curfile.") backwards"))
5165    while 1
5166     keepj call search('^\M'.s:treedepthstring.curfile,"wb")
5167     let treepath= s:NetrwTreePath(w:netrw_treetop)
5168"     call Decho("..current treepath<".treepath.">",'~'.expand("<slnum>"))
5169     if treepath == curpath
5170      break
5171     endif
5172    endwhile
5173   endif
5174
5175  else
5176"   call Decho("case: not treestyle",'~'.expand("<slnum>"))
5177   call s:SavePosn(s:netrw_posn)
5178   if exists("b:netrw_curdir")
5179    let curdir= b:netrw_curdir
5180   else
5181    let curdir= expand(getcwd())
5182   endif
5183   if a:islocal
5184    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5185   else
5186    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5187   endif
5188   call s:RestorePosn(s:netrw_posn)
5189   let curdir= substitute(curdir,'^.*[\/]','','')
5190   call search('\<'.curdir.'/','wc')
5191  endif
5192"  call Dret("s:NetrwBrowseUpDir")
5193endfun
5194
5195" ---------------------------------------------------------------------
5196" netrw#BrowseX:  (implements "x" and "gx") executes a special "viewer" script or program for the {{{2
5197"              given filename; typically this means given their extension.
5198"              0=local, 1=remote
5199fun! netrw#BrowseX(fname,remote)
5200  let use_ctrlo= 1
5201"  call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")  implements x and gx maps")
5202
5203  if a:remote == 0 && isdirectory(a:fname)
5204   " if its really just a local directory, then do a "gf" instead
5205"   call Decho("remote≡0 and a:fname<".a:fname."> ".(isdirectory(a:fname)? "is a directory" : "is not a directory"),'~'.expand("<slnum>"))
5206"   call Decho("..appears to be a local directory; using e ".a:fname." instead",'~'.expand("<slnum>"))
5207   exe "e ".a:fname
5208"   call Dret("netrw#BrowseX")
5209   return
5210  elseif a:remote == 1 && a:fname !~ '^https\=:' && a:fname =~ '/$'
5211   " remote directory, not a webpage access, looks like an attempt to do a directory listing
5212"   call Decho("remote≡1 and a:fname<".a:fname.">",'~'.expand("<slnum>"))
5213"   call Decho("..and fname ".((a:fname =~ '^https\=:')? 'matches' : 'does not match').'^https\=:','~'.expand("<slnum>"))
5214"   call Decho("..and fname ".((a:fname =~ '/$')?        'matches' : 'does not match').' /$','~'.expand("<slnum>"))
5215"   call Decho("..appears to be a remote directory listing request; using gf instead",'~'.expand("<slnum>"))
5216   norm! gf
5217"   call Dret("netrw#BrowseX")
5218   return
5219  endif
5220"  call Decho("not a local file nor a webpage request",'~'.expand("<slnum>"))
5221
5222  let ykeep      = @@
5223  let screenposn = winsaveview()
5224"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5225
5226  " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
5227  let awkeep     = &aw
5228  set noaw
5229
5230  " special core dump handler
5231  if a:fname =~ '/core\(\.\d\+\)\=$'
5232   if exists("g:Netrw_corehandler")
5233    if type(g:Netrw_corehandler) == 2
5234     " g:Netrw_corehandler is a function reference (see :help Funcref)
5235"     call Decho("g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
5236     call g:Netrw_corehandler(s:NetrwFile(a:fname))
5237    elseif type(g:Netrw_corehandler) == 3
5238     " g:Netrw_corehandler is a List of function references (see :help Funcref)
5239"     call Decho("g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
5240     for Fncref in g:Netrw_corehandler
5241      if type(FncRef) == 2
5242       call FncRef(a:fname)
5243      endif
5244     endfor
5245    endif
5246"    call Decho("restoring posn: screenposn<".string(screenposn).">,'~'.expand("<slnum>"))"
5247    call winrestview(screenposn)
5248    let @@= ykeep
5249    let &aw= awkeep
5250"    call Dret("netrw#BrowseX : coredump handler invoked")
5251    return
5252   endif
5253  endif
5254
5255  " set up the filename
5256  " (lower case the extension, make a local copy of a remote file)
5257  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5258  if has("win32") || has("win95") || has("win64") || has("win16")
5259   let exten= substitute(exten,'^.*$','\L&\E','')
5260  endif
5261  if exten =~ "[\\/]"
5262   let exten= ""
5263  endif
5264"  call Decho("exten<".exten.">",'~'.expand("<slnum>"))
5265
5266  if a:remote == 1
5267   " create a local copy
5268"   call Decho("remote: a:remote=".a:remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
5269   setl bh=delete
5270   call netrw#NetRead(3,a:fname)
5271   " attempt to rename tempfile
5272   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5273   let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5274"   call Decho("basename<".basename.">",'~'.expand("<slnum>"))
5275"   call Decho("newname <".newname.">",'~'.expand("<slnum>"))
5276   if s:netrw_tmpfile != newname && newname != ""
5277    if rename(s:netrw_tmpfile,newname) == 0
5278     " renaming succeeded
5279"     call Decho("renaming succeeded (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5280     let fname= newname
5281    else
5282     " renaming failed
5283"     call Decho("renaming failed (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5284     let fname= s:netrw_tmpfile
5285    endif
5286   else
5287    let fname= s:netrw_tmpfile
5288   endif
5289  else
5290"   call Decho("local: a:remote=".a:remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
5291   let fname= a:fname
5292   " special ~ handler for local
5293   if fname =~ '^\~' && expand("$HOME") != ""
5294"    call Decho('invoking special ~ handler','~'.expand("<slnum>"))
5295    let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5296   endif
5297  endif
5298"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
5299"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
5300
5301  " set up redirection (avoids browser messages)
5302  " by default, g:netrw_suppress_gx_mesg is true
5303  if g:netrw_suppress_gx_mesg
5304   if &srr =~ "%s"
5305    if (has("win32") || has("win95") || has("win64") || has("win16"))
5306     let redir= substitute(&srr,"%s","nul","")
5307    else
5308     let redir= substitute(&srr,"%s","/dev/null","")
5309    endif
5310   elseif (has("win32") || has("win95") || has("win64") || has("win16"))
5311    let redir= &srr . "nul"
5312   else
5313    let redir= &srr . "/dev/null"
5314   endif
5315  endif
5316"  call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
5317
5318  " extract any viewing options.  Assumes that they're set apart by spaces.
5319  if exists("g:netrw_browsex_viewer")
5320"   call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5321   if g:netrw_browsex_viewer =~ '\s'
5322    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5323    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5324    let oviewer = ''
5325    let cnt     = 1
5326    while !executable(viewer) && viewer != oviewer
5327     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5328     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5329     let cnt     = cnt + 1
5330     let oviewer = viewer
5331"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5332    endwhile
5333   else
5334    let viewer  = g:netrw_browsex_viewer
5335    let viewopt = ""
5336   endif
5337"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5338  endif
5339
5340  " execute the file handler
5341"  call Decho("execute the file handler (if any)",'~'.expand("<slnum>"))
5342  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
5343"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5344   let ret= netrwFileHandlers#Invoke(exten,fname)
5345
5346  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
5347"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5348   call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
5349   let ret= v:shell_error
5350
5351  elseif has("win32") || has("win64")
5352"   call Decho("(netrw#BrowseX) win".(has("win32")? "32" : "64"),'~'.expand("<slnum>"))
5353   if executable("start")
5354    call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5355   elseif executable("rundll32")
5356    call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5357   else
5358    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5359   endif
5360   let ret= v:shell_error
5361
5362  elseif has("win32unix")
5363   let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
5364"   call Decho("(netrw#BrowseX) cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
5365   if executable("start")
5366"    call Decho("(netrw#BrowseX) win32unix+start",'~'.expand("<slnum>"))
5367    call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5368   elseif executable("rundll32")
5369"    call Decho("(netrw#BrowseX) win32unix+rundll32",'~'.expand("<slnum>"))
5370    call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5371   elseif executable("cygstart")
5372"    call Decho("(netrw#BrowseX) win32unix+cygstart",'~'.expand("<slnum>"))
5373    call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
5374   else
5375    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5376   endif
5377   let ret= v:shell_error
5378
5379  elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
5380"   call Decho("(netrw#BrowseX) unix and kfmclient",'~'.expand("<slnum>"))
5381   call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
5382   let ret= v:shell_error
5383
5384  elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
5385"   call Decho("(netrw#BrowseX) unix, exo-open, xdg-open",'~'.expand("<slnum>"))
5386   call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir)
5387   let ret= v:shell_error
5388
5389  elseif has("unix") && $DESKTOP_SESSION == "mate" && executable("atril")
5390"   call Decho("(netrw#BrowseX) unix and atril",'~'.expand("<slnum>"))
5391   if a:fname =~ '^https\=://'
5392    " atril does not appear to understand how to handle html -- so use gvim to edit the document
5393    let use_ctrlo= 0
5394"    call Decho("(COMBAK) fname<".fname.">")
5395"    call Decho("(COMBAK) a:fname<".a:fname.">")
5396    call s:NetrwExe("sil! !gvim ".fname.' -c "keepj keepalt file '.fnameescape(a:fname).'"')
5397
5398   else
5399    call s:NetrwExe("sil !atril ".s:ShellEscape(fname,1).redir)
5400   endif
5401   let ret= v:shell_error
5402
5403  elseif has("unix") && executable("xdg-open")
5404"   call Decho("(netrw#BrowseX) unix and xdg-open",'~'.expand("<slnum>"))
5405   call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir)
5406   let ret= v:shell_error
5407
5408  elseif has("macunix") && executable("open")
5409"   call Decho("(netrw#BrowseX) macunix and open",'~'.expand("<slnum>"))
5410   call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
5411   let ret= v:shell_error
5412
5413  else
5414   " netrwFileHandlers#Invoke() always returns 0
5415"   call Decho("(netrw#BrowseX) use netrwFileHandlers",'~'.expand("<slnum>"))
5416   let ret= netrwFileHandlers#Invoke(exten,fname)
5417  endif
5418
5419  " if unsuccessful, attempt netrwFileHandlers#Invoke()
5420  if ret
5421"   call Decho("(netrw#BrowseX) ret=".ret," indicates unsuccessful thus far",'~'.expand("<slnum>"))
5422   let ret= netrwFileHandlers#Invoke(exten,fname)
5423  endif
5424
5425  " restoring redraw! after external file handlers
5426  redraw!
5427
5428  " cleanup: remove temporary file,
5429  "          delete current buffer if success with handler,
5430  "          return to prior buffer (directory listing)
5431  "          Feb 12, 2008: had to de-activiate removal of
5432  "          temporary file because it wasn't getting seen.
5433"  if a:remote == 1 && fname != a:fname
5434""   call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
5435"   call s:NetrwDelete(fname)
5436"  endif
5437
5438  if a:remote == 1
5439   setl bh=delete bt=nofile
5440   if g:netrw_use_noswf
5441    setl noswf
5442   endif
5443   if use_ctrlo
5444    exe "sil! NetrwKeepj norm! \<c-o>"
5445   endif
5446  endif
5447"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5448  call winrestview(screenposn)
5449  let @@ = ykeep
5450  let &aw= awkeep
5451
5452"  call Dret("netrw#BrowseX")
5453endfun
5454
5455" ---------------------------------------------------------------------
5456" netrw#GX: gets word under cursor for gx support {{{2
5457"           See also: netrw#BrowseXVis
5458"                     netrw#BrowseX
5459fun! netrw#GX()
5460"  call Dfunc("netrw#GX()")
5461  if &ft == "netrw"
5462   let fname= s:NetrwGetWord()
5463  else
5464   let fname= expand((exists("g:netrw_gx")? g:netrw_gx : '<cfile>'))
5465  endif
5466"  call Dret("netrw#GX <".fname.">")
5467  return fname
5468endfun
5469
5470" ---------------------------------------------------------------------
5471" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5472fun! netrw#BrowseXVis()
5473"  call Dfunc("netrw#BrowseXVis()")
5474  let akeep = @a
5475  norm! gv"ay
5476  let gxfile= @a
5477  let @a    = akeep
5478  call netrw#BrowseX(gxfile,netrw#CheckIfRemote(gxfile))
5479"  call Dret("netrw#BrowseXVis")
5480endfun
5481
5482" ---------------------------------------------------------------------
5483" s:NetrwBufRename: renames a buffer without the side effect of retaining an unlisted buffer having the old name {{{2
5484"                   Using the file command on a "[No Name]" buffer does not seem to cause the old "[No Name]" buffer
5485"                   to become an unlisted buffer, so in that case don't bwipe it.
5486fun! s:NetrwBufRename(newname)
5487"  call Dfunc("s:NetrwBufRename(newname<".a:newname.">) buf(%)#".bufnr("%")."<".bufname(bufnr("%")).">")
5488"  call Dredir("ls!","s:NetrwBufRename (before rename)")
5489  let oldbufname= bufname(bufnr("%"))
5490"  call Decho("buf#".bufnr("%").": oldbufname<".oldbufname.">",'~'.expand("<slnum>"))
5491
5492  if oldbufname != a:newname
5493"   call Decho("do buffer rename: oldbufname<".oldbufname."> ≠ a:newname<".a:newname.">",'~'.expand("<slnum>"))
5494   let b:junk= 1
5495"   call Decho("rename buffer: sil! keepj keepalt file ".fnameescape(a:newname),'~'.expand("<slnum>"))
5496   exe 'sil! keepj keepalt file '.fnameescape(a:newname)
5497"   call Dredir("ls!","s:NetrwBufRename (before bwipe)")
5498   let oldbufnr= bufnr(oldbufname)
5499"   call Decho("oldbufname<".oldbufname."> oldbufnr#".oldbufnr,'~'.expand("<slnum>"))
5500"   call Decho("bufnr(%)=".bufnr("%"),'~'.expand("<slnum>"))
5501   if oldbufname != "" && oldbufnr != -1 && oldbufnr != bufnr("%")
5502"    call Decho("bwipe ".oldbufnr,'~'.expand("<slnum>"))
5503    exe "bwipe! ".oldbufnr
5504"   else " Decho
5505"    call Decho("did *not* bwipe buf#".oldbufnr,'~'.expand("<slnum>"))
5506   endif
5507"   call Dredir("ls!","s:NetrwBufRename (after rename)")
5508"  else " Decho
5509"   call Decho("oldbufname<".oldbufname."> == a:newname: did *not* rename",'~'.expand("<slnum>"))
5510  endif
5511
5512"  call Dret("s:NetrwBufRename : buf#".bufnr("%").": oldname<".oldbufname."> newname<".a:newname."> expand(%)<".expand("%").">")
5513endfun
5514
5515" ---------------------------------------------------------------------
5516" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5517fun! netrw#CheckIfRemote(...)
5518"  call Dfunc("netrw#CheckIfRemote() a:0=".a:0)
5519  if a:0 > 0
5520   let curfile= a:1
5521  else
5522   let curfile= expand("%")
5523  endif
5524"  call Decho("curfile<".curfile.">")
5525  if curfile =~ '^\a\{3,}://'
5526"   call Dret("netrw#CheckIfRemote 1")
5527   return 1
5528  else
5529"   call Dret("netrw#CheckIfRemote 0")
5530   return 0
5531  endif
5532endfun
5533
5534" ---------------------------------------------------------------------
5535" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5536fun! s:NetrwChgPerm(islocal,curdir)
5537"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
5538  let ykeep  = @@
5539  call inputsave()
5540  let newperm= input("Enter new permission: ")
5541  call inputrestore()
5542  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5543  let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5544"  call Decho("chgperm<".chgperm.">",'~'.expand("<slnum>"))
5545  call system(chgperm)
5546  if v:shell_error != 0
5547   NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5548  endif
5549  if a:islocal
5550   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5551  endif
5552  let @@= ykeep
5553"  call Dret("s:NetrwChgPerm")
5554endfun
5555
5556" ---------------------------------------------------------------------
5557" s:CheckIfKde: checks if kdeinit is running {{{2
5558"    Returns 0: kdeinit not running
5559"            1: kdeinit is  running
5560fun! s:CheckIfKde()
5561"  call Dfunc("s:CheckIfKde()")
5562  " seems kde systems often have gnome-open due to dependencies, even though
5563  " gnome-open's subsidiary display tools are largely absent.  Kde systems
5564  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
5565  if !exists("s:haskdeinit")
5566   if has("unix") && executable("ps") && !has("win32unix")
5567    let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5568    if v:shell_error
5569     let s:haskdeinit = 0
5570    endif
5571   else
5572    let s:haskdeinit= 0
5573   endif
5574"   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5575  endif
5576
5577"  call Dret("s:CheckIfKde ".s:haskdeinit)
5578  return s:haskdeinit
5579endfun
5580
5581" ---------------------------------------------------------------------
5582" s:NetrwClearExplore: clear explore variables (if any) {{{2
5583fun! s:NetrwClearExplore()
5584"  call Dfunc("s:NetrwClearExplore()")
5585  2match none
5586  if exists("s:explore_match")        |unlet s:explore_match        |endif
5587  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
5588  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5589  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
5590  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
5591  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
5592  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5593  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
5594  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
5595"   redraw!
5596  echo " "
5597  echo " "
5598"  call Dret("s:NetrwClearExplore")
5599endfun
5600
5601" ---------------------------------------------------------------------
5602" s:NetrwExploreListUniq: {{{2
5603fun! s:NetrwExploreListUniq(explist)
5604"  call Dfunc("s:NetrwExploreListUniq(explist<".string(a:explist).">)")
5605
5606  " this assumes that the list is already sorted
5607  let newexplist= []
5608  for member in a:explist
5609   if !exists("uniqmember") || member != uniqmember
5610    let uniqmember = member
5611    let newexplist = newexplist + [ member ]
5612   endif
5613  endfor
5614
5615"  call Dret("s:NetrwExploreListUniq newexplist<".string(newexplist).">")
5616  return newexplist
5617endfun
5618
5619" ---------------------------------------------------------------------
5620" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5621fun! s:NetrwForceChgDir(islocal,newdir)
5622"  call Dfunc("s:NetrwForceChgDir(islocal=".a:islocal." newdir<".a:newdir.">)")
5623  let ykeep= @@
5624  if a:newdir !~ '/$'
5625   " ok, looks like force is needed to get directory-style treatment
5626   if a:newdir =~ '@$'
5627    let newdir= substitute(a:newdir,'@$','/','')
5628   elseif a:newdir =~ '[*=|\\]$'
5629    let newdir= substitute(a:newdir,'.$','/','')
5630   else
5631    let newdir= a:newdir.'/'
5632   endif
5633"   call Decho("adjusting newdir<".newdir."> due to gd",'~'.expand("<slnum>"))
5634  else
5635   " should already be getting treatment as a directory
5636   let newdir= a:newdir
5637  endif
5638  let newdir= s:NetrwBrowseChgDir(a:islocal,newdir)
5639  call s:NetrwBrowse(a:islocal,newdir)
5640  let @@= ykeep
5641"  call Dret("s:NetrwForceChgDir")
5642endfun
5643
5644" ---------------------------------------------------------------------
5645" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5646"     direntry: this is the name of the directory.  Will be fnameescape'd to prevent wildcard handling by glob()
5647"     expr    : this is the expression to follow the directory.  Will use s:ComposePath()
5648"     pare    =1: remove the current directory from the resulting glob() filelist
5649"             =0: leave  the current directory   in the resulting glob() filelist
5650fun! s:NetrwGlob(direntry,expr,pare)
5651"  call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")")
5652  if netrw#CheckIfRemote()
5653   keepalt 1sp
5654   keepalt enew
5655   let keep_liststyle    = w:netrw_liststyle
5656   let w:netrw_liststyle = s:THINLIST
5657   if s:NetrwRemoteListing() == 0
5658    keepj keepalt %s@/@@
5659    let filelist= getline(1,$)
5660    q!
5661   else
5662    " remote listing error -- leave treedict unchanged
5663    let filelist= w:netrw_treedict[a:direntry]
5664   endif
5665   let w:netrw_liststyle= keep_liststyle
5666  elseif v:version > 704 || (v:version == 704 && has("patch656"))
5667   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1)
5668   if a:pare
5669    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5670   endif
5671  else
5672   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1)
5673   if a:pare
5674    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5675   endif
5676  endif
5677"  call Dret("s:NetrwGlob ".string(filelist))
5678  return filelist
5679endfun
5680
5681" ---------------------------------------------------------------------
5682" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5683fun! s:NetrwForceFile(islocal,newfile)
5684"  call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)")
5685  if a:newfile =~ '[/@*=|\\]$'
5686   let newfile= substitute(a:newfile,'.$','','')
5687  else
5688   let newfile= a:newfile
5689  endif
5690  if a:islocal
5691   call s:NetrwBrowseChgDir(a:islocal,newfile)
5692  else
5693   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile))
5694  endif
5695"  call Dret("s:NetrwForceFile")
5696endfun
5697
5698" ---------------------------------------------------------------------
5699" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5700"          and switches the hiding mode.  The actual hiding is done by
5701"          s:NetrwListHide().
5702"             g:netrw_hide= 0: show all
5703"                           1: show not-hidden files
5704"                           2: show hidden files only
5705fun! s:NetrwHide(islocal)
5706"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
5707  let ykeep= @@
5708  let svpos= winsaveview()
5709"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5710
5711  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5712"   call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>"))
5713"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5714
5715   " hide the files in the markfile list
5716   for fname in s:netrwmarkfilelist_{bufnr("%")}
5717"    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>"))
5718    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5719     " remove fname from hiding list
5720     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5721     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5722     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5723"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5724    else
5725     " append fname to hiding list
5726     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5727      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5728     else
5729      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5730     endif
5731"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5732    endif
5733   endfor
5734   NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5735   let g:netrw_hide= 1
5736
5737  else
5738
5739   " switch between show-all/show-not-hidden/show-hidden
5740   let g:netrw_hide=(g:netrw_hide+1)%3
5741   exe "NetrwKeepj norm! 0"
5742   if g:netrw_hide && g:netrw_list_hide == ""
5743    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5744    let @@= ykeep
5745"    call Dret("NetrwHide")
5746    return
5747   endif
5748  endif
5749
5750  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5751"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5752  NetrwKeepj call winrestview(svpos)
5753  let @@= ykeep
5754"  call Dret("NetrwHide")
5755endfun
5756
5757" ---------------------------------------------------------------------
5758" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5759fun! s:NetrwHideEdit(islocal)
5760"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
5761
5762  let ykeep= @@
5763  " save current cursor position
5764  let svpos= winsaveview()
5765"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5766
5767  " get new hiding list from user
5768  call inputsave()
5769  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5770  call inputrestore()
5771  let g:netrw_list_hide= newhide
5772"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5773
5774  " refresh the listing
5775  sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
5776
5777  " restore cursor position
5778"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5779  call winrestview(svpos)
5780  let @@= ykeep
5781
5782"  call Dret("NetrwHideEdit")
5783endfun
5784
5785" ---------------------------------------------------------------------
5786" s:NetrwHidden: invoked by "gh" {{{2
5787fun! s:NetrwHidden(islocal)
5788"  call Dfunc("s:NetrwHidden()")
5789  let ykeep= @@
5790  "  save current position
5791  let svpos  = winsaveview()
5792"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5793
5794  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5795   " remove .file pattern from hiding list
5796"   call Decho("remove .file pattern from hiding list",'~'.expand("<slnum>"))
5797   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5798  elseif s:Strlen(g:netrw_list_hide) >= 1
5799"   call Decho("add .file pattern from hiding list",'~'.expand("<slnum>"))
5800   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5801  else
5802"   call Decho("set .file pattern as hiding list",'~'.expand("<slnum>"))
5803   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5804  endif
5805  if g:netrw_list_hide =~ '^,'
5806   let g:netrw_list_hide= strpart(g:netrw_list_hide,1)
5807  endif
5808
5809  " refresh screen and return to saved position
5810  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5811"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5812  NetrwKeepj call winrestview(svpos)
5813  let @@= ykeep
5814"  call Dret("s:NetrwHidden")
5815endfun
5816
5817" ---------------------------------------------------------------------
5818"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5819fun! s:NetrwHome()
5820  if exists("g:netrw_home")
5821   let home= expand(g:netrw_home)
5822  else
5823   " go to vim plugin home
5824   for home in split(&rtp,',') + ['']
5825    if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5826     let basehome= substitute(home,'[/\\]\.vim$','','')
5827     if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5828     let home= basehome."/.vim"
5829     break
5830    endif
5831   endfor
5832   if home == ""
5833    " just pick the first directory
5834    let home= substitute(&rtp,',.*$','','')
5835   endif
5836   if (has("win32") || has("win95") || has("win64") || has("win16"))
5837    let home= substitute(home,'/','\\','g')
5838   endif
5839  endif
5840  " insure that the home directory exists
5841  if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5842"   call Decho("insure that the home<".home."> directory exists")
5843   if exists("g:netrw_mkdir")
5844"    call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")")
5845    call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5846   else
5847"    call Decho("mkdir(".home.")")
5848    call mkdir(home)
5849   endif
5850  endif
5851  let g:netrw_home= home
5852  return home
5853endfun
5854
5855" ---------------------------------------------------------------------
5856" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5857fun! s:NetrwLeftmouse(islocal)
5858  if exists("s:netrwdrag")
5859   return
5860  endif
5861  if &ft != "netrw"
5862   return
5863  endif
5864"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
5865
5866  let ykeep= @@
5867  " check if the status bar was clicked on instead of a file/directory name
5868  while getchar(0) != 0
5869   "clear the input stream
5870  endwhile
5871  call feedkeys("\<LeftMouse>")
5872  let c          = getchar()
5873  let mouse_lnum = v:mouse_lnum
5874  let wlastline  = line('w$')
5875  let lastline   = line('$')
5876"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr(),'~'.expand("<slnum>"))
5877"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0),'~'.expand("<slnum>"))
5878  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5879   " appears to be a status bar leftmouse click
5880   let @@= ykeep
5881"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
5882   return
5883  endif
5884   " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5885   " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5886   " without this test when its disabled.
5887   " May 26, 2014: edit file, :Lex, resize window -- causes refresh.  Reinstated a modified test.  See if problems develop.
5888"   call Decho("v:mouse_col=".v:mouse_col." col#".col('.')." virtcol#".virtcol('.')." col($)#".col("$")." virtcol($)#".virtcol("$"),'~'.expand("<slnum>"))
5889   if v:mouse_col > virtcol('.')
5890    let @@= ykeep
5891"    call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
5892    return
5893   endif
5894
5895  if a:islocal
5896   if exists("b:netrw_curdir")
5897    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
5898   endif
5899  else
5900   if exists("b:netrw_curdir")
5901    NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5902   endif
5903  endif
5904  let @@= ykeep
5905"  call Dret("s:NetrwLeftmouse")
5906endfun
5907
5908" ---------------------------------------------------------------------
5909" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5910fun! s:NetrwCLeftmouse(islocal)
5911  if &ft != "netrw"
5912   return
5913  endif
5914"  call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")")
5915  call s:NetrwMarkFileTgt(a:islocal)
5916"  call Dret("s:NetrwCLeftmouse")
5917endfun
5918
5919" ---------------------------------------------------------------------
5920" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER  (implements <c-r>){{{2
5921"   a:islocal=0 : <c-r> not used, remote
5922"   a:islocal=1 : <c-r> not used, local
5923"   a:islocal=2 : <c-r>     used, remote
5924"   a:islocal=3 : <c-r>     used, local
5925fun! s:NetrwServerEdit(islocal,fname)
5926"  call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5927  let islocal = a:islocal%2      " =0: remote           =1: local
5928  let ctrlr   = a:islocal >= 2   " =0: <c-r> not used   =1: <c-r> used
5929"  call Decho("islocal=".islocal." ctrlr=".ctrlr,'~'.expand("<slnum>"))
5930
5931  if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5932   " handle directories in the local window -- not in the remote vim server
5933   " user must have closed the NETRWSERVER window.  Treat as normal editing from netrw.
5934"   call Decho("handling directory in client window",'~'.expand("<slnum>"))
5935   let g:netrw_browse_split= 0
5936   if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
5937    let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5938    unlet s:netrw_browse_split_{winnr()}
5939   endif
5940   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5941"   call Dret("s:NetrwServerEdit")
5942   return
5943  endif
5944
5945"  call Decho("handling file in server window",'~'.expand("<slnum>"))
5946  if has("clientserver") && executable("gvim")
5947"   call Decho("has clientserver and gvim",'~'.expand("<slnum>"))
5948
5949    if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
5950"     call Decho("g:netrw_browse_split=".string(g:netrw_browse_split),'~'.expand("<slnum>"))
5951     let srvrname = g:netrw_browse_split[0]
5952     let tabnum   = g:netrw_browse_split[1]
5953     let winnum   = g:netrw_browse_split[2]
5954
5955     if serverlist() !~ '\<'.srvrname.'\>'
5956"      call Decho("server not available; ctrlr=".ctrlr,'~'.expand("<slnum>"))
5957
5958      if !ctrlr
5959       " user must have closed the server window and the user did not use <c-r>, but
5960       " used something like <cr>.
5961"       call Decho("user must have closed server AND did not use ctrl-r",'~'.expand("<slnum>"))
5962       if exists("g:netrw_browse_split")
5963	unlet g:netrw_browse_split
5964       endif
5965       let g:netrw_browse_split= 0
5966       if exists("s:netrw_browse_split_".winnr())
5967        let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5968       endif
5969       call s:NetrwBrowseChgDir(islocal,a:fname)
5970"       call Dret("s:NetrwServerEdit")
5971       return
5972
5973      elseif has("win32") && executable("start")
5974       " start up remote netrw server under windows
5975"       call Decho("starting up gvim server<".srvrname."> for windows",'~'.expand("<slnum>"))
5976       call system("start gvim --servername ".srvrname)
5977
5978      else
5979       " start up remote netrw server under linux
5980"       call Decho("starting up gvim server<".srvrname.">",'~'.expand("<slnum>"))
5981       call system("gvim --servername ".srvrname)
5982      endif
5983     endif
5984
5985"     call Decho("srvrname<".srvrname."> tabnum=".tabnum." winnum=".winnum." server-editing<".a:fname.">",'~'.expand("<slnum>"))
5986     call remote_send(srvrname,":tabn ".tabnum."\<cr>")
5987     call remote_send(srvrname,":".winnum."wincmd w\<cr>")
5988     call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5989
5990    else
5991
5992     if serverlist() !~ '\<'.g:netrw_servername.'\>'
5993
5994      if !ctrlr
5995"       call Decho("server<".g:netrw_servername."> not available and ctrl-r not used",'~'.expand("<slnum>"))
5996       if exists("g:netrw_browse_split")
5997	unlet g:netrw_browse_split
5998       endif
5999       let g:netrw_browse_split= 0
6000       call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
6001"       call Dret("s:NetrwServerEdit")
6002       return
6003
6004      else
6005"       call Decho("server<".g:netrw_servername."> not available but ctrl-r used",'~'.expand("<slnum>"))
6006       if has("win32") && executable("start")
6007        " start up remote netrw server under windows
6008"        call Decho("starting up gvim server<".g:netrw_servername."> for windows",'~'.expand("<slnum>"))
6009        call system("start gvim --servername ".g:netrw_servername)
6010       else
6011        " start up remote netrw server under linux
6012"        call Decho("starting up gvim server<".g:netrw_servername.">",'~'.expand("<slnum>"))
6013        call system("gvim --servername ".g:netrw_servername)
6014       endif
6015      endif
6016     endif
6017
6018     while 1
6019      try
6020"       call Decho("remote-send: e ".a:fname,'~'.expand("<slnum>"))
6021       call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
6022       break
6023      catch /^Vim\%((\a\+)\)\=:E241/
6024       sleep 200m
6025      endtry
6026     endwhile
6027
6028     if exists("g:netrw_browse_split")
6029      if type(g:netrw_browse_split) != 3
6030        let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
6031       endif
6032      unlet g:netrw_browse_split
6033     endif
6034     let g:netrw_browse_split= [g:netrw_servername,1,1]
6035    endif
6036
6037   else
6038    call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
6039   endif
6040
6041"  call Dret("s:NetrwServerEdit")
6042endfun
6043
6044" ---------------------------------------------------------------------
6045" s:NetrwSLeftmouse: marks the file under the cursor.  May be dragged to select additional files {{{2
6046fun! s:NetrwSLeftmouse(islocal)
6047  if &ft != "netrw"
6048   return
6049  endif
6050"  call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
6051
6052  let s:ngw= s:NetrwGetWord()
6053  call s:NetrwMarkFile(a:islocal,s:ngw)
6054
6055"  call Dret("s:NetrwSLeftmouse")
6056endfun
6057
6058" ---------------------------------------------------------------------
6059" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
6060"                   Used to mark multiple files.
6061fun! s:NetrwSLeftdrag(islocal)
6062"  call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
6063  if !exists("s:netrwdrag")
6064   let s:netrwdrag = winnr()
6065   if a:islocal
6066    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
6067   else
6068    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
6069   endif
6070  endif
6071  let ngw = s:NetrwGetWord()
6072  if !exists("s:ngw") || s:ngw != ngw
6073   call s:NetrwMarkFile(a:islocal,ngw)
6074  endif
6075  let s:ngw= ngw
6076"  call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
6077endfun
6078
6079" ---------------------------------------------------------------------
6080" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
6081fun! s:NetrwSLeftrelease(islocal)
6082"  call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
6083  if exists("s:netrwdrag")
6084   nunmap <s-leftrelease>
6085   let ngw = s:NetrwGetWord()
6086   if !exists("s:ngw") || s:ngw != ngw
6087    call s:NetrwMarkFile(a:islocal,ngw)
6088   endif
6089   if exists("s:ngw")
6090    unlet s:ngw
6091   endif
6092   unlet s:netrwdrag
6093  endif
6094"  call Dret("s:NetrwSLeftrelease")
6095endfun
6096
6097" ---------------------------------------------------------------------
6098" s:NetrwListHide: uses [range]g~...~d to delete files that match       {{{2
6099"                  comma-separated patterns given in g:netrw_list_hide
6100fun! s:NetrwListHide()
6101"  call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
6102"  call Decho("initial: ".string(getline(w:netrw_bannercnt,'$')))
6103  let ykeep= @@
6104
6105  " find a character not in the "hide" string to use as a separator for :g and :v commands
6106  " How-it-works: take the hiding command, convert it into a range.
6107  " Duplicate characters don't matter.
6108  " Remove all such characters from the '/~@#...890' string.
6109  " Use the first character left as a separator character.
6110"  call Decho("find a character not in the hide string to use as a separator")
6111  let listhide= g:netrw_list_hide
6112  let sep     = strpart(substitute('~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
6113"  call Decho("sep=".sep,"  (sep not in hide string)'~'.expand("<slnum>"))
6114
6115  while listhide != ""
6116   if listhide =~ ','
6117    let hide     = substitute(listhide,',.*$','','e')
6118    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
6119   else
6120    let hide     = listhide
6121    let listhide = ""
6122   endif
6123"   call Decho("..extracted from listhide: hide<".hide."> g:netrw_sort_by<".g:netrw_sort_by.'>','~'.expand("<slnum>"))
6124   if g:netrw_sort_by =~ '^[ts]'
6125    if hide =~ '^\^'
6126"     call Decho("..modify hide to handle a \"^...\" pattern",'~'.expand("<slnum>"))
6127     let hide= substitute(hide,'^\^','^\(\\d\\+/\)','')
6128    elseif hide =~ '^\\(\^'
6129     let hide= substitute(hide,'^\\(\^','\\(^\\(\\d\\+/\\)','')
6130    endif
6131"    call Decho("..hide<".hide."> listhide<".listhide.'>','~'.expand("<slnum>"))
6132   endif
6133
6134   " Prune the list by hiding any files which match
6135"   call Decho("..prune the list by hiding any files which ",((g:netrw_hide == 1)? "" : "don't")." match hide<".hide.">")
6136   if g:netrw_hide == 1
6137"    call Decho("..hiding<".hide.">",'~'.expand("<slnum>"))
6138    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
6139   elseif g:netrw_hide == 2
6140"    call Decho("..showing<".hide.">",'~'.expand("<slnum>"))
6141    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
6142   endif
6143"   call Decho("..result: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6144  endwhile
6145
6146  if g:netrw_hide == 2
6147   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
6148"   call Decho("..v KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6149   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
6150"   call Decho("..g KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6151  endif
6152
6153  " remove any blank lines that have somehow remained.
6154  " This seems to happen under Windows.
6155  exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
6156
6157  let @@= ykeep
6158"  call Dret("s:NetrwListHide")
6159endfun
6160
6161" ---------------------------------------------------------------------
6162" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
6163"                 implements the "d" mapping.
6164fun! s:NetrwMakeDir(usrhost)
6165"  call Dfunc("s:NetrwMakeDir(usrhost<".a:usrhost.">)")
6166
6167  let ykeep= @@
6168  " get name of new directory from user.  A bare <CR> will skip.
6169  " if its currently a directory, also request will be skipped, but with
6170  " a message.
6171  call inputsave()
6172  let newdirname= input("Please give directory name: ")
6173  call inputrestore()
6174"  call Decho("newdirname<".newdirname.">",'~'.expand("<slnum>"))
6175
6176  if newdirname == ""
6177   let @@= ykeep
6178"   call Dret("s:NetrwMakeDir : user aborted with bare <cr>")
6179   return
6180  endif
6181
6182  if a:usrhost == ""
6183"   call Decho("local mkdir",'~'.expand("<slnum>"))
6184
6185   " Local mkdir:
6186   " sanity checks
6187   let fullnewdir= b:netrw_curdir.'/'.newdirname
6188"   call Decho("fullnewdir<".fullnewdir.">",'~'.expand("<slnum>"))
6189   if isdirectory(s:NetrwFile(fullnewdir))
6190    if !exists("g:netrw_quiet")
6191     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
6192    endif
6193    let @@= ykeep
6194"    call Dret("s:NetrwMakeDir : directory<".newdirname."> exists previously")
6195    return
6196   endif
6197   if s:FileReadable(fullnewdir)
6198    if !exists("g:netrw_quiet")
6199     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
6200    endif
6201    let @@= ykeep
6202"    call Dret("s:NetrwMakeDir : file<".newdirname."> exists previously")
6203    return
6204   endif
6205
6206   " requested new local directory is neither a pre-existing file or
6207   " directory, so make it!
6208   if exists("*mkdir")
6209    if has("unix")
6210     call mkdir(fullnewdir,"p",xor(0777, system("umask")))
6211    else
6212     call mkdir(fullnewdir,"p")
6213    endif
6214   else
6215    let netrw_origdir= s:NetrwGetcwd(1)
6216    if s:NetrwLcd(b:netrw_curdir)
6217"    call Dret("s:NetrwMakeDir : lcd failure")
6218     return
6219    endif
6220"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("<slnum>"))
6221    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(newdirname,1))
6222    if v:shell_error != 0
6223     let @@= ykeep
6224     call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6225"     call Dret("s:NetrwMakeDir : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
6226     return
6227    endif
6228    if !g:netrw_keepdir
6229"     call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
6230     if s:NetrwLcd(netrw_origdir)
6231"     call Dret("s:NetrwBrowse : lcd failure")
6232      return
6233     endif
6234    endif
6235   endif
6236
6237   if v:shell_error == 0
6238    " refresh listing
6239"    call Decho("refresh listing",'~'.expand("<slnum>"))
6240    let svpos= winsaveview()
6241"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6242    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
6243"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6244    call winrestview(svpos)
6245   elseif !exists("g:netrw_quiet")
6246    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
6247   endif
6248"   redraw!
6249
6250  elseif !exists("b:netrw_method") || b:netrw_method == 4
6251   " Remote mkdir:  using ssh
6252"   call Decho("remote mkdir",'~'.expand("<slnum>"))
6253   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
6254   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
6255   call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
6256   if v:shell_error == 0
6257    " refresh listing
6258    let svpos= winsaveview()
6259"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6260    NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6261"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6262    NetrwKeepj call winrestview(svpos)
6263   elseif !exists("g:netrw_quiet")
6264    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
6265   endif
6266"   redraw!
6267
6268  elseif b:netrw_method == 2
6269   " Remote mkdir:  using ftp+.netrc
6270   let svpos= winsaveview()
6271"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6272"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6273   if exists("b:netrw_fname")
6274"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6275    let remotepath= b:netrw_fname
6276   else
6277    let remotepath= ""
6278   endif
6279   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6280   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6281"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6282   NetrwKeepj call winrestview(svpos)
6283
6284  elseif b:netrw_method == 3
6285   " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
6286   let svpos= winsaveview()
6287"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6288"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6289   if exists("b:netrw_fname")
6290"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6291    let remotepath= b:netrw_fname
6292   else
6293    let remotepath= ""
6294   endif
6295   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6296   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6297"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6298   NetrwKeepj call winrestview(svpos)
6299  endif
6300
6301  let @@= ykeep
6302"  call Dret("s:NetrwMakeDir")
6303endfun
6304
6305" ---------------------------------------------------------------------
6306" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
6307fun! s:TreeSqueezeDir(islocal)
6308"  call Dfunc("s:TreeSqueezeDir(islocal=".a:islocal.")")
6309  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6310   " its a tree-listing style
6311   let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
6312   let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
6313   let depth    = strchars(substitute(curdepth,' ','','g'))
6314   let srch     = -1
6315"   call Decho("curdepth<".curdepth.'>','~'.expand("<slnum>"))
6316"   call Decho("depth   =".depth,'~'.expand("<slnum>"))
6317"   call Decho("stopline#".stopline,'~'.expand("<slnum>"))
6318"   call Decho("curline#".line(".")."<".getline('.').'>','~'.expand("<slnum>"))
6319   if depth >= 2
6320    NetrwKeepj norm! 0
6321    let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
6322    let srch      = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
6323"    call Decho("curdepthm1<".curdepthm1.'>','~'.expand("<slnum>"))
6324"    call Decho("case depth>=2: srch<".srch.'>','~'.expand("<slnum>"))
6325   elseif depth == 1
6326    NetrwKeepj norm! 0
6327    let treedepthchr= substitute(s:treedepthstring,' ','','')
6328    let srch        = search('^[^'.treedepthchr.']','bW',stopline)
6329"    call Decho("case depth==1: srch<".srch.'>','~'.expand("<slnum>"))
6330   endif
6331   if srch > 0
6332"    call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
6333    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord()))
6334    exe srch
6335   endif
6336  endif
6337"  call Dret("s:TreeSqueezeDir")
6338endfun
6339
6340" ---------------------------------------------------------------------
6341" s:NetrwMaps: {{{2
6342fun! s:NetrwMaps(islocal)
6343"  call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6344
6345  " mouse <Plug> maps: {{{3
6346  if g:netrw_mousemaps && g:netrw_retmap
6347"   call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
6348   if !hasmapto("<Plug>NetrwReturn")
6349    if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
6350"     call Decho("making map for 2-leftmouse",'~'.expand("<slnum>"))
6351     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
6352    elseif maparg("<c-leftmouse>","n") == ""
6353"     call Decho("making map for c-leftmouse",'~'.expand("<slnum>"))
6354     nmap <unique> <silent> <c-leftmouse>	<Plug>NetrwReturn
6355    endif
6356   endif
6357   nno <silent> <Plug>NetrwReturn	:Rexplore<cr>
6358"   call Decho("made <Plug>NetrwReturn map",'~'.expand("<slnum>"))
6359  endif
6360
6361  " generate default <Plug> maps {{{3
6362  if !hasmapto('<Plug>NetrwHide')              |nmap <buffer> <silent> <nowait> a	<Plug>NetrwHide_a|endif
6363  if !hasmapto('<Plug>NetrwBrowseUpDir')       |nmap <buffer> <silent> <nowait> -	<Plug>NetrwBrowseUpDir|endif
6364  if !hasmapto('<Plug>NetrwOpenFile')          |nmap <buffer> <silent> <nowait> %	<Plug>NetrwOpenFile|endif
6365  if !hasmapto('<Plug>NetrwBadd_cb')           |nmap <buffer> <silent> <nowait> cb	<Plug>NetrwBadd_cb|endif
6366  if !hasmapto('<Plug>NetrwBadd_cB')           |nmap <buffer> <silent> <nowait> cB	<Plug>NetrwBadd_cB|endif
6367  if !hasmapto('<Plug>NetrwLcd')               |nmap <buffer> <silent> <nowait> cd	<Plug>NetrwLcd|endif
6368  if !hasmapto('<Plug>NetrwSetChgwin')         |nmap <buffer> <silent> <nowait> C	<Plug>NetrwSetChgwin|endif
6369  if !hasmapto('<Plug>NetrwRefresh')           |nmap <buffer> <silent> <nowait> <c-l>	<Plug>NetrwRefresh|endif
6370  if !hasmapto('<Plug>NetrwLocalBrowseCheck')  |nmap <buffer> <silent> <nowait> <cr>	<Plug>NetrwLocalBrowseCheck|endif
6371  if !hasmapto('<Plug>NetrwServerEdit')        |nmap <buffer> <silent> <nowait> <c-r>	<Plug>NetrwServerEdit|endif
6372  if !hasmapto('<Plug>NetrwMakeDir')           |nmap <buffer> <silent> <nowait> d	<Plug>NetrwMakeDir|endif
6373  if !hasmapto('<Plug>NetrwBookHistHandler_gb')|nmap <buffer> <silent> <nowait> gb	<Plug>NetrwBookHistHandler_gb|endif
6374" ---------------------------------------------------------------------
6375"  if !hasmapto('<Plug>NetrwForceChgDir')       |nmap <buffer> <silent> <nowait> gd	<Plug>NetrwForceChgDir|endif
6376"  if !hasmapto('<Plug>NetrwForceFile')         |nmap <buffer> <silent> <nowait> gf	<Plug>NetrwForceFile|endif
6377"  if !hasmapto('<Plug>NetrwHidden')            |nmap <buffer> <silent> <nowait> gh	<Plug>NetrwHidden|endif
6378"  if !hasmapto('<Plug>NetrwSetTreetop')        |nmap <buffer> <silent> <nowait> gn	<Plug>NetrwSetTreetop|endif
6379"  if !hasmapto('<Plug>NetrwChgPerm')           |nmap <buffer> <silent> <nowait> gp	<Plug>NetrwChgPerm|endif
6380"  if !hasmapto('<Plug>NetrwBannerCtrl')        |nmap <buffer> <silent> <nowait> I	<Plug>NetrwBannerCtrl|endif
6381"  if !hasmapto('<Plug>NetrwListStyle')         |nmap <buffer> <silent> <nowait> i	<Plug>NetrwListStyle|endif
6382"  if !hasmapto('<Plug>NetrwMarkMoveMF2Arglist')|nmap <buffer> <silent> <nowait> ma	<Plug>NetrwMarkMoveMF2Arglist|endif
6383"  if !hasmapto('<Plug>NetrwMarkMoveArglist2MF')|nmap <buffer> <silent> <nowait> mA	<Plug>NetrwMarkMoveArglist2MF|endif
6384"  if !hasmapto('<Plug>NetrwBookHistHandler_mA')|nmap <buffer> <silent> <nowait> mb	<Plug>NetrwBookHistHandler_mA|endif
6385"  if !hasmapto('<Plug>NetrwBookHistHandler_mB')|nmap <buffer> <silent> <nowait> mB	<Plug>NetrwBookHistHandler_mB|endif
6386"  if !hasmapto('<Plug>NetrwMarkFileCopy')      |nmap <buffer> <silent> <nowait> mc	<Plug>NetrwMarkFileCopy|endif
6387"  if !hasmapto('<Plug>NetrwMarkFileDiff')      |nmap <buffer> <silent> <nowait> md	<Plug>NetrwMarkFileDiff|endif
6388"  if !hasmapto('<Plug>NetrwMarkFileEdit')      |nmap <buffer> <silent> <nowait> me	<Plug>NetrwMarkFileEdit|endif
6389"  if !hasmapto('<Plug>NetrwMarkFile')          |nmap <buffer> <silent> <nowait> mf	<Plug>NetrwMarkFile|endif
6390"  if !hasmapto('<Plug>NetrwUnmarkList')        |nmap <buffer> <silent> <nowait> mF	<Plug>NetrwUnmarkList|endif
6391"  if !hasmapto('<Plug>NetrwMarkFileGrep')      |nmap <buffer> <silent> <nowait> mg	<Plug>NetrwMarkFileGrep|endif
6392"  if !hasmapto('<Plug>NetrwMarkHideSfx')       |nmap <buffer> <silent> <nowait> mh	<Plug>NetrwMarkHideSfx|endif
6393"  if !hasmapto('<Plug>NetrwMarkFileMove')      |nmap <buffer> <silent> <nowait> mm	<Plug>NetrwMarkFileMove|endif
6394"  if !hasmapto('<Plug>NetrwMarkFilePrint')     |nmap <buffer> <silent> <nowait> mp	<Plug>NetrwMarkFilePrint|endif
6395"  if !hasmapto('<Plug>NetrwMarkFileRegexp')    |nmap <buffer> <silent> <nowait> mr	<Plug>NetrwMarkFileRegexp|endif
6396"  if !hasmapto('<Plug>NetrwMarkFileSource')    |nmap <buffer> <silent> <nowait> ms	<Plug>NetrwMarkFileSource|endif
6397"  if !hasmapto('<Plug>NetrwMarkFileTag')       |nmap <buffer> <silent> <nowait> mT	<Plug>NetrwMarkFileTag|endif
6398"  if !hasmapto('<Plug>NetrwMarkFileTgt')       |nmap <buffer> <silent> <nowait> mt	<Plug>NetrwMarkFileTgt|endif
6399"  if !hasmapto('<Plug>NetrwUnMarkFile')        |nmap <buffer> <silent> <nowait> mu	<Plug>NetrwUnMarkFile|endif
6400"  if !hasmapto('<Plug>NetrwMarkFileVimCmd')    |nmap <buffer> <silent> <nowait> mv	<Plug>NetrwMarkFileVimCmd|endif
6401"  if !hasmapto('<Plug>NetrwMarkFileExe_mx')    |nmap <buffer> <silent> <nowait> mx	<Plug>NetrwMarkFileExe_mx|endif
6402"  if !hasmapto('<Plug>NetrwMarkFileExe_mX')    |nmap <buffer> <silent> <nowait> mX	<Plug>NetrwMarkFileExe_mX|endif
6403"  if !hasmapto('<Plug>NetrwMarkFileCompress')  |nmap <buffer> <silent> <nowait> mz	<Plug>NetrwMarkFileCompress|endif
6404"  if !hasmapto('<Plug>NetrwObtain')            |nmap <buffer> <silent> <nowait> O	<Plug>NetrwObtain|endif
6405"  if !hasmapto('<Plug>NetrwSplit_o')           |nmap <buffer> <silent> <nowait> o	<Plug>NetrwSplit_o|endif
6406"  if !hasmapto('<Plug>NetrwPreview')           |nmap <buffer> <silent> <nowait> p	<Plug>NetrwPreview|endif
6407"  if !hasmapto('<Plug>NetrwPrevWinOpen')       |nmap <buffer> <silent> <nowait> P	<Plug>NetrwPrevWinOpen|endif
6408"  if !hasmapto('<Plug>NetrwBookHistHandler_qb')|nmap <buffer> <silent> <nowait> qb	<Plug>NetrwBookHistHandler_qb|endif
6409"  if !hasmapto('<Plug>NetrwFileInfo')          |nmap <buffer> <silent> <nowait> qf	<Plug>NetrwFileInfo|endif
6410"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qF')   |nmap <buffer> <silent> <nowait> qF	<Plug>NetrwMarkFileQFEL_qF|endif
6411"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qL')   |nmap <buffer> <silent> <nowait> qL	<Plug>NetrwMarkFileQFEL_qL|endif
6412"  if !hasmapto('<Plug>NetrwSortStyle')         |nmap <buffer> <silent> <nowait> s	<Plug>NetrwSortStyle|endif
6413"  if !hasmapto('<Plug>NetSortSequence')        |nmap <buffer> <silent> <nowait> S	<Plug>NetSortSequence|endif
6414"  if !hasmapto('<Plug>NetrwSetTgt_Tb')         |nmap <buffer> <silent> <nowait> Tb	<Plug>NetrwSetTgt_Tb|endif
6415"  if !hasmapto('<Plug>NetrwSetTgt_Th')         |nmap <buffer> <silent> <nowait> Th	<Plug>NetrwSetTgt_Th|endif
6416"  if !hasmapto('<Plug>NetrwSplit_t')           |nmap <buffer> <silent> <nowait> t	<Plug>NetrwSplit_t|endif
6417"  if !hasmapto('<Plug>NetrwBookHistHandler_u') |nmap <buffer> <silent> <nowait> u	<Plug>NetrwBookHistHandler_u|endif
6418"  if !hasmapto('<Plug>NetrwBookHistHandler_U') |nmap <buffer> <silent> <nowait> U	<Plug>NetrwBookHistHandler_U|endif
6419"  if !hasmapto('<Plug>NetrwSplit_v')           |nmap <buffer> <silent> <nowait> v	<Plug>NetrwSplit_v|endif
6420"  if !hasmapto('<Plug>NetrwBrowseX')           |nmap <buffer> <silent> <nowait> x	<Plug>NetrwBrowseX|endif
6421"  if !hasmapto('<Plug>NetrwLocalExecute')      |nmap <buffer> <silent> <nowait> X	<Plug>NetrwLocalExecute|endif
6422
6423  if a:islocal
6424"   call Decho("make local maps",'~'.expand("<slnum>"))
6425   " local normal-mode maps {{{3
6426   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(1)<cr>
6427   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6428   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(1)<cr>
6429   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(1,0)<cr>
6430   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(1,1)<cr>
6431   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6432   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6433   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6434   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6435   nnoremap <buffer> <silent> <Plug>NetrwMakeDir		:<c-u>call <SID>NetrwMakeDir("")<cr>
6436   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6437" ---------------------------------------------------------------------
6438   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6439   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6440   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
6441   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(0,<SID>NetrwGetWord())<cr>
6442   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6443   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6444   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(1)<cr>
6445   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6446   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6447   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6448   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6449   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6450   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6451   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6452   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6453   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6454   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6455   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6456   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6457   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6458   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6459   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6460   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6461   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6462   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6463   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6464   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6465   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6466   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6467   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(1)<cr>
6468   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(3)<cr>
6469   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6470   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6471   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6472   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6473   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6474   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6475   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(1)<cr>
6476   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(1)<cr>
6477   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6478   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(4)<cr>
6479   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6480   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6481   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6482   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(5)<cr>
6483   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6484   nnoremap <buffer> <silent> <nowait> X	:<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6485
6486   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>
6487   if !hasmapto('<Plug>NetrwHideEdit')
6488    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6489   endif
6490   nnoremap <buffer> <silent> <Plug>NetrwHideEdit		:call <SID>NetrwHideEdit(1)<cr>
6491   if !hasmapto('<Plug>NetrwRefresh')
6492    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6493   endif
6494   nnoremap <buffer> <silent> <Plug>NetrwRefresh		<c-l>:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr>
6495   if s:didstarstar || !mapcheck("<s-down>","n")
6496    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6497   endif
6498   if s:didstarstar || !mapcheck("<s-up>","n")
6499    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6500   endif
6501   if !hasmapto('<Plug>NetrwTreeSqueeze')
6502    nmap <buffer> <silent> <nowait> <s-cr>			<Plug>NetrwTreeSqueeze
6503   endif
6504   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze		:call <SID>TreeSqueezeDir(1)<cr>
6505   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6506   if g:netrw_mousemaps == 1
6507    nmap <buffer>			<leftmouse>   		<Plug>NetrwLeftmouse
6508    nmap <buffer>			<c-leftmouse>		<Plug>NetrwCLeftmouse
6509    nmap <buffer>			<middlemouse>		<Plug>NetrwMiddlemouse
6510    nmap <buffer>			<s-leftmouse>		<Plug>NetrwSLeftmouse
6511    nmap <buffer>			<s-leftdrag>		<Plug>NetrwSLeftdrag
6512    nmap <buffer>			<2-leftmouse>		<Plug>Netrw2Leftmouse
6513    imap <buffer>			<leftmouse>		<Plug>ILeftmouse
6514    imap <buffer>			<middlemouse>		<Plug>IMiddlemouse
6515    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
6516    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(1)<cr>
6517    nno  <buffer> <silent>		<Plug>NetrwMiddlemouse	<leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
6518    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(1)<cr>
6519    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(1)<cr>
6520    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6521    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6522    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6523   endif
6524   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6525   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6526   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6527   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("")<cr>'
6528   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6529   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6530   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6531   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6532
6533   " support user-specified maps
6534   call netrw#UserMaps(1)
6535
6536  else
6537   " remote normal-mode maps {{{3
6538"   call Decho("make remote maps",'~'.expand("<slnum>"))
6539   call s:RemotePathAnalysis(b:netrw_curdir)
6540   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(0)<cr>
6541   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6542   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(0)<cr>
6543   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(0,0)<cr>
6544   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(0,1)<cr>
6545   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6546   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6547   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6548   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6549   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6550   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6551" ---------------------------------------------------------------------
6552   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6553   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6554   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
6555   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6556   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6557   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(0)<cr>
6558   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6559   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6560   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6561   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6562   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6563   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6564   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6565   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6566   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6567   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6568   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6569   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6570   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6571   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6572   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6573   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6574   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6575   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6576   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6577   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6578   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6579   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6580   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(0)<cr>
6581   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(0)<cr>
6582   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6583   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6584   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6585   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6586   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6587   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6588   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>
6589   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(0)<cr>
6590   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(0)<cr>
6591   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6592   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(1)<cr>
6593   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6594   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6595   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6596   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(2)<cr>
6597   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6598   if !hasmapto('<Plug>NetrwHideEdit')
6599    nmap <buffer> <c-h> <Plug>NetrwHideEdit
6600   endif
6601   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
6602   if !hasmapto('<Plug>NetrwRefresh')
6603    nmap <buffer> <c-l> <Plug>NetrwRefresh
6604   endif
6605   if !hasmapto('<Plug>NetrwTreeSqueeze')
6606    nmap <buffer> <silent> <nowait> <s-cr>	<Plug>NetrwTreeSqueeze
6607   endif
6608   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze	:call <SID>TreeSqueezeDir(0)<cr>
6609
6610   let mapsafepath     = escape(s:path, s:netrw_map_escape)
6611   let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6612
6613   nnoremap <buffer> <silent> <Plug>NetrwRefresh	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6614   if g:netrw_mousemaps == 1
6615    nmap <buffer> <leftmouse>		<Plug>NetrwLeftmouse
6616    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
6617    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6618    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(0)<cr>
6619    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6620    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(0)<cr>
6621    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6622    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(0)<cr>
6623    nmap <middlemouse>			<Plug>NetrwMiddlemouse
6624    nno  <buffer> <silent>		<middlemouse>		<Plug>NetrwMiddlemouse <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
6625    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6626    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6627    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6628    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6629    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6630    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6631    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6632   endif
6633   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6634   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6635   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6636   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6637   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6638   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6639   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6640   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6641
6642   " support user-specified maps
6643   call netrw#UserMaps(0)
6644  endif " }}}3
6645
6646"  call Dret("s:NetrwMaps")
6647endfun
6648
6649" ---------------------------------------------------------------------
6650" s:NetrwCommands: set up commands 				{{{2
6651"  If -buffer, the command is only available from within netrw buffers
6652"  Otherwise, the command is available from any window, so long as netrw
6653"  has been used at least once in the session.
6654fun! s:NetrwCommands(islocal)
6655"  call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6656
6657  com! -nargs=* -complete=file -bang	NetrwMB	call s:NetrwBookmark(<bang>0,<f-args>)
6658  com! -nargs=*			    	NetrwC	call s:NetrwSetChgwin(<q-args>)
6659  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
6660  if a:islocal
6661   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(1,<f-args>)
6662  else
6663   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(0,<f-args>)
6664  endif
6665  com! -buffer -nargs=? -complete=file	MT	call s:NetrwMarkTarget(<q-args>)
6666
6667"  call Dret("s:NetrwCommands")
6668endfun
6669
6670" ---------------------------------------------------------------------
6671" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6672"                   glob()ing only works with local files
6673fun! s:NetrwMarkFiles(islocal,...)
6674"  call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6675  let curdir = s:NetrwGetCurdir(a:islocal)
6676  let i      = 1
6677  while i <= a:0
6678   if a:islocal
6679    if v:version > 704 || (v:version == 704 && has("patch656"))
6680     let mffiles= glob(a:{i},0,1,1)
6681    else
6682     let mffiles= glob(a:{i},0,1)
6683    endif
6684   else
6685    let mffiles= [a:{i}]
6686   endif
6687"   call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6688   for mffile in mffiles
6689"    call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6690    call s:NetrwMarkFile(a:islocal,mffile)
6691   endfor
6692   let i= i + 1
6693  endwhile
6694"  call Dret("s:NetrwMarkFiles")
6695endfun
6696
6697" ---------------------------------------------------------------------
6698" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6699fun! s:NetrwMarkTarget(...)
6700"  call Dfunc("s:NetrwMarkTarget() a:0=".a:0)
6701  if a:0 == 0 || (a:0 == 1 && a:1 == "")
6702   let curdir = s:NetrwGetCurdir(1)
6703   let tgt    = b:netrw_curdir
6704  else
6705   let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6706   let tgt    = a:1
6707  endif
6708"  call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
6709  let s:netrwmftgt         = tgt
6710  let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6711  let curislocal           = b:netrw_curdir !~ '^\a\{3,}://'
6712  let svpos                = winsaveview()
6713"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6714  call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./'))
6715"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6716  call winrestview(svpos)
6717"  call Dret("s:NetrwMarkTarget")
6718endfun
6719
6720" ---------------------------------------------------------------------
6721" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6722"                  mark and unmark files.  If a markfile list exists,
6723"                  then the rename and delete functions will use it instead
6724"                  of whatever may happen to be under the cursor at that
6725"                  moment.  When the mouse and gui are available,
6726"                  shift-leftmouse may also be used to mark files.
6727"
6728"  Creates two lists
6729"    s:netrwmarkfilelist    -- holds complete paths to all marked files
6730"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
6731"
6732"  Creates a marked file match string
6733"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
6734"
6735"  Creates a buffer version of islocal
6736"    b:netrw_islocal
6737fun! s:NetrwMarkFile(islocal,fname)
6738"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6739"  call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6740
6741  " sanity check
6742  if empty(a:fname)
6743"   call Dret("s:NetrwMarkFile : emtpy fname")
6744   return
6745  endif
6746  let curdir = s:NetrwGetCurdir(a:islocal)
6747
6748  let ykeep   = @@
6749  let curbufnr= bufnr("%")
6750  if a:fname =~ '^\a'
6751   let leader= '\<'
6752  else
6753   let leader= ''
6754  endif
6755  if a:fname =~ '\a$'
6756   let trailer = '\>[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6757  else
6758   let trailer = '[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6759  endif
6760
6761  if exists("s:netrwmarkfilelist_".curbufnr)
6762   " markfile list pre-exists
6763"   call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6764"   call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6765"   call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6766   let b:netrw_islocal= a:islocal
6767
6768   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6769    " append filename to buffer's markfilelist
6770"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6771    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6772    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6773
6774   else
6775    " remove filename from buffer's markfilelist
6776"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6777    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6778    if s:netrwmarkfilelist_{curbufnr} == []
6779     " local markfilelist is empty; remove it entirely
6780"     call Decho("markfile list now empty",'~'.expand("<slnum>"))
6781     call s:NetrwUnmarkList(curbufnr,curdir)
6782    else
6783     " rebuild match list to display markings correctly
6784"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6785     let s:netrwmarkfilemtch_{curbufnr}= ""
6786     let first                         = 1
6787     for fname in s:netrwmarkfilelist_{curbufnr}
6788      if first
6789       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6790      else
6791       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6792      endif
6793      let first= 0
6794     endfor
6795"     call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6796    endif
6797   endif
6798
6799  else
6800   " initialize new markfilelist
6801"   call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6802
6803"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6804   let s:netrwmarkfilelist_{curbufnr}= []
6805   call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6806"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6807
6808   " build initial markfile matching pattern
6809   if a:fname =~ '/$'
6810    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6811   else
6812    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6813   endif
6814"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6815  endif
6816
6817  " handle global markfilelist
6818  if exists("s:netrwmarkfilelist")
6819   let dname= s:ComposePath(b:netrw_curdir,a:fname)
6820   if index(s:netrwmarkfilelist,dname) == -1
6821    " append new filename to global markfilelist
6822    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6823"    call Decho("append filename<".a:fname."> to global s:markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6824   else
6825    " remove new filename from global markfilelist
6826"    call Decho("remove new filename from global s:markfilelist",'~'.expand("<slnum>"))
6827"    call Decho("..filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6828    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6829"    call Decho("..ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6830    if s:netrwmarkfilelist == []
6831"     call Decho("s:netrwmarkfilelist is empty; unlet it",'~'.expand("<slnum>"))
6832     unlet s:netrwmarkfilelist
6833    endif
6834   endif
6835  else
6836   " initialize new global-directory markfilelist
6837   let s:netrwmarkfilelist= []
6838   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6839"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6840  endif
6841
6842  " set up 2match'ing to netrwmarkfilemtch_# list
6843  if has("syntax") && exists("g:syntax_on") && g:syntax_on
6844   if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6845" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6846    if exists("g:did_drchip_netrwlist_syntax")
6847     exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6848    endif
6849   else
6850" "   call Decho("2match none",'~'.expand("<slnum>"))
6851    2match none
6852   endif
6853  endif
6854  let @@= ykeep
6855"  call Decho("s:netrwmarkfilelist[".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : "")."] (avail in all buffers)",'~'.expand("<slnum>"))
6856"  call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">  (buf#".curbufnr."list)")
6857endfun
6858
6859" ---------------------------------------------------------------------
6860" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6861"                         mA: move the argument list to marked file list     (tomflist=1)
6862"                            Uses the global marked file list
6863fun! s:NetrwMarkFileArgList(islocal,tomflist)
6864"  call Dfunc("s:NetrwMarkFileArgList(islocal=".a:islocal.",tomflist=".a:tomflist.")")
6865
6866  let svpos    = winsaveview()
6867"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6868  let curdir   = s:NetrwGetCurdir(a:islocal)
6869  let curbufnr = bufnr("%")
6870
6871  if a:tomflist
6872   " mA: move argument list to marked file list
6873   while argc()
6874    let fname= argv(0)
6875"    call Decho("exe argdel ".fname,'~'.expand("<slnum>"))
6876    exe "argdel ".fnameescape(fname)
6877    call s:NetrwMarkFile(a:islocal,fname)
6878   endwhile
6879
6880  else
6881   " ma: move marked file list to argument list
6882   if exists("s:netrwmarkfilelist")
6883
6884    " for every filename in the marked list
6885    for fname in s:netrwmarkfilelist
6886"     call Decho("exe argadd ".fname,'~'.expand("<slnum>"))
6887     exe "argadd ".fnameescape(fname)
6888    endfor	" for every file in the marked list
6889
6890    " unmark list and refresh
6891    call s:NetrwUnmarkList(curbufnr,curdir)
6892    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6893"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6894    NetrwKeepj call winrestview(svpos)
6895   endif
6896  endif
6897
6898"  call Dret("s:NetrwMarkFileArgList")
6899endfun
6900
6901" ---------------------------------------------------------------------
6902" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6903"                          compress/decompress files using the programs
6904"                          in g:netrw_compress and g:netrw_uncompress,
6905"                          using g:netrw_compress_suffix to know which to
6906"                          do.  By default:
6907"                            g:netrw_compress        = "gzip"
6908"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6909fun! s:NetrwMarkFileCompress(islocal)
6910"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
6911  let svpos    = winsaveview()
6912"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6913  let curdir   = s:NetrwGetCurdir(a:islocal)
6914  let curbufnr = bufnr("%")
6915
6916  " sanity check
6917  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6918   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6919"   call Dret("s:NetrwMarkFileCompress")
6920   return
6921  endif
6922"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6923
6924  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6925
6926   " for every filename in the marked list
6927   for fname in s:netrwmarkfilelist_{curbufnr}
6928    let sfx= substitute(fname,'^.\{-}\(\.\a\+\)$','\1','')
6929"    call Decho("extracted sfx<".sfx.">",'~'.expand("<slnum>"))
6930    if exists("g:netrw_decompress['".sfx."']")
6931     " fname has a suffix indicating that its compressed; apply associated decompression routine
6932     let exe= g:netrw_decompress[sfx]
6933"     call Decho("fname<".fname."> is compressed so decompress with <".exe.">",'~'.expand("<slnum>"))
6934     let exe= netrw#WinPath(exe)
6935     if a:islocal
6936      if g:netrw_keepdir
6937       let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6938      endif
6939      call system(exe." ".fname)
6940      if v:shell_error
6941       NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6942      endif
6943     else
6944      let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6945      NetrwKeepj call s:RemoteSystem(exe." ".fname)
6946     endif
6947
6948    endif
6949    unlet sfx
6950
6951    if exists("exe")
6952     unlet exe
6953    elseif a:islocal
6954     " fname not a compressed file, so compress it
6955     call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
6956     if v:shell_error
6957      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_compress<".g:netrw_compress."> to something that works",104)
6958     endif
6959    else
6960     " fname not a compressed file, so compress it
6961     NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
6962    endif
6963   endfor	" for every file in the marked list
6964
6965   call s:NetrwUnmarkList(curbufnr,curdir)
6966   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6967"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6968   NetrwKeepj call winrestview(svpos)
6969  endif
6970"  call Dret("s:NetrwMarkFileCompress")
6971endfun
6972
6973" ---------------------------------------------------------------------
6974" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
6975"                      If no marked files, then set up directory as the
6976"                      target.  Currently does not support copying entire
6977"                      directories.  Uses the local-buffer marked file list.
6978"                      Returns 1=success  (used by NetrwMarkFileMove())
6979"                              0=failure
6980fun! s:NetrwMarkFileCopy(islocal,...)
6981"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
6982
6983  let curdir   = s:NetrwGetCurdir(a:islocal)
6984  let curbufnr = bufnr("%")
6985  if b:netrw_curdir !~ '/$'
6986   if !exists("b:netrw_curdir")
6987    let b:netrw_curdir= curdir
6988   endif
6989   let b:netrw_curdir= b:netrw_curdir."/"
6990  endif
6991
6992  " sanity check
6993  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6994   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6995"   call Dret("s:NetrwMarkFileCopy")
6996   return
6997  endif
6998"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6999
7000  if !exists("s:netrwmftgt")
7001   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
7002"   call Dret("s:NetrwMarkFileCopy 0")
7003   return 0
7004  endif
7005"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7006
7007  if a:islocal &&  s:netrwmftgt_islocal
7008   " Copy marked files, local directory to local directory
7009"   call Decho("copy from local to local",'~'.expand("<slnum>"))
7010   if !executable(g:netrw_localcopycmd)
7011    call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
7012"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
7013    return
7014   endif
7015
7016   " copy marked files while within the same directory (ie. allow renaming)
7017   if simplify(s:netrwmftgt) == simplify(b:netrw_curdir)
7018    if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
7019     " only one marked file
7020"     call Decho("case: only one marked file",'~'.expand("<slnum>"))
7021     let args    = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
7022     let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
7023    elseif a:0 == 1
7024"     call Decho("case: handling one input argument",'~'.expand("<slnum>"))
7025     " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
7026     let args    = s:ShellEscape(b:netrw_curdir.a:1)
7027     let oldname = a:1
7028    else
7029     " copy multiple marked files inside the same directory
7030"     call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
7031     let s:recursive= 1
7032     for oldname in s:netrwmarkfilelist_{bufnr("%")}
7033      let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
7034      if ret == 0
7035       break
7036      endif
7037     endfor
7038     unlet s:recursive
7039     call s:NetrwUnmarkList(curbufnr,curdir)
7040"     call Dret("s:NetrwMarkFileCopy ".ret)
7041     return ret
7042    endif
7043
7044    call inputsave()
7045    let newname= input("Copy ".oldname." to : ",oldname,"file")
7046    call inputrestore()
7047    if newname == ""
7048"     call Dret("s:NetrwMarkFileCopy 0")
7049     return 0
7050    endif
7051    let args= s:ShellEscape(oldname)
7052    let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
7053   else
7054    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
7055    let tgt = s:ShellEscape(s:netrwmftgt)
7056   endif
7057   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7058    let args= substitute(args,'/','\\','g')
7059    let tgt = substitute(tgt, '/','\\','g')
7060   endif
7061   if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
7062   if tgt  =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
7063   if args =~ '//'|let args= substitute(args,'//','/','g')|endif
7064   if tgt  =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
7065"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
7066"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
7067   if isdirectory(s:NetrwFile(args))
7068"    call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
7069    let copycmd= g:netrw_localcopydircmd
7070"    call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
7071    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7072     " window's xcopy doesn't copy a directory to a target properly.  Instead, it copies a directory's
7073     " contents to a target.  One must append the source directory name to the target to get xcopy to
7074     " do the right thing.
7075     let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
7076"     call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
7077    endif
7078   else
7079    let copycmd= g:netrw_localcopycmd
7080   endif
7081   if g:netrw_localcopycmd =~ '\s'
7082    let copycmd     = substitute(copycmd,'\s.*$','','')
7083    let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
7084    let copycmd     = netrw#WinPath(copycmd).copycmdargs
7085   else
7086    let copycmd = netrw#WinPath(copycmd)
7087   endif
7088"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
7089"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
7090"   call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
7091"   call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
7092   call system(copycmd.g:netrw_localcopycmdopt." '".args."' '".tgt."'")
7093   if v:shell_error != 0
7094    if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7095     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)
7096    else
7097     call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
7098    endif
7099"    call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
7100    return 0
7101   endif
7102
7103  elseif  a:islocal && !s:netrwmftgt_islocal
7104   " Copy marked files, local directory to remote directory
7105"   call Decho("copy from local to remote",'~'.expand("<slnum>"))
7106   NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
7107
7108  elseif !a:islocal &&  s:netrwmftgt_islocal
7109   " Copy marked files, remote directory to local directory
7110"   call Decho("copy from remote to local",'~'.expand("<slnum>"))
7111   NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
7112
7113  elseif !a:islocal && !s:netrwmftgt_islocal
7114   " Copy marked files, remote directory to remote directory
7115"   call Decho("copy from remote to remote",'~'.expand("<slnum>"))
7116   let curdir = getcwd()
7117   let tmpdir = s:GetTempfile("")
7118   if tmpdir !~ '/'
7119    let tmpdir= curdir."/".tmpdir
7120   endif
7121   if exists("*mkdir")
7122    call mkdir(tmpdir)
7123   else
7124    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(tmpdir,1))
7125    if v:shell_error != 0
7126     call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
7127"     call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
7128     return
7129    endif
7130   endif
7131   if isdirectory(s:NetrwFile(tmpdir))
7132    if s:NetrwLcd(tmpdir)
7133"     call Dret("s:NetrwMarkFileCopy : lcd failure")
7134     return
7135    endif
7136    NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
7137    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
7138    NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
7139    if getcwd() == tmpdir
7140     for fname in s:netrwmarkfilelist_{bufnr('%')}
7141      NetrwKeepj call s:NetrwDelete(fname)
7142     endfor
7143     if s:NetrwLcd(curdir)
7144"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7145      return
7146     endif
7147     if delete(tmpdir,"d")
7148      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
7149     endif
7150    else
7151     if s:NetrwLcd(curdir)
7152"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7153      return
7154     endif
7155    endif
7156   endif
7157  endif
7158
7159  " -------
7160  " cleanup
7161  " -------
7162"  call Decho("cleanup",'~'.expand("<slnum>"))
7163  " remove markings from local buffer
7164  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7165"  call Decho(" g:netrw_fastbrowse  =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
7166"  call Decho(" s:netrwmftgt        =".s:netrwmftgt,'~'.expand("<slnum>"))
7167"  call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
7168"  call Decho(" curdir              =".curdir,'~'.expand("<slnum>"))
7169"  call Decho(" a:islocal           =".a:islocal,'~'.expand("<slnum>"))
7170"  call Decho(" curbufnr            =".curbufnr,'~'.expand("<slnum>"))
7171  if exists("s:recursive")
7172"   call Decho(" s:recursive         =".s:recursive,'~'.expand("<slnum>"))
7173  else
7174"   call Decho(" s:recursive         =n/a",'~'.expand("<slnum>"))
7175  endif
7176  " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
7177  if g:netrw_fastbrowse <= 1
7178   NetrwKeepj call s:LocalBrowseRefresh()
7179  else
7180   " refresh local and targets for fast browsing
7181   if !exists("s:recursive")
7182    " remove markings from local buffer
7183"    call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
7184    NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
7185   endif
7186
7187   " refresh buffers
7188   if s:netrwmftgt_islocal
7189"    call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
7190    NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7191   endif
7192   if a:islocal && s:netrwmftgt != curdir
7193"    call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
7194    NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
7195   endif
7196  endif
7197
7198"  call Dret("s:NetrwMarkFileCopy 1")
7199  return 1
7200endfun
7201
7202" ---------------------------------------------------------------------
7203" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
7204"                      invoke vim's diff mode on the marked files.
7205"                      Either two or three files can be so handled.
7206"                      Uses the global marked file list.
7207fun! s:NetrwMarkFileDiff(islocal)
7208"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
7209  let curbufnr= bufnr("%")
7210
7211  " sanity check
7212  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7213   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7214"   call Dret("s:NetrwMarkFileDiff")
7215   return
7216  endif
7217  let curdir= s:NetrwGetCurdir(a:islocal)
7218"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7219
7220  if exists("s:netrwmarkfilelist_{".curbufnr."}")
7221   let cnt    = 0
7222   for fname in s:netrwmarkfilelist
7223    let cnt= cnt + 1
7224    if cnt == 1
7225"     call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
7226     exe "NetrwKeepj e ".fnameescape(fname)
7227     diffthis
7228    elseif cnt == 2 || cnt == 3
7229     vsplit
7230     wincmd l
7231"     call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
7232     exe "NetrwKeepj e ".fnameescape(fname)
7233     diffthis
7234    else
7235     break
7236    endif
7237   endfor
7238   call s:NetrwUnmarkList(curbufnr,curdir)
7239  endif
7240
7241"  call Dret("s:NetrwMarkFileDiff")
7242endfun
7243
7244" ---------------------------------------------------------------------
7245" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
7246"                       Uses global markfilelist
7247fun! s:NetrwMarkFileEdit(islocal)
7248"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
7249
7250  let curdir   = s:NetrwGetCurdir(a:islocal)
7251  let curbufnr = bufnr("%")
7252
7253  " sanity check
7254  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7255   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7256"   call Dret("s:NetrwMarkFileEdit")
7257   return
7258  endif
7259"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7260
7261  if exists("s:netrwmarkfilelist_{curbufnr}")
7262   call s:SetRexDir(a:islocal,curdir)
7263   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7264   " unmark markedfile list
7265"   call s:NetrwUnmarkList(curbufnr,curdir)
7266   call s:NetrwUnmarkAll()
7267"   call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
7268   exe "sil args ".flist
7269  endif
7270  echo "(use :bn, :bp to navigate files; :Rex to return)"
7271
7272"  call Dret("s:NetrwMarkFileEdit")
7273endfun
7274
7275" ---------------------------------------------------------------------
7276" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
7277fun! s:NetrwMarkFileQFEL(islocal,qfel)
7278"  call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
7279  call s:NetrwUnmarkAll()
7280  let curbufnr= bufnr("%")
7281
7282  if !empty(a:qfel)
7283   for entry in a:qfel
7284    let bufnmbr= entry["bufnr"]
7285"    call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
7286    if !exists("s:netrwmarkfilelist_{curbufnr}")
7287"     call Decho("case: no marked file list",'~'.expand("<slnum>"))
7288     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7289    elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
7290     " s:NetrwMarkFile will remove duplicate entries from the marked file list.
7291     " So, this test lets two or more hits on the same pattern to be ignored.
7292"     call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
7293     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7294    else
7295"     call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
7296    endif
7297   endfor
7298   echo "(use me to edit marked files)"
7299  else
7300   call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
7301  endif
7302
7303"  call Dret("s:NetrwMarkFileQFEL")
7304endfun
7305
7306" ---------------------------------------------------------------------
7307" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
7308"                     mx enbloc=0: Uses the local marked-file list, applies command to each file individually
7309"                     mX enbloc=1: Uses the global marked-file list, applies command to entire list
7310fun! s:NetrwMarkFileExe(islocal,enbloc)
7311"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")")
7312  let svpos    = winsaveview()
7313"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7314  let curdir   = s:NetrwGetCurdir(a:islocal)
7315  let curbufnr = bufnr("%")
7316
7317  if a:enbloc == 0
7318   " individually apply command to files, one at a time
7319    " sanity check
7320    if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7321     NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7322"     call Dret("s:NetrwMarkFileExe")
7323     return
7324    endif
7325"    call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7326
7327    if exists("s:netrwmarkfilelist_{curbufnr}")
7328     " get the command
7329     call inputsave()
7330     let cmd= input("Enter command: ","","file")
7331     call inputrestore()
7332"     call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7333     if cmd == ""
7334"      call Dret("s:NetrwMarkFileExe : early exit, empty command")
7335      return
7336     endif
7337
7338     " apply command to marked files, individually.  Substitute: filename -> %
7339     " If no %, then append a space and the filename to the command
7340     for fname in s:netrwmarkfilelist_{curbufnr}
7341      if a:islocal
7342       if g:netrw_keepdir
7343	let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
7344       endif
7345      else
7346       let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
7347      endif
7348      if cmd =~ '%'
7349       let xcmd= substitute(cmd,'%',fname,'g')
7350      else
7351       let xcmd= cmd.' '.fname
7352      endif
7353      if a:islocal
7354"       call Decho("local: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7355       let ret= system(xcmd)
7356      else
7357"       call Decho("remote: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7358       let ret= s:RemoteSystem(xcmd)
7359      endif
7360      if v:shell_error < 0
7361       NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7362       break
7363      else
7364       echo ret
7365      endif
7366     endfor
7367
7368   " unmark marked file list
7369   call s:NetrwUnmarkList(curbufnr,curdir)
7370
7371   " refresh the listing
7372   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7373"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7374   NetrwKeepj call winrestview(svpos)
7375  else
7376   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7377  endif
7378
7379 else " apply command to global list of files, en bloc
7380
7381  call inputsave()
7382  let cmd= input("Enter command: ","","file")
7383  call inputrestore()
7384"  call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7385  if cmd == ""
7386"   call Dret("s:NetrwMarkFileExe : early exit, empty command")
7387   return
7388  endif
7389  if cmd =~ '%'
7390   let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7391  else
7392   let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7393  endif
7394  if a:islocal
7395   call system(cmd)
7396   if v:shell_error < 0
7397    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7398   endif
7399  else
7400   let ret= s:RemoteSystem(cmd)
7401  endif
7402  call s:NetrwUnmarkAll()
7403
7404  " refresh the listing
7405  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7406"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7407  NetrwKeepj call winrestview(svpos)
7408
7409 endif
7410
7411"  call Dret("s:NetrwMarkFileExe")
7412endfun
7413
7414" ---------------------------------------------------------------------
7415" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7416"                  as the marked file(s) (toggles suffix presence)
7417"                  Uses the local marked file list.
7418fun! s:NetrwMarkHideSfx(islocal)
7419"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7420  let svpos    = winsaveview()
7421"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7422  let curbufnr = bufnr("%")
7423
7424  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7425  if exists("s:netrwmarkfilelist_{curbufnr}")
7426
7427   for fname in s:netrwmarkfilelist_{curbufnr}
7428"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7429     " construct suffix pattern
7430     if fname =~ '\.'
7431      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7432     else
7433      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7434     endif
7435     " determine if its in the hiding list or not
7436     let inhidelist= 0
7437     if g:netrw_list_hide != ""
7438      let itemnum = 0
7439      let hidelist= split(g:netrw_list_hide,',')
7440      for hidepat in hidelist
7441       if sfxpat == hidepat
7442        let inhidelist= 1
7443        break
7444       endif
7445       let itemnum= itemnum + 1
7446      endfor
7447     endif
7448"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7449     if inhidelist
7450      " remove sfxpat from list
7451      call remove(hidelist,itemnum)
7452      let g:netrw_list_hide= join(hidelist,",")
7453     elseif g:netrw_list_hide != ""
7454      " append sfxpat to non-empty list
7455      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7456     else
7457      " set hiding list to sfxpat
7458      let g:netrw_list_hide= sfxpat
7459     endif
7460    endfor
7461
7462   " refresh the listing
7463   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7464"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7465   NetrwKeepj call winrestview(svpos)
7466  else
7467   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7468  endif
7469
7470"  call Dret("s:NetrwMarkHideSfx")
7471endfun
7472
7473" ---------------------------------------------------------------------
7474" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7475"                     Uses the local marked-file list.
7476fun! s:NetrwMarkFileVimCmd(islocal)
7477"  call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")")
7478  let svpos    = winsaveview()
7479"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7480  let curdir   = s:NetrwGetCurdir(a:islocal)
7481  let curbufnr = bufnr("%")
7482
7483  " sanity check
7484  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7485   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7486"   call Dret("s:NetrwMarkFileVimCmd")
7487   return
7488  endif
7489"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7490
7491  if exists("s:netrwmarkfilelist_{curbufnr}")
7492   " get the command
7493   call inputsave()
7494   let cmd= input("Enter vim command: ","","file")
7495   call inputrestore()
7496"   call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7497   if cmd == ""
7498"    "   call Dret("s:NetrwMarkFileVimCmd : early exit, empty command")
7499    return
7500   endif
7501
7502   " apply command to marked files.  Substitute: filename -> %
7503   " If no %, then append a space and the filename to the command
7504   for fname in s:netrwmarkfilelist_{curbufnr}
7505"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7506    if a:islocal
7507     1split
7508     exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7509"     call Decho("local<".fname.">: exe ".cmd,'~'.expand("<slnum>"))
7510     exe cmd
7511     exe "sil! keepalt wq!"
7512    else
7513"     call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET",'~'.expand("<slnum>"))
7514     echo "sorry, \"mv\" not supported yet for remote files"
7515    endif
7516   endfor
7517
7518   " unmark marked file list
7519   call s:NetrwUnmarkList(curbufnr,curdir)
7520
7521   " refresh the listing
7522   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7523"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7524   NetrwKeepj call winrestview(svpos)
7525  else
7526   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7527  endif
7528
7529"  call Dret("s:NetrwMarkFileVimCmd")
7530endfun
7531
7532" ---------------------------------------------------------------------
7533" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7534"                  as the marked file(s) (toggles suffix presence)
7535"                  Uses the local marked file list.
7536fun! s:NetrwMarkHideSfx(islocal)
7537"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7538  let svpos    = winsaveview()
7539"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7540  let curbufnr = bufnr("%")
7541
7542  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7543  if exists("s:netrwmarkfilelist_{curbufnr}")
7544
7545   for fname in s:netrwmarkfilelist_{curbufnr}
7546"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7547     " construct suffix pattern
7548     if fname =~ '\.'
7549      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7550     else
7551      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7552     endif
7553     " determine if its in the hiding list or not
7554     let inhidelist= 0
7555     if g:netrw_list_hide != ""
7556      let itemnum = 0
7557      let hidelist= split(g:netrw_list_hide,',')
7558      for hidepat in hidelist
7559       if sfxpat == hidepat
7560        let inhidelist= 1
7561        break
7562       endif
7563       let itemnum= itemnum + 1
7564      endfor
7565     endif
7566"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7567     if inhidelist
7568      " remove sfxpat from list
7569      call remove(hidelist,itemnum)
7570      let g:netrw_list_hide= join(hidelist,",")
7571     elseif g:netrw_list_hide != ""
7572      " append sfxpat to non-empty list
7573      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7574     else
7575      " set hiding list to sfxpat
7576      let g:netrw_list_hide= sfxpat
7577     endif
7578    endfor
7579
7580   " refresh the listing
7581   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7582"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7583   NetrwKeepj call winrestview(svpos)
7584  else
7585   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7586  endif
7587
7588"  call Dret("s:NetrwMarkHideSfx")
7589endfun
7590
7591" ---------------------------------------------------------------------
7592" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7593"                     Uses the global markfilelist
7594fun! s:NetrwMarkFileGrep(islocal)
7595"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7596  let svpos    = winsaveview()
7597"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7598  let curbufnr = bufnr("%")
7599  let curdir   = s:NetrwGetCurdir(a:islocal)
7600
7601  if exists("s:netrwmarkfilelist")
7602"   call Decho("using s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7603   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7604"   call Decho("keeping copy of s:netrwmarkfilelist in function-local variable,'~'.expand("<slnum>"))"
7605   call s:NetrwUnmarkAll()
7606  else
7607"   call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7608   let netrwmarkfilelist= "*"
7609  endif
7610
7611  " ask user for pattern
7612"  call Decho("ask user for search pattern",'~'.expand("<slnum>"))
7613  call inputsave()
7614  let pat= input("Enter pattern: ","")
7615  call inputrestore()
7616  let patbang = ""
7617  if pat =~ '^!'
7618   let patbang = "!"
7619   let pat     = strpart(pat,2)
7620  endif
7621  if pat =~ '^\i'
7622   let pat    = escape(pat,'/')
7623   let pat    = '/'.pat.'/'
7624  else
7625   let nonisi = pat[0]
7626  endif
7627
7628  " use vimgrep for both local and remote
7629"  call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7630  try
7631   exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7632  catch /^Vim\%((\a\+)\)\=:E480/
7633   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7634"   call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7635   return
7636  endtry
7637  echo "(use :cn, :cp to navigate, :Rex to return)"
7638
7639  2match none
7640"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7641  NetrwKeepj call winrestview(svpos)
7642
7643  if exists("nonisi")
7644   " original, user-supplied pattern did not begin with a character from isident
7645"   call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7646   if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7647    call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7648   endif
7649  endif
7650
7651"  call Dret("s:NetrwMarkFileGrep")
7652endfun
7653
7654" ---------------------------------------------------------------------
7655" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7656"                      uses the global marked file list
7657"                      s:netrwmfloc= 0: target directory is remote
7658"                                  = 1: target directory is local
7659fun! s:NetrwMarkFileMove(islocal)
7660"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7661  let curdir   = s:NetrwGetCurdir(a:islocal)
7662  let curbufnr = bufnr("%")
7663
7664  " sanity check
7665  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7666   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7667"   call Dret("s:NetrwMarkFileMove")
7668   return
7669  endif
7670"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7671
7672  if !exists("s:netrwmftgt")
7673   NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7674"   call Dret("s:NetrwMarkFileCopy 0")
7675   return 0
7676  endif
7677"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7678
7679  if      a:islocal &&  s:netrwmftgt_islocal
7680   " move: local -> local
7681"   call Decho("move from local to local",'~'.expand("<slnum>"))
7682"   call Decho("local to local move",'~'.expand("<slnum>"))
7683   if !executable(g:netrw_localmovecmd)
7684    call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7685"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7686    return
7687   endif
7688   let tgt = s:ShellEscape(s:netrwmftgt)
7689"   call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7690   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7691    let tgt= substitute(tgt, '/','\\','g')
7692"    call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7693    if g:netrw_localmovecmd =~ '\s'
7694     let movecmd     = substitute(g:netrw_localmovecmd,'\s.*$','','')
7695     let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7696     let movecmd     = netrw#WinPath(movecmd).movecmdargs
7697"     call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7698    else
7699     let movecmd = netrw#WinPath(movecmd)
7700"     call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7701    endif
7702   else
7703    let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7704"    call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7705   endif
7706   for fname in s:netrwmarkfilelist_{bufnr("%")}
7707    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7708     let fname= substitute(fname,'/','\\','g')
7709    endif
7710"    call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7711    let ret= system(movecmd.g:netrw_localmovecmdopt." ".s:ShellEscape(fname)." ".tgt)
7712    if v:shell_error != 0
7713     if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7714      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)
7715     else
7716      call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7717     endif
7718     break
7719    endif
7720   endfor
7721
7722  elseif  a:islocal && !s:netrwmftgt_islocal
7723   " move: local -> remote
7724"   call Decho("move from local to remote",'~'.expand("<slnum>"))
7725"   call Decho("copy",'~'.expand("<slnum>"))
7726   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7727   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7728"   call Decho("remove",'~'.expand("<slnum>"))
7729   for fname in mflist
7730    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7731    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7732   endfor
7733   unlet mflist
7734
7735  elseif !a:islocal &&  s:netrwmftgt_islocal
7736   " move: remote -> local
7737"   call Decho("move from remote to local",'~'.expand("<slnum>"))
7738"   call Decho("copy",'~'.expand("<slnum>"))
7739   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7740   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7741"   call Decho("remove",'~'.expand("<slnum>"))
7742   for fname in mflist
7743    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7744    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7745   endfor
7746   unlet mflist
7747
7748  elseif !a:islocal && !s:netrwmftgt_islocal
7749   " move: remote -> remote
7750"   call Decho("move from remote to remote",'~'.expand("<slnum>"))
7751"   call Decho("copy",'~'.expand("<slnum>"))
7752   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7753   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7754"   call Decho("remove",'~'.expand("<slnum>"))
7755   for fname in mflist
7756    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7757    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7758   endfor
7759   unlet mflist
7760  endif
7761
7762  " -------
7763  " cleanup
7764  " -------
7765"  call Decho("cleanup",'~'.expand("<slnum>"))
7766
7767  " remove markings from local buffer
7768  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7769
7770  " refresh buffers
7771  if !s:netrwmftgt_islocal
7772"   call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7773   NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7774  endif
7775  if a:islocal
7776"   call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7777   NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7778  endif
7779  if g:netrw_fastbrowse <= 1
7780"   call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7781   NetrwKeepj call s:LocalBrowseRefresh()
7782  endif
7783
7784"  call Dret("s:NetrwMarkFileMove")
7785endfun
7786
7787" ---------------------------------------------------------------------
7788" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7789"                       using the hardcopy command.  Local marked-file list only.
7790fun! s:NetrwMarkFilePrint(islocal)
7791"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7792  let curbufnr= bufnr("%")
7793
7794  " sanity check
7795  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7796   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7797"   call Dret("s:NetrwMarkFilePrint")
7798   return
7799  endif
7800"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7801  let curdir= s:NetrwGetCurdir(a:islocal)
7802
7803  if exists("s:netrwmarkfilelist_{curbufnr}")
7804   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7805   call s:NetrwUnmarkList(curbufnr,curdir)
7806   for fname in netrwmarkfilelist
7807    if a:islocal
7808     if g:netrw_keepdir
7809      let fname= s:ComposePath(curdir,fname)
7810     endif
7811    else
7812     let fname= curdir.fname
7813    endif
7814    1split
7815    " the autocmds will handle both local and remote files
7816"    call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7817    exe "sil NetrwKeepj e ".fnameescape(fname)
7818"    call Decho("hardcopy",'~'.expand("<slnum>"))
7819    hardcopy
7820    q
7821   endfor
7822   2match none
7823  endif
7824"  call Dret("s:NetrwMarkFilePrint")
7825endfun
7826
7827" ---------------------------------------------------------------------
7828" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7829"                        files when given a regexp (for which a prompt is
7830"                        issued) (matches to name of files).
7831fun! s:NetrwMarkFileRegexp(islocal)
7832"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7833
7834  " get the regular expression
7835  call inputsave()
7836  let regexp= input("Enter regexp: ","","file")
7837  call inputrestore()
7838
7839  if a:islocal
7840   let curdir= s:NetrwGetCurdir(a:islocal)
7841"   call Decho("curdir<".fnameescape(curdir).">")
7842   " get the matching list of files using local glob()
7843"   call Decho("handle local regexp",'~'.expand("<slnum>"))
7844   let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7845   if v:version > 704 || (v:version == 704 && has("patch656"))
7846    let filelist= glob(s:ComposePath(dirname,regexp),0,1,1)
7847   else
7848    let files   = glob(s:ComposePath(dirname,regexp),0,0)
7849    let filelist= split(files,"\n")
7850   endif
7851"   call Decho("files<".string(filelist).">",'~'.expand("<slnum>"))
7852
7853  " mark the list of files
7854  for fname in filelist
7855   if fname =~ '^'.fnameescape(curdir)
7856"    call Decho("fname<".substitute(fname,'^'.fnameescape(curdir).'/','','').">",'~'.expand("<slnum>"))
7857    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^'.fnameescape(curdir).'/','',''))
7858   else
7859"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7860    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7861   endif
7862  endfor
7863
7864  else
7865"   call Decho("handle remote regexp",'~'.expand("<slnum>"))
7866
7867   " convert displayed listing into a filelist
7868   let eikeep = &ei
7869   let areg   = @a
7870   sil NetrwKeepj %y a
7871   setl ei=all ma
7872"   call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7873   1split
7874   NetrwKeepj call s:NetrwEnew()
7875   NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
7876   sil NetrwKeepj norm! "ap
7877   NetrwKeepj 2
7878   let bannercnt= search('^" =====','W')
7879   exe "sil NetrwKeepj 1,".bannercnt."d"
7880   setl bt=nofile
7881   if     g:netrw_liststyle == s:LONGLIST
7882    sil NetrwKeepj %s/\s\{2,}\S.*$//e
7883    call histdel("/",-1)
7884   elseif g:netrw_liststyle == s:WIDELIST
7885    sil NetrwKeepj %s/\s\{2,}/\r/ge
7886    call histdel("/",-1)
7887   elseif g:netrw_liststyle == s:TREELIST
7888    exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7889    sil! NetrwKeepj g/^ .*$/d
7890    call histdel("/",-1)
7891    call histdel("/",-1)
7892   endif
7893   " convert regexp into the more usual glob-style format
7894   let regexp= substitute(regexp,'\*','.*','g')
7895"   call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7896   exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7897   call histdel("/",-1)
7898   let filelist= getline(1,line("$"))
7899   q!
7900   for filename in filelist
7901    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7902   endfor
7903   unlet filelist
7904   let @a  = areg
7905   let &ei = eikeep
7906  endif
7907  echo "  (use me to edit marked files)"
7908
7909"  call Dret("s:NetrwMarkFileRegexp")
7910endfun
7911
7912" ---------------------------------------------------------------------
7913" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7914"                        Uses the local marked file list.
7915fun! s:NetrwMarkFileSource(islocal)
7916"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7917  let curbufnr= bufnr("%")
7918
7919  " sanity check
7920  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7921   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7922"   call Dret("s:NetrwMarkFileSource")
7923   return
7924  endif
7925"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7926  let curdir= s:NetrwGetCurdir(a:islocal)
7927
7928  if exists("s:netrwmarkfilelist_{curbufnr}")
7929   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7930   call s:NetrwUnmarkList(curbufnr,curdir)
7931   for fname in netrwmarkfilelist
7932    if a:islocal
7933     if g:netrw_keepdir
7934      let fname= s:ComposePath(curdir,fname)
7935     endif
7936    else
7937     let fname= curdir.fname
7938    endif
7939    " the autocmds will handle sourcing both local and remote files
7940"    call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7941    exe "so ".fnameescape(fname)
7942   endfor
7943   2match none
7944  endif
7945"  call Dret("s:NetrwMarkFileSource")
7946endfun
7947
7948" ---------------------------------------------------------------------
7949" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
7950"                     Uses the global markfilelist
7951fun! s:NetrwMarkFileTag(islocal)
7952"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
7953  let svpos    = winsaveview()
7954"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7955  let curdir   = s:NetrwGetCurdir(a:islocal)
7956  let curbufnr = bufnr("%")
7957
7958  " sanity check
7959  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7960   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7961"   call Dret("s:NetrwMarkFileTag")
7962   return
7963  endif
7964"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7965
7966  if exists("s:netrwmarkfilelist")
7967"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7968   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
7969   call s:NetrwUnmarkAll()
7970
7971   if a:islocal
7972
7973"    call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("<slnum>"))
7974    call system(g:netrw_ctags." ".netrwmarkfilelist)
7975    if v:shell_error
7976     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
7977    endif
7978
7979   else
7980    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
7981    call netrw#Obtain(a:islocal,"tags")
7982    let curdir= b:netrw_curdir
7983    1split
7984    NetrwKeepj e tags
7985    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
7986"    call Decho("curdir<".curdir."> path<".path.">",'~'.expand("<slnum>"))
7987    exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
7988    call histdel("/",-1)
7989    wq!
7990   endif
7991   2match none
7992   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7993"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7994   call winrestview(svpos)
7995  endif
7996
7997"  call Dret("s:NetrwMarkFileTag")
7998endfun
7999
8000" ---------------------------------------------------------------------
8001" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
8002"   Sets up two variables,
8003"     s:netrwmftgt         : holds the target directory
8004"     s:netrwmftgt_islocal : 0=target directory is remote
8005"                            1=target directory is local
8006fun! s:NetrwMarkFileTgt(islocal)
8007" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
8008  let svpos  = winsaveview()
8009"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8010  let curdir = s:NetrwGetCurdir(a:islocal)
8011  let hadtgt = exists("s:netrwmftgt")
8012  if !exists("w:netrw_bannercnt")
8013   let w:netrw_bannercnt= b:netrw_bannercnt
8014  endif
8015
8016  " set up target
8017  if line(".") < w:netrw_bannercnt
8018"   call Decho("set up target: line(.) < w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
8019   " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
8020   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
8021"    call Decho("cursor in banner region, and target already is <".b:netrw_curdir.">: removing target",'~'.expand("<slnum>"))
8022    unlet s:netrwmftgt s:netrwmftgt_islocal
8023    if g:netrw_fastbrowse <= 1
8024     call s:LocalBrowseRefresh()
8025    endif
8026    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8027"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8028    call winrestview(svpos)
8029"    call Dret("s:NetrwMarkFileTgt : removed target")
8030    return
8031   else
8032    let s:netrwmftgt= b:netrw_curdir
8033"    call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8034   endif
8035
8036  else
8037   " get word under cursor.
8038   "  * If directory, use it for the target.
8039   "  * If file, use b:netrw_curdir for the target
8040"   call Decho("get word under cursor",'~'.expand("<slnum>"))
8041   let curword= s:NetrwGetWord()
8042   let tgtdir = s:ComposePath(curdir,curword)
8043   if a:islocal && isdirectory(s:NetrwFile(tgtdir))
8044    let s:netrwmftgt = tgtdir
8045"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8046   elseif !a:islocal && tgtdir =~ '/$'
8047    let s:netrwmftgt = tgtdir
8048"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8049   else
8050    let s:netrwmftgt = curdir
8051"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8052   endif
8053  endif
8054  if a:islocal
8055   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
8056   let s:netrwmftgt= simplify(s:netrwmftgt)
8057"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
8058  endif
8059  if g:netrw_cygwin
8060   let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
8061   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
8062  endif
8063  let s:netrwmftgt_islocal= a:islocal
8064
8065  " need to do refresh so that the banner will be updated
8066  "  s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
8067  if g:netrw_fastbrowse <= 1
8068"   call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers",'~'.expand("<slnum>"))
8069   call s:LocalBrowseRefresh()
8070  endif
8071"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8072  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8073   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop))
8074  else
8075   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8076  endif
8077"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8078  call winrestview(svpos)
8079  if !hadtgt
8080   sil! NetrwKeepj norm! j
8081  endif
8082
8083"  call Decho("getmatches=".string(getmatches()),'~'.expand("<slnum>"))
8084"  call Decho("s:netrwmarkfilelist=".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : 'n/a'),'~'.expand("<slnum>"))
8085"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
8086endfun
8087
8088" ---------------------------------------------------------------------
8089" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
8090fun! s:NetrwGetCurdir(islocal)
8091"  call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
8092
8093  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8094   let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
8095"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
8096  elseif !exists("b:netrw_curdir")
8097   let b:netrw_curdir= getcwd()
8098"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
8099  endif
8100
8101"  call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>"))
8102  if b:netrw_curdir !~ '\<\a\{3,}://'
8103   let curdir= b:netrw_curdir
8104"   call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
8105   if g:netrw_keepdir == 0
8106    call s:NetrwLcd(curdir)
8107   endif
8108  endif
8109
8110"  call Dret("s:NetrwGetCurdir <".curdir.">")
8111  return b:netrw_curdir
8112endfun
8113
8114" ---------------------------------------------------------------------
8115" s:NetrwOpenFile: query user for a filename and open it {{{2
8116fun! s:NetrwOpenFile(islocal)
8117"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
8118  let ykeep= @@
8119  call inputsave()
8120  let fname= input("Enter filename: ")
8121  call inputrestore()
8122  if fname !~ '[/\\]'
8123   if exists("b:netrw_curdir")
8124    if exists("g:netrw_quiet")
8125     let netrw_quiet_keep = g:netrw_quiet
8126    endif
8127    let g:netrw_quiet = 1
8128    " save position for benefit of Rexplore
8129    let s:rexposn_{bufnr("%")}= winsaveview()
8130"    call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
8131    if b:netrw_curdir =~ '/$'
8132     exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
8133    else
8134     exe "e ".fnameescape(b:netrw_curdir."/".fname)
8135    endif
8136    if exists("netrw_quiet_keep")
8137     let g:netrw_quiet= netrw_quiet_keep
8138    else
8139     unlet g:netrw_quiet
8140    endif
8141   endif
8142  else
8143   exe "NetrwKeepj e ".fnameescape(fname)
8144  endif
8145  let @@= ykeep
8146"  call Dret("s:NetrwOpenFile")
8147endfun
8148
8149" ---------------------------------------------------------------------
8150" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
8151"               For the mapping to this function be made via
8152"               netrwPlugin, you'll need to have had
8153"               g:netrw_usetab set to non-zero.
8154fun! netrw#Shrink()
8155"  call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
8156  let curwin  = winnr()
8157  let wiwkeep = &wiw
8158  set wiw=1
8159
8160  if &ft == "netrw"
8161   if winwidth(0) > g:netrw_wiw
8162    let t:netrw_winwidth= winwidth(0)
8163    exe "vert resize ".g:netrw_wiw
8164    wincmd l
8165    if winnr() == curwin
8166     wincmd h
8167    endif
8168"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8169   else
8170    exe "vert resize ".t:netrw_winwidth
8171"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8172   endif
8173
8174  elseif exists("t:netrw_lexbufnr")
8175   exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
8176   if     winwidth(bufwinnr(t:netrw_lexbufnr)) >  g:netrw_wiw
8177    let t:netrw_winwidth= winwidth(0)
8178    exe "vert resize ".g:netrw_wiw
8179    wincmd l
8180    if winnr() == curwin
8181     wincmd h
8182    endif
8183"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8184   elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
8185    exe "vert resize ".t:netrw_winwidth
8186"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8187   else
8188    call netrw#Lexplore(0,0)
8189   endif
8190
8191  else
8192   call netrw#Lexplore(0,0)
8193  endif
8194  let wiw= wiwkeep
8195
8196"  call Dret("netrw#Shrink")
8197endfun
8198
8199" ---------------------------------------------------------------------
8200" s:NetSortSequence: allows user to edit the sorting sequence {{{2
8201fun! s:NetSortSequence(islocal)
8202"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
8203
8204  let ykeep= @@
8205  let svpos= winsaveview()
8206"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8207  call inputsave()
8208  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
8209  call inputrestore()
8210
8211  " refresh the listing
8212  let g:netrw_sort_sequence= newsortseq
8213  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8214"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8215  NetrwKeepj call winrestview(svpos)
8216  let @@= ykeep
8217
8218"  call Dret("NetSortSequence")
8219endfun
8220
8221" ---------------------------------------------------------------------
8222" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
8223"   User access provided by the <mF> mapping. (see :help netrw-mF)
8224"   Used by many MarkFile functions.
8225fun! s:NetrwUnmarkList(curbufnr,curdir)
8226"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
8227
8228  "  remove all files in local marked-file list from global list
8229  if exists("s:netrwmarkfilelist")
8230   for mfile in s:netrwmarkfilelist_{a:curbufnr}
8231    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
8232    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
8233    call remove(s:netrwmarkfilelist,idx)            " remove from global list
8234   endfor
8235   if s:netrwmarkfilelist == []
8236    unlet s:netrwmarkfilelist
8237   endif
8238
8239   " getting rid of the local marked-file lists is easy
8240   unlet s:netrwmarkfilelist_{a:curbufnr}
8241  endif
8242  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
8243   unlet s:netrwmarkfilemtch_{a:curbufnr}
8244  endif
8245  2match none
8246"  call Dret("s:NetrwUnmarkList")
8247endfun
8248
8249" ---------------------------------------------------------------------
8250" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
8251fun! s:NetrwUnmarkAll()
8252"  call Dfunc("s:NetrwUnmarkAll()")
8253  if exists("s:netrwmarkfilelist")
8254   unlet s:netrwmarkfilelist
8255  endif
8256  sil call s:NetrwUnmarkAll2()
8257  2match none
8258"  call Dret("s:NetrwUnmarkAll")
8259endfun
8260
8261" ---------------------------------------------------------------------
8262" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
8263fun! s:NetrwUnmarkAll2()
8264"  call Dfunc("s:NetrwUnmarkAll2()")
8265  redir => netrwmarkfilelist_let
8266  let
8267  redir END
8268  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
8269  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
8270  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
8271  for flist in netrwmarkfilelist_list
8272   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
8273   unlet s:netrwmarkfilelist_{curbufnr}
8274   unlet s:netrwmarkfilemtch_{curbufnr}
8275  endfor
8276"  call Dret("s:NetrwUnmarkAll2")
8277endfun
8278
8279" ---------------------------------------------------------------------
8280" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
8281"
8282" Marked files are in two types of lists:
8283"    s:netrwmarkfilelist    -- holds complete paths to all marked files
8284"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
8285"
8286" Marked files suitable for use with 2match are in:
8287"    s:netrwmarkfilemtch_#   -- used with 2match to display marked files
8288fun! s:NetrwUnMarkFile(islocal)
8289"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
8290  let svpos    = winsaveview()
8291"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8292  let curbufnr = bufnr("%")
8293
8294  " unmark marked file list
8295  " (although I expect s:NetrwUpload() to do it, I'm just making sure)
8296  if exists("s:netrwmarkfilelist")
8297"   "   call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
8298   unlet s:netrwmarkfilelist
8299  endif
8300
8301  let ibuf= 1
8302  while ibuf < bufnr("$")
8303   if exists("s:netrwmarkfilelist_".ibuf)
8304    unlet s:netrwmarkfilelist_{ibuf}
8305    unlet s:netrwmarkfilemtch_{ibuf}
8306   endif
8307   let ibuf = ibuf + 1
8308  endwhile
8309  2match none
8310
8311"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8312"call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8313call winrestview(svpos)
8314"  call Dret("s:NetrwUnMarkFile")
8315endfun
8316
8317" ---------------------------------------------------------------------
8318" s:NetrwMenu: generates the menu for gvim and netrw {{{2
8319fun! s:NetrwMenu(domenu)
8320
8321  if !exists("g:NetrwMenuPriority")
8322   let g:NetrwMenuPriority= 80
8323  endif
8324
8325  if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8326"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
8327
8328   if !exists("s:netrw_menu_enabled") && a:domenu
8329"    call Decho("initialize menu",'~'.expand("<slnum>"))
8330    let s:netrw_menu_enabled= 1
8331    exe 'sil! menu '.g:NetrwMenuPriority.'.1      '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
8332    exe 'sil! menu '.g:NetrwMenuPriority.'.5      '.g:NetrwTopLvlMenu.'-Sep1-	:'
8333    exe 'sil! menu '.g:NetrwMenuPriority.'.6      '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
8334    exe 'sil! menu '.g:NetrwMenuPriority.'.7      '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
8335    if g:netrw_dirhistmax > 0
8336     exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
8337     exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
8338     exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
8339     exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
8340    else
8341     exe 'sil! menu '.g:NetrwMenuPriority.'.8     '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History	:echo "(disabled)"'."\<cr>"
8342    endif
8343    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1    '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o	o'
8344    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2    '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v	v'
8345    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3    '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t	t'
8346    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4    '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p	p'
8347    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
8348    exe 'sil! menu '.g:NetrwMenuPriority.'.9.6    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
8349    exe 'sil! menu '.g:NetrwMenuPriority.'.9.7    '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
8350    exe 'sil! menu '.g:NetrwMenuPriority.'.9.8    '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
8351    exe 'sil! menu '.g:NetrwMenuPriority.'.9.9    '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
8352    exe 'sil! menu '.g:NetrwMenuPriority.'.10     '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
8353    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
8354    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
8355    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
8356    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
8357    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
8358    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t	t'
8359    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
8360    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1   '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
8361    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
8362    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
8363    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
8364    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
8365    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
8366    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
8367    exe 'sil! menu '.g:NetrwMenuPriority.'.13     '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
8368    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
8369    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
8370    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3   '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
8371    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4   '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
8372    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5   '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
8373    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6   '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
8374    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7   '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
8375    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8   '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
8376    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9   '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
8377    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10  '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
8378    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11  '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
8379    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12  '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
8380    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13  '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
8381    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14  '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
8382    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15  '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
8383    exe 'sil! menu '.g:NetrwMenuPriority.'.15     '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
8384    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i	:let w:netrw_liststyle=0<cr><c-L>'
8385    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i	:let w:netrw_liststyle=1<cr><c-L>'
8386    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i	:let w:netrw_liststyle=2<cr><c-L>'
8387    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i	:let w:netrw_liststyle=3<cr><c-L>'
8388    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>'
8389    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>'
8390    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>'
8391    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3   '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
8392    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>'
8393    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>'
8394    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>'
8395    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>'
8396    exe 'sil! menu '.g:NetrwMenuPriority.'.17     '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
8397    exe 'sil! menu '.g:NetrwMenuPriority.'.18     '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
8398    let s:netrw_menucnt= 28
8399    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
8400    call s:NetrwTgtMenu()      " let bookmarks and history be easy targets
8401
8402   elseif !a:domenu
8403    let s:netrwcnt = 0
8404    let curwin     = winnr()
8405    windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8406    exe curwin."wincmd w"
8407
8408    if s:netrwcnt <= 1
8409"     call Decho("clear menus",'~'.expand("<slnum>"))
8410     exe 'sil! unmenu '.g:NetrwTopLvlMenu
8411"     call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8412     sil! unlet s:netrw_menu_enabled
8413    endif
8414   endif
8415"   call Dret("NetrwMenu")
8416   return
8417  endif
8418
8419endfun
8420
8421" ---------------------------------------------------------------------
8422" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8423"                Used by the O maps (as <SID>NetrwObtain())
8424fun! s:NetrwObtain(islocal)
8425"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8426
8427  let ykeep= @@
8428  if exists("s:netrwmarkfilelist_{bufnr('%')}")
8429   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8430   call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8431   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
8432  else
8433   call netrw#Obtain(a:islocal,s:NetrwGetWord())
8434  endif
8435  let @@= ykeep
8436
8437"  call Dret("NetrwObtain")
8438endfun
8439
8440" ---------------------------------------------------------------------
8441" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
8442"   If there's only one window, then the window will first be split.
8443"   Returns:
8444"     choice = 0 : didn't have to choose
8445"     choice = 1 : saved modified file in window first
8446"     choice = 2 : didn't save modified file, opened window
8447"     choice = 3 : cancel open
8448fun! s:NetrwPrevWinOpen(islocal)
8449"  call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")")
8450
8451  let ykeep= @@
8452  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8453  let curdir = b:netrw_curdir
8454
8455  " get last window number and the word currently under the cursor
8456  let origwin   = winnr()
8457  let lastwinnr = winnr("$")
8458  let curword   = s:NetrwGetWord()
8459  let choice    = 0
8460  let s:treedir = s:NetrwTreeDir(a:islocal)
8461  let curdir    = s:treedir
8462"  call Decho("winnr($)#".lastwinnr." curword<".curword.">",'~'.expand("<slnum>"))
8463
8464  let didsplit = 0
8465  if lastwinnr == 1
8466   " if only one window, open a new one first
8467"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("<slnum>"))
8468   " g:netrw_preview=0: preview window shown in a horizontally split window
8469   " g:netrw_preview=1: preview window shown in a vertically   split window
8470   if g:netrw_preview
8471    " vertically split preview window
8472    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8473"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("<slnum>"))
8474    exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8475   else
8476    " horizontally split preview window
8477    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8478"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8479    exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8480   endif
8481   let didsplit = 1
8482"   call Decho("did split",'~'.expand("<slnum>"))
8483
8484  else
8485   NetrwKeepj call s:SaveBufVars()
8486   let eikeep= &ei
8487   setl ei=all
8488   wincmd p
8489"   call Decho("wincmd p  (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
8490
8491   " prevwinnr: the window number of the "prev" window
8492   " prevbufnr: the buffer number of the buffer in the "prev" window
8493   " bnrcnt   : the qty of windows open on the "prev" buffer
8494   let prevwinnr   = winnr()
8495   let prevbufnr   = bufnr("%")
8496   let prevbufname = bufname("%")
8497   let prevmod     = &mod
8498   let bnrcnt      = 0
8499   NetrwKeepj call s:RestoreBufVars()
8500"   call Decho("after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr,'~'.expand("<slnum>"))
8501
8502   " if the previous window's buffer has been changed (ie. its modified flag is set),
8503   " and it doesn't appear in any other extant window, then ask the
8504   " user if s/he wants to abandon modifications therein.
8505   if prevmod
8506"    call Decho("detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr(),'~'.expand("<slnum>"))
8507    windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8508"    call Decho("prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr,'~'.expand("<slnum>"))
8509    exe prevwinnr."wincmd w"
8510
8511    if bnrcnt == 1 && &hidden == 0
8512     " only one copy of the modified buffer in a window, and
8513     " hidden not set, so overwriting will lose the modified file.  Ask first...
8514     let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8515"     call Decho("prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("<slnum>"))
8516     let &ei= eikeep
8517
8518     if choice == 1
8519      " Yes -- write file & then browse
8520      let v:errmsg= ""
8521      sil w
8522      if v:errmsg != ""
8523       call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8524       exe origwin."wincmd w"
8525       let &ei = eikeep
8526       let @@  = ykeep
8527"       call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">")
8528       return choice
8529      endif
8530
8531     elseif choice == 2
8532      " No -- don't worry about changed file, just browse anyway
8533"      call Decho("don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")",'~'.expand("<slnum>"))
8534      echomsg "**note** changes to ".prevbufname." abandoned"
8535
8536     else
8537      " Cancel -- don't do this
8538"      call Decho("cancel, don't browse, switch to win#".origwin,'~'.expand("<slnum>"))
8539      exe origwin."wincmd w"
8540      let &ei= eikeep
8541      let @@ = ykeep
8542"      call Dret("s:NetrwPrevWinOpen ".choice." : cancelled")
8543      return choice
8544     endif
8545    endif
8546   endif
8547   let &ei= eikeep
8548  endif
8549
8550  " restore b:netrw_curdir (window split/enew may have lost it)
8551  let b:netrw_curdir= curdir
8552  if a:islocal < 2
8553   if a:islocal
8554    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
8555   else
8556    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
8557   endif
8558  endif
8559  let @@= ykeep
8560"  call Dret("s:NetrwPrevWinOpen ".choice)
8561  return choice
8562endfun
8563
8564" ---------------------------------------------------------------------
8565" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8566"                Always assumed to be local -> remote
8567"                call s:NetrwUpload(filename, target)
8568"                call s:NetrwUpload(filename, target, fromdirectory)
8569fun! s:NetrwUpload(fname,tgt,...)
8570"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
8571
8572  if a:tgt =~ '^\a\{3,}://'
8573   let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
8574  else
8575   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
8576  endif
8577"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
8578
8579  if a:0 > 0
8580   let fromdir= a:1
8581  else
8582   let fromdir= getcwd()
8583  endif
8584"  call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
8585
8586  if type(a:fname) == 1
8587   " handle uploading a single file using NetWrite
8588"   call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8589   1split
8590"   call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8591   exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8592"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8593   if a:tgt =~ '/$'
8594    let wfname= substitute(a:fname,'^.*/','','')
8595"    call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8596    exe "w! ".fnameescape(a:tgt.wfname)
8597   else
8598"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8599    exe "w ".fnameescape(a:tgt)
8600"    call Decho("done writing local->remote",'~'.expand("<slnum>"))
8601   endif
8602   q!
8603
8604  elseif type(a:fname) == 3
8605   " handle uploading a list of files via scp
8606"   call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8607   let curdir= getcwd()
8608   if a:tgt =~ '^scp:'
8609    if s:NetrwLcd(fromdir)
8610"     call Dret("s:NetrwUpload : lcd failure")
8611     return
8612    endif
8613    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8614    let args    = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8615    if exists("g:netrw_port") && g:netrw_port != ""
8616     let useport= " ".g:netrw_scpport." ".g:netrw_port
8617    else
8618     let useport= ""
8619    endif
8620    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8621    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8622    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8623    if s:NetrwLcd(curdir)
8624"     call Dret("s:NetrwUpload : lcd failure")
8625     return
8626    endif
8627
8628   elseif a:tgt =~ '^ftp:'
8629    call s:NetrwMethod(a:tgt)
8630
8631    if b:netrw_method == 2
8632     " handle uploading a list of files via ftp+.netrc
8633     let netrw_fname = b:netrw_fname
8634     sil NetrwKeepj new
8635"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8636
8637     NetrwKeepj put =g:netrw_ftpmode
8638"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8639
8640     if exists("g:netrw_ftpextracmd")
8641      NetrwKeepj put =g:netrw_ftpextracmd
8642"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8643     endif
8644
8645     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8646"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8647
8648     if tgtdir == ""
8649      let tgtdir= '/'
8650     endif
8651     NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8652"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8653
8654     for fname in a:fname
8655      NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8656"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8657     endfor
8658
8659     if exists("g:netrw_port") && g:netrw_port != ""
8660      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8661     else
8662"      call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8663      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8664     endif
8665     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8666     sil NetrwKeepj g/Local directory now/d
8667     call histdel("/",-1)
8668     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8669      call netrw#ErrorMsg(s:ERROR,getline(1),14)
8670     else
8671      bw!|q
8672     endif
8673
8674    elseif b:netrw_method == 3
8675     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8676     let netrw_fname= b:netrw_fname
8677     NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8678     let tmpbufnr= bufnr("%")
8679     setl ff=unix
8680
8681     if exists("g:netrw_port") && g:netrw_port != ""
8682      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8683"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8684     else
8685      NetrwKeepj put ='open '.g:netrw_machine
8686"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8687     endif
8688
8689     if exists("g:netrw_uid") && g:netrw_uid != ""
8690      if exists("g:netrw_ftp") && g:netrw_ftp == 1
8691       NetrwKeepj put =g:netrw_uid
8692"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8693       if exists("s:netrw_passwd")
8694        NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8695       endif
8696"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8697      elseif exists("s:netrw_passwd")
8698       NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8699"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8700      endif
8701     endif
8702
8703     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8704"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8705
8706     if exists("b:netrw_fname") && b:netrw_fname != ""
8707      NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8708"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8709     endif
8710
8711     if exists("g:netrw_ftpextracmd")
8712      NetrwKeepj put =g:netrw_ftpextracmd
8713"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8714     endif
8715
8716     for fname in a:fname
8717      NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8718"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8719     endfor
8720
8721     " perform ftp:
8722     " -i       : turns off interactive prompting from ftp
8723     " -n  unix : DON'T use <.netrc>, even though it exists
8724     " -n  win32: quit being obnoxious about password
8725     NetrwKeepj norm! 1G"_dd
8726     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8727     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8728     sil NetrwKeepj g/Local directory now/d
8729     call histdel("/",-1)
8730     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8731      let debugkeep= &debug
8732      setl debug=msg
8733      call netrw#ErrorMsg(s:ERROR,getline(1),15)
8734      let &debug = debugkeep
8735      let mod    = 1
8736     else
8737      bw!|q
8738     endif
8739    elseif !exists("b:netrw_method") || b:netrw_method < 0
8740"     call Dret("s:#NetrwUpload : unsupported method")
8741     return
8742    endif
8743   else
8744    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
8745   endif
8746  endif
8747
8748"  call Dret("s:NetrwUpload")
8749endfun
8750
8751" ---------------------------------------------------------------------
8752" s:NetrwPreview: supports netrw's "p" map {{{2
8753fun! s:NetrwPreview(path) range
8754"  call Dfunc("NetrwPreview(path<".a:path.">)")
8755"  call Decho("g:netrw_alto   =".(exists("g:netrw_alto")?    g:netrw_alto    : 'n/a'),'~'.expand("<slnum>"))
8756"  call Decho("g:netrw_preview=".(exists("g:netrw_preview")? g:netrw_preview : 'n/a'),'~'.expand("<slnum>"))
8757  let ykeep= @@
8758  NetrwKeepj call s:NetrwOptionsSave("s:")
8759  if a:path !~ '^\*\{1,2}/' && a:path !~ '^\a\{3,}://'
8760   NetrwKeepj call s:NetrwOptionsSafe(1)
8761  else
8762   NetrwKeepj call s:NetrwOptionsSafe(0)
8763  endif
8764  if has("quickfix")
8765"   call Decho("has quickfix",'~'.expand("<slnum>"))
8766   if !isdirectory(s:NetrwFile(a:path))
8767"    call Decho("good; not previewing a directory",'~'.expand("<slnum>"))
8768    if g:netrw_preview
8769     " vertical split
8770     let pvhkeep = &pvh
8771     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8772     let &pvh    = winwidth(0) - winsz
8773"     call Decho("g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily)  g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8774    else
8775     " horizontal split
8776     let pvhkeep = &pvh
8777     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8778     let &pvh    = winheight(0) - winsz
8779"     call Decho("!g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily)  g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8780    endif
8781    " g:netrw_preview   g:netrw_alto
8782    "    1 : vert        1: top       -- preview window is vertically   split off and on the left
8783    "    1 : vert        0: bot       -- preview window is vertically   split off and on the right
8784    "    0 :             1: top       -- preview window is horizontally split off and on the top
8785    "    0 :             0: bot       -- preview window is horizontally split off and on the bottom
8786    "
8787    " Note that the file being previewed is already known to not be a directory, hence we can avoid doing a LocalBrowse() check via
8788    " the BufEnter event set up in netrwPlugin.vim
8789"    call Decho("exe ".(g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path),'~'.expand("<slnum>"))
8790    let eikeep = &ei
8791    set ei=BufEnter
8792    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8793    let &ei= eikeep
8794"    call Decho("winnr($)=".winnr("$"),'~'.expand("<slnum>"))
8795    if exists("pvhkeep")
8796     let &pvh= pvhkeep
8797    endif
8798   elseif !exists("g:netrw_quiet")
8799    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
8800   endif
8801  elseif !exists("g:netrw_quiet")
8802   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
8803  endif
8804  NetrwKeepj call s:NetrwOptionsRestore("s:")
8805  let @@= ykeep
8806"  call Dret("NetrwPreview")
8807endfun
8808
8809" ---------------------------------------------------------------------
8810" s:NetrwRefresh: {{{2
8811fun! s:NetrwRefresh(islocal,dirname)
8812"  call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") g:netrw_hide=".g:netrw_hide." g:netrw_sort_direction=".g:netrw_sort_direction)
8813  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
8814  setl ma noro
8815"  call Decho("setl ma noro",'~'.expand("<slnum>"))
8816"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8817  let ykeep      = @@
8818  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8819   if !exists("w:netrw_treetop")
8820    if exists("b:netrw_curdir")
8821     let w:netrw_treetop= b:netrw_curdir
8822    else
8823     let w:netrw_treetop= getcwd()
8824    endif
8825   endif
8826   NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
8827  endif
8828
8829  " save the cursor position before refresh.
8830  let screenposn = winsaveview()
8831"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8832
8833"  call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8834"  call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
8835  sil! NetrwKeepj %d _
8836  if a:islocal
8837   NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
8838  else
8839   NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
8840  endif
8841
8842  " restore position
8843"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8844  NetrwKeepj call winrestview(screenposn)
8845
8846  " restore file marks
8847  if has("syntax") && exists("g:syntax_on") && g:syntax_on
8848   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8849" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8850    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8851   else
8852" "   call Decho("2match none  (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8853    2match none
8854   endif
8855 endif
8856
8857"  restore
8858  let @@= ykeep
8859"  call Dret("s:NetrwRefresh")
8860endfun
8861
8862" ---------------------------------------------------------------------
8863" s:NetrwRefreshDir: refreshes a directory by name {{{2
8864"                    Called by NetrwMarkFileCopy()
8865"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
8866fun! s:NetrwRefreshDir(islocal,dirname)
8867"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) g:netrw_fastbrowse=".g:netrw_fastbrowse)
8868  if g:netrw_fastbrowse == 0
8869   " slowest mode (keep buffers refreshed, local or remote)
8870"   call Decho("slowest mode: keep buffers refreshed, local or remote",'~'.expand("<slnum>"))
8871   let tgtwin= bufwinnr(a:dirname)
8872"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin,'~'.expand("<slnum>"))
8873
8874   if tgtwin > 0
8875    " tgtwin is being displayed, so refresh it
8876    let curwin= winnr()
8877"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")",'~'.expand("<slnum>"))
8878    exe tgtwin."wincmd w"
8879    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8880    exe curwin."wincmd w"
8881
8882   elseif bufnr(a:dirname) > 0
8883    let bn= bufnr(a:dirname)
8884"    call Decho("bd bufnr(".a:dirname.")=".bn,'~'.expand("<slnum>"))
8885    exe "sil keepj bd ".bn
8886   endif
8887
8888  elseif g:netrw_fastbrowse <= 1
8889"   call Decho("medium-speed mode: refresh local buffers only",'~'.expand("<slnum>"))
8890   NetrwKeepj call s:LocalBrowseRefresh()
8891  endif
8892"  call Dret("s:NetrwRefreshDir")
8893endfun
8894
8895" ---------------------------------------------------------------------
8896" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8897" window number to do its editing in.
8898" Supports   [count]C  where the count, if present, is used to specify
8899" a window to use for editing via the <cr> mapping.
8900fun! s:NetrwSetChgwin(...)
8901"  call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
8902  if a:0 > 0
8903"   call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8904   if a:1 == ""    " :NetrwC win#
8905    let g:netrw_chgwin= winnr()
8906   else              " :NetrwC
8907    let g:netrw_chgwin= a:1
8908   endif
8909  elseif v:count > 0 " [count]C
8910   let g:netrw_chgwin= v:count
8911  else               " C
8912   let g:netrw_chgwin= winnr()
8913  endif
8914  echo "editing window now set to window#".g:netrw_chgwin
8915"  call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
8916endfun
8917
8918" ---------------------------------------------------------------------
8919" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8920"          What this function does is to compute a priority for the patterns
8921"          in the g:netrw_sort_sequence.  It applies a substitute to any
8922"          "files" that satisfy each pattern, putting the priority / in
8923"          front.  An "*" pattern handles the default priority.
8924fun! s:NetrwSetSort()
8925"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
8926  let ykeep= @@
8927  if w:netrw_liststyle == s:LONGLIST
8928   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
8929  else
8930   let seqlist  = g:netrw_sort_sequence
8931  endif
8932  " sanity check -- insure that * appears somewhere
8933  if seqlist == ""
8934   let seqlist= '*'
8935  elseif seqlist !~ '\*'
8936   let seqlist= seqlist.',*'
8937  endif
8938  let priority = 1
8939  while seqlist != ""
8940   if seqlist =~ ','
8941    let seq     = substitute(seqlist,',.*$','','e')
8942    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
8943   else
8944    let seq     = seqlist
8945    let seqlist = ""
8946   endif
8947   if priority < 10
8948    let spriority= "00".priority.g:netrw_sepchr
8949   elseif priority < 100
8950    let spriority= "0".priority.g:netrw_sepchr
8951   else
8952    let spriority= priority.g:netrw_sepchr
8953   endif
8954"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
8955
8956   " sanity check
8957   if w:netrw_bannercnt > line("$")
8958    " apparently no files were left after a Hiding pattern was used
8959"    call Dret("SetSort : no files left after hiding")
8960    return
8961   endif
8962   if seq == '*'
8963    let starpriority= spriority
8964   else
8965    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
8966    call histdel("/",-1)
8967    " sometimes multiple sorting patterns will match the same file or directory.
8968    " The following substitute is intended to remove the excess matches.
8969    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
8970    NetrwKeepj call histdel("/",-1)
8971   endif
8972   let priority = priority + 1
8973  endwhile
8974  if exists("starpriority")
8975   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
8976   NetrwKeepj call histdel("/",-1)
8977  endif
8978
8979  " Following line associated with priority -- items that satisfy a priority
8980  " pattern get prefixed by ###/ which permits easy sorting by priority.
8981  " Sometimes files can satisfy multiple priority patterns -- only the latest
8982  " priority pattern needs to be retained.  So, at this point, these excess
8983  " priority prefixes need to be removed, but not directories that happen to
8984  " be just digits themselves.
8985  exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
8986  NetrwKeepj call histdel("/",-1)
8987  let @@= ykeep
8988
8989"  call Dret("SetSort")
8990endfun
8991
8992" ---------------------------------------------------------------------
8993" s:NetrwSetTgt: sets the target to the specified choice index {{{2
8994"    Implements [count]Tb  (bookhist<b>)
8995"               [count]Th  (bookhist<h>)
8996"               See :help netrw-qb for how to make the choice.
8997fun! s:NetrwSetTgt(islocal,bookhist,choice)
8998"  call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
8999
9000  if     a:bookhist == 'b'
9001   " supports choosing a bookmark as a target using a qb-generated list
9002   let choice= a:choice - 1
9003   if exists("g:netrw_bookmarklist[".choice."]")
9004    call netrw#MakeTgt(g:netrw_bookmarklist[choice])
9005   else
9006    echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
9007   endif
9008
9009  elseif a:bookhist == 'h'
9010   " supports choosing a history stack entry as a target using a qb-generated list
9011   let choice= (a:choice % g:netrw_dirhistmax) + 1
9012   if exists("g:netrw_dirhist_".choice)
9013    let histentry = g:netrw_dirhist_{choice}
9014    call netrw#MakeTgt(histentry)
9015   else
9016    echomsg "Sorry, history#".a:choice." not available!"
9017   endif
9018  endif
9019
9020  " refresh the display
9021  if !exists("b:netrw_curdir")
9022   let b:netrw_curdir= getcwd()
9023  endif
9024  call s:NetrwRefresh(a:islocal,b:netrw_curdir)
9025
9026"  call Dret("s:NetrwSetTgt")
9027endfun
9028
9029" =====================================================================
9030" s:NetrwSortStyle: change sorting style (name - time - size - exten) and refresh display {{{2
9031fun! s:NetrwSortStyle(islocal)
9032"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
9033  NetrwKeepj call s:NetrwSaveWordPosn()
9034  let svpos= winsaveview()
9035"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9036
9037  let g:netrw_sort_by= (g:netrw_sort_by =~# '^n')? 'time' : (g:netrw_sort_by =~# '^t')? 'size' : (g:netrw_sort_by =~# '^siz')? 'exten' : 'name'
9038  NetrwKeepj norm! 0
9039  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
9040"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9041  NetrwKeepj call winrestview(svpos)
9042
9043"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
9044endfun
9045
9046" ---------------------------------------------------------------------
9047" s:NetrwSplit: mode {{{2
9048"           =0 : net   and o
9049"           =1 : net   and t
9050"           =2 : net   and v
9051"           =3 : local and o
9052"           =4 : local and t
9053"           =5 : local and v
9054fun! s:NetrwSplit(mode)
9055"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
9056
9057  let ykeep= @@
9058  call s:SaveWinVars()
9059
9060  if a:mode == 0
9061   " remote and o
9062   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
9063   if winsz == 0|let winsz= ""|endif
9064"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
9065   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
9066   let s:didsplit= 1
9067   NetrwKeepj call s:RestoreWinVars()
9068   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
9069   unlet s:didsplit
9070
9071  elseif a:mode == 1
9072   " remote and t
9073   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
9074"   call Decho("tabnew",'~'.expand("<slnum>"))
9075   tabnew
9076   let s:didsplit= 1
9077   NetrwKeepj call s:RestoreWinVars()
9078   NetrwKeepj call s:NetrwBrowse(0,newdir)
9079   unlet s:didsplit
9080
9081  elseif a:mode == 2
9082   " remote and v
9083   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
9084   if winsz == 0|let winsz= ""|endif
9085"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
9086   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
9087   let s:didsplit= 1
9088   NetrwKeepj call s:RestoreWinVars()
9089   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
9090   unlet s:didsplit
9091
9092  elseif a:mode == 3
9093   " local and o
9094   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
9095   if winsz == 0|let winsz= ""|endif
9096"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
9097   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
9098   let s:didsplit= 1
9099   NetrwKeepj call s:RestoreWinVars()
9100   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
9101   unlet s:didsplit
9102
9103  elseif a:mode == 4
9104   " local and t
9105   let cursorword  = s:NetrwGetWord()
9106   let eikeep      = &ei
9107   let netrw_winnr = winnr()
9108   let netrw_line  = line(".")
9109   let netrw_col   = virtcol(".")
9110   NetrwKeepj norm! H0
9111   let netrw_hline = line(".")
9112   setl ei=all
9113   exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
9114   exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
9115   let &ei          = eikeep
9116   let netrw_curdir = s:NetrwTreeDir(0)
9117"   call Decho("tabnew",'~'.expand("<slnum>"))
9118   tabnew
9119   let b:netrw_curdir = netrw_curdir
9120   let s:didsplit     = 1
9121   NetrwKeepj call s:RestoreWinVars()
9122   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
9123   if &ft == "netrw"
9124    setl ei=all
9125    exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
9126    exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
9127    let &ei= eikeep
9128   endif
9129   unlet s:didsplit
9130
9131  elseif a:mode == 5
9132   " local and v
9133   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
9134   if winsz == 0|let winsz= ""|endif
9135"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
9136   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
9137   let s:didsplit= 1
9138   NetrwKeepj call s:RestoreWinVars()
9139   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
9140   unlet s:didsplit
9141
9142  else
9143   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
9144  endif
9145
9146  let @@= ykeep
9147"  call Dret("s:NetrwSplit")
9148endfun
9149
9150" ---------------------------------------------------------------------
9151" s:NetrwTgtMenu: {{{2
9152fun! s:NetrwTgtMenu()
9153  if !exists("s:netrw_menucnt")
9154   return
9155  endif
9156"  call Dfunc("s:NetrwTgtMenu()")
9157
9158  " the following test assures that gvim is running, has menus available, and has menus enabled.
9159  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
9160   if exists("g:NetrwTopLvlMenu")
9161"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
9162    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
9163   endif
9164   if !exists("s:netrw_initbookhist")
9165    call s:NetrwBookHistRead()
9166   endif
9167
9168   " try to cull duplicate entries
9169   let tgtdict={}
9170
9171   " target bookmarked places
9172   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
9173"    call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
9174    let cnt= 1
9175    for bmd in g:netrw_bookmarklist
9176     if has_key(tgtdict,bmd)
9177      let cnt= cnt + 1
9178      continue
9179     endif
9180     let tgtdict[bmd]= cnt
9181     let ebmd= escape(bmd,g:netrw_menu_escape)
9182     " show bookmarks for goto menu
9183"     call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
9184     exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd."	:call netrw#MakeTgt('".bmd."')\<cr>"
9185     let cnt= cnt + 1
9186    endfor
9187   endif
9188
9189   " target directory browsing history
9190   if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
9191"    call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
9192    let histcnt = 1
9193    while histcnt <= g:netrw_dirhistmax
9194     let priority = g:netrw_dirhistcnt + histcnt
9195     if exists("g:netrw_dirhist_{histcnt}")
9196      let histentry  = g:netrw_dirhist_{histcnt}
9197      if has_key(tgtdict,histentry)
9198       let histcnt = histcnt + 1
9199       continue
9200      endif
9201      let tgtdict[histentry] = histcnt
9202      let ehistentry         = escape(histentry,g:netrw_menu_escape)
9203"      call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
9204      exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry."	:call netrw#MakeTgt('".histentry."')\<cr>"
9205     endif
9206     let histcnt = histcnt + 1
9207    endwhile
9208   endif
9209  endif
9210"  call Dret("s:NetrwTgtMenu")
9211endfun
9212
9213" ---------------------------------------------------------------------
9214" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
9215" (full path directory with trailing slash returned)
9216fun! s:NetrwTreeDir(islocal)
9217"  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)
9218"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
9219"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9220"  call Decho("w:netrw_treetop  =".(exists("w:netrw_treetop")?   w:netrw_treetop   : 'n/a'),'~'.expand("<slnum>"))
9221
9222  if exists("s:treedir")
9223   " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
9224   let treedir= s:treedir
9225   unlet s:treedir
9226"   call Dret("s:NetrwTreeDir ".treedir)
9227   return treedir
9228  endif
9229
9230  if !exists("b:netrw_curdir") || b:netrw_curdir == ""
9231   let b:netrw_curdir= getcwd()
9232  endif
9233  let treedir = b:netrw_curdir
9234"  call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>"))
9235
9236  let s:treecurpos= winsaveview()
9237"  call Decho("saving posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9238
9239  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9240"   call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>"))
9241"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9242
9243   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
9244   let curline= substitute(getline('.'),"\t -->.*$",'','')
9245   if curline =~ '/$'
9246"    call Decho("extract tree subdirectory from current line",'~'.expand("<slnum>"))
9247    let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9248"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9249   elseif curline =~ '@$'
9250"    call Decho("handle symbolic link from current line",'~'.expand("<slnum>"))
9251    let treedir= resolve(substitute(substitute(getline('.'),'@.*$','','e'),'^|*\s*','','e'))
9252"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9253   else
9254"    call Decho("do not extract tree subdirectory from current line and set treedir to empty",'~'.expand("<slnum>"))
9255    let treedir= ""
9256   endif
9257
9258   " detect user attempting to close treeroot
9259"   call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>"))
9260"   call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9261"   call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~# '^'.s:treedepthstring)? '=~#' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>"))
9262   if curline !~ '^'.s:treedepthstring && getline('.') != '..'
9263"    call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>"))
9264    " now force a refresh
9265"    call Decho(".force refresh: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9266    sil! NetrwKeepj %d _
9267"    call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9268    return b:netrw_curdir
9269"   else " Decho
9270"    call Decho(".user not attempting to close treeroot",'~'.expand("<slnum>"))
9271   endif
9272
9273"   call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>"))
9274   let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
9275"   call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(potentialdir),'~'.expand("<slnum>"))
9276
9277   " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
9278"   if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
9279"    let newdir          = w:netrw_treetop.'/'.potentialdir
9280" "   call Decho("apply NetrwTreePath to newdir<".newdir.">",'~'.expand("<slnum>"))
9281"    let treedir         = s:NetrwTreePath(newdir)
9282"    let w:netrw_treetop = newdir
9283" "   call Decho("newdir <".newdir.">",'~'.expand("<slnum>"))
9284"   else
9285"    call Decho("apply NetrwTreePath to treetop<".w:netrw_treetop.">",'~'.expand("<slnum>"))
9286    let treedir = s:NetrwTreePath(w:netrw_treetop)
9287"   endif
9288  endif
9289
9290  " sanity maintenance: keep those //s away...
9291  let treedir= substitute(treedir,'//$','/','')
9292"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9293
9294"  call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9295  return treedir
9296endfun
9297
9298" ---------------------------------------------------------------------
9299" s:NetrwTreeDisplay: recursive tree display {{{2
9300fun! s:NetrwTreeDisplay(dir,depth)
9301"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
9302
9303  " insure that there are no folds
9304  setl nofen
9305
9306  " install ../ and shortdir
9307  if a:depth == ""
9308   call setline(line("$")+1,'../')
9309"   call Decho("setline#".line("$")." ../ (depth is zero)",'~'.expand("<slnum>"))
9310  endif
9311  if a:dir =~ '^\a\{3,}://'
9312   if a:dir == w:netrw_treetop
9313    let shortdir= a:dir
9314   else
9315    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
9316   endif
9317   call setline(line("$")+1,a:depth.shortdir)
9318  else
9319   let shortdir= substitute(a:dir,'^.*/','','e')
9320   call setline(line("$")+1,a:depth.shortdir.'/')
9321  endif
9322"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">",'~'.expand("<slnum>"))
9323
9324  " append a / to dir if its missing one
9325  let dir= a:dir
9326
9327  " display subtrees (if any)
9328  let depth= s:treedepthstring.a:depth
9329"  call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>"))
9330
9331  " implement g:netrw_hide for tree listings (uses g:netrw_list_hide)
9332  if     g:netrw_hide == 1
9333   " hide given patterns
9334   let listhide= split(g:netrw_list_hide,',')
9335"   call Decho("listhide=".string(listhide))
9336   for pat in listhide
9337    call filter(w:netrw_treedict[dir],'v:val !~ "'.pat.'"')
9338   endfor
9339
9340  elseif g:netrw_hide == 2
9341   " show given patterns (only)
9342   let listhide= split(g:netrw_list_hide,',')
9343"   call Decho("listhide=".string(listhide))
9344   let entries=[]
9345   for entry in w:netrw_treedict[dir]
9346    for pat in listhide
9347     if entry =~ pat
9348      call add(entries,entry)
9349      break
9350     endif
9351    endfor
9352   endfor
9353   let w:netrw_treedict[dir]= entries
9354  endif
9355  if depth != ""
9356   " always remove "." and ".." entries when there's depth
9357   call filter(w:netrw_treedict[dir],'v:val !~ "\\.\\.$"')
9358   call filter(w:netrw_treedict[dir],'v:val !~ "\\.$"')
9359  endif
9360
9361"  call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>"))
9362  for entry in w:netrw_treedict[dir]
9363   if dir =~ '/$'
9364    let direntry= substitute(dir.entry,'[@/]$','','e')
9365   else
9366    let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
9367   endif
9368"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9369   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9370"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9371    NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
9372   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9373"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9374    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9375   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9376"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9377    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9378   else
9379"    call Decho("<".entry."> is not a key in treedict (no subtree)",'~'.expand("<slnum>"))
9380    sil! NetrwKeepj call setline(line("$")+1,depth.entry)
9381   endif
9382  endfor
9383"  call Decho("displaying: ".string(getline(w:netrw_bannercnt,'$')))
9384
9385"  call Dret("NetrwTreeDisplay")
9386endfun
9387
9388" ---------------------------------------------------------------------
9389" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
9390fun! s:NetrwRefreshTreeDict(dir)
9391"  call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)")
9392  if !exists("w:netrw_treedict")
9393"   call Dret("s:NetrwRefreshTreeDict : w:netrw_treedict doesn't exist")
9394   return
9395  endif
9396
9397  for entry in w:netrw_treedict[a:dir]
9398   let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
9399"   call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9400
9401   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9402"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9403    NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
9404    let liststar                   = s:NetrwGlob(direntry,'*',1)
9405    let listdotstar                = s:NetrwGlob(direntry,'.*',1)
9406    let w:netrw_treedict[direntry] = liststar + listdotstar
9407"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9408
9409   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9410"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9411    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9412    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9413    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9414    let w:netrw_treedict[direntry]= liststar + listdotstar
9415"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9416
9417   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9418"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9419    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9420    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9421    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9422"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9423
9424   else
9425"    call Decho('not updating w:netrw_treedict['.string(direntry).'] with entry<'.string(entry).'> (no subtree)','~'.expand("<slnum>"))
9426   endif
9427  endfor
9428"  call Dret("s:NetrwRefreshTreeDict")
9429endfun
9430
9431" ---------------------------------------------------------------------
9432" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
9433"                     Called by s:PerformListing()
9434fun! s:NetrwTreeListing(dirname)
9435  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9436"   call Dfunc("NetrwTreeListing() bufname<".expand("%").">")
9437"   call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
9438"   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>"))
9439"   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>"))
9440
9441   " update the treetop
9442"   call Decho("update the treetop",'~'.expand("<slnum>"))
9443   if !exists("w:netrw_treetop")
9444    let w:netrw_treetop= a:dirname
9445"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>"))
9446   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
9447    let w:netrw_treetop= a:dirname
9448"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
9449   endif
9450
9451   if !exists("w:netrw_treedict")
9452    " insure that we have a treedict, albeit empty
9453"    call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
9454    let w:netrw_treedict= {}
9455   endif
9456
9457   " update the dictionary for the current directory
9458"   call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>"))
9459"   call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9460   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
9461   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
9462"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
9463   exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9464
9465   " if past banner, record word
9466   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
9467    let fname= expand("<cword>")
9468   else
9469    let fname= ""
9470   endif
9471"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9472"   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>"))
9473
9474   " display from treetop on down
9475   NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
9476"   call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
9477
9478   " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
9479   while getline(1) =~ '^\s*$' && byte2line(1) > 0
9480"    call Decho("deleting blank line",'~'.expand("<slnum>"))
9481    1d
9482   endwhile
9483
9484   exe "setl ".g:netrw_bufsettings
9485
9486"   call Dret("NetrwTreeListing : bufname<".expand("%").">")
9487   return
9488  endif
9489endfun
9490
9491" ---------------------------------------------------------------------
9492" s:NetrwTreePath: returns path to current file/directory in tree listing {{{2
9493"                  Normally, treetop is w:netrw_treetop, but a
9494"                  user of the function ( netrw#SetTreetop() )
9495"                  wipes that out prior to calling this function
9496fun! s:NetrwTreePath(treetop)
9497"  call Dfunc("s:NetrwTreePath(treetop<".a:treetop.">) line#".line(".")."<".getline(".").">")
9498  if line(".") < w:netrw_bannercnt + 2
9499   let treedir= a:treetop
9500   if treedir !~ '/$'
9501    let treedir= treedir.'/'
9502   endif
9503"   call Dret("s:NetrwTreePath ".treedir." : line#".line(".")." ≤ ".(w:netrw_bannercnt+2))
9504   return treedir
9505  endif
9506
9507  let svpos = winsaveview()
9508"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9509  let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
9510"  call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
9511  let depth = substitute(depth,'^'.s:treedepthstring,'','')
9512"  call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
9513  let curline= getline('.')
9514"  call Decho("curline<".curline.'>','~'.expand("<slnum>"))
9515  if curline =~ '/$'
9516"   call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9517   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9518"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9519  elseif curline =~ '@\s\+-->'
9520"   call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9521   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9522   let treedir= substitute(treedir,'@\s\+-->.*$','','e')
9523"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9524  else
9525"   call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9526   let treedir= ""
9527  endif
9528  " construct treedir by searching backwards at correct depth
9529"  call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9530"  call Decho("initial      treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
9531  while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
9532   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9533   let treedir= dirname.treedir
9534   let depth  = substitute(depth,'^'.s:treedepthstring,'','')
9535"   call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
9536  endwhile
9537"  call Decho("treedir#1<".treedir.">",'~'.expand("<slnum>"))
9538  if a:treetop =~ '/$'
9539   let treedir= a:treetop.treedir
9540  else
9541   let treedir= a:treetop.'/'.treedir
9542  endif
9543"  call Decho("treedir#2<".treedir.">",'~'.expand("<slnum>"))
9544  let treedir= substitute(treedir,'//$','/','')
9545"  call Decho("treedir#3<".treedir.">",'~'.expand("<slnum>"))
9546"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
9547  call winrestview(svpos)
9548"  call Dret("s:NetrwTreePath <".treedir.">")
9549  return treedir
9550endfun
9551
9552" ---------------------------------------------------------------------
9553" s:NetrwWideListing: {{{2
9554fun! s:NetrwWideListing()
9555
9556  if w:netrw_liststyle == s:WIDELIST
9557"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9558   " look for longest filename (cpf=characters per filename)
9559   " cpf: characters per filename
9560   " fpl: filenames per line
9561   " fpc: filenames per column
9562   setl ma noro
9563   let keepa= @a
9564"   call Decho("setl ma noro",'~'.expand("<slnum>"))
9565   let b:netrw_cpf= 0
9566   if line("$") >= w:netrw_bannercnt
9567    " determine the maximum filename size; use that to set cpf
9568    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
9569    NetrwKeepj call histdel("/",-1)
9570   else
9571    let @a= keepa
9572"    call Dret("NetrwWideListing")
9573    return
9574   endif
9575   " allow for two spaces to separate columns
9576   let b:netrw_cpf= b:netrw_cpf + 2
9577"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
9578
9579   " determine qty files per line (fpl)
9580   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9581   if w:netrw_fpl <= 0
9582    let w:netrw_fpl= 1
9583   endif
9584"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
9585
9586   " make wide display
9587   "   fpc: files per column of wide listing
9588   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9589   NetrwKeepj call histdel("/",-1)
9590   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9591   let newcolstart = w:netrw_bannercnt + fpc
9592   let newcolend   = newcolstart + fpc - 1
9593"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9594   if has("clipboard")
9595"    call Decho("(s:NetrwWideListing) save @* and @+",'~'.expand("<slnum>"))
9596    sil! let keepregstar = @*
9597    sil! let keepregplus = @+
9598   endif
9599   while line("$") >= newcolstart
9600    if newcolend > line("$") | let newcolend= line("$") | endif
9601    let newcolqty= newcolend - newcolstart
9602    exe newcolstart
9603    " COMBAK: both of the visual-mode using lines below are problematic vis-a-vis @*
9604    if newcolqty == 0
9605     exe "sil! NetrwKeepj norm! 0\<c-v>$h\"ax".w:netrw_bannercnt."G$\"ap"
9606    else
9607     exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$h"ax'.w:netrw_bannercnt.'G$"ap'
9608    endif
9609    exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
9610    exe 'sil! NetrwKeepj '.w:netrw_bannercnt
9611   endwhile
9612   if has("clipboard")
9613"    call Decho("(s:NetrwWideListing) restore @* and @+",'~'.expand("<slnum>"))
9614    if @* != keepregstar | sil! let @* = keepregstar | endif
9615    if @+ != keepregplus | sil! let @+ = keepregplus | endif
9616   endif
9617   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9618   NetrwKeepj call histdel("/",-1)
9619   exe 'nno <buffer> <silent> w	:call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9620   exe 'nno <buffer> <silent> b	:call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9621"   call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9622   exe "setl ".g:netrw_bufsettings
9623    let @a= keepa
9624"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9625"   call Dret("NetrwWideListing")
9626   return
9627  else
9628   if hasmapto("w","n")
9629    sil! nunmap <buffer> w
9630   endif
9631   if hasmapto("b","n")
9632    sil! nunmap <buffer> b
9633   endif
9634  endif
9635
9636endfun
9637
9638" ---------------------------------------------------------------------
9639" s:PerformListing: {{{2
9640fun! s:PerformListing(islocal)
9641"  call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9642"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9643"  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>"))
9644  sil! NetrwKeepj %d _
9645"  call DechoBuf(bufnr("%"))
9646
9647  " set up syntax highlighting {{{3
9648"  call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
9649  sil! setl ft=netrw
9650
9651  NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
9652  setl noro ma
9653"  call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
9654
9655"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
9656"   call Decho("Processing your browsing request...",'~'.expand("<slnum>"))
9657"  endif								" Decho
9658
9659"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9660  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
9661   " force a refresh for tree listings
9662"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9663   sil! NetrwKeepj %d _
9664  endif
9665
9666  " save current directory on directory history list
9667  NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
9668
9669  " Set up the banner {{{3
9670  if g:netrw_banner
9671"   call Decho("--set up banner",'~'.expand("<slnum>"))
9672   NetrwKeepj call setline(1,'" ============================================================================')
9673   if exists("g:netrw_pchk")
9674    " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9675    " failure detections.
9676    NetrwKeepj call setline(2,'" Netrw Directory Listing')
9677   else
9678    NetrwKeepj call setline(2,'" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')')
9679   endif
9680   if exists("g:netrw_pchk")
9681    let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9682   else
9683    let curdir= b:netrw_curdir
9684   endif
9685   if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9686    NetrwKeepj call setline(3,'"   '.substitute(curdir,'/','\\','g'))
9687   else
9688    NetrwKeepj call setline(3,'"   '.curdir)
9689   endif
9690   let w:netrw_bannercnt= 3
9691   NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
9692  else
9693"   call Decho("--no banner",'~'.expand("<slnum>"))
9694   NetrwKeepj 1
9695   let w:netrw_bannercnt= 1
9696  endif
9697"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9698"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9699
9700  " construct sortby string: [name|time|size|exten] [reversed]
9701  let sortby= g:netrw_sort_by
9702  if g:netrw_sort_direction =~# "^r"
9703   let sortby= sortby." reversed"
9704  endif
9705
9706  " Sorted by... {{{3
9707  if g:netrw_banner
9708"   call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9709   if g:netrw_sort_by =~# "^n"
9710"   call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9711    " sorted by name (also includes the sorting sequence in the banner)
9712    NetrwKeepj put ='\"   Sorted by      '.sortby
9713    NetrwKeepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
9714    let w:netrw_bannercnt= w:netrw_bannercnt + 2
9715   else
9716"   call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9717    " sorted by time, size, exten
9718    NetrwKeepj put ='\"   Sorted by '.sortby
9719    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9720   endif
9721   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9722"  else " Decho
9723"   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>"))
9724  endif
9725
9726  " show copy/move target, if any {{{3
9727  if g:netrw_banner
9728   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9729"    call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9730    NetrwKeepj put =''
9731    if s:netrwmftgt_islocal
9732     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9733    else
9734     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9735    endif
9736    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9737   else
9738"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
9739   endif
9740   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9741  endif
9742
9743  " Hiding...  -or-  Showing... {{{3
9744  if g:netrw_banner
9745"   call Decho("--handle hiding/showing (g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9746   if g:netrw_list_hide != "" && g:netrw_hide
9747    if g:netrw_hide == 1
9748     NetrwKeepj put ='\"   Hiding:        '.g:netrw_list_hide
9749    else
9750     NetrwKeepj put ='\"   Showing:       '.g:netrw_list_hide
9751    endif
9752    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9753   endif
9754   exe "NetrwKeepj ".w:netrw_bannercnt
9755
9756"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9757   let quickhelp   = g:netrw_quickhelp%len(s:QuickHelp)
9758"   call Decho("quickhelp   =".quickhelp,'~'.expand("<slnum>"))
9759   NetrwKeepj put ='\"   Quick Help: <F1>:help  '.s:QuickHelp[quickhelp]
9760"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9761   NetrwKeepj put ='\" =============================================================================='
9762   let w:netrw_bannercnt= w:netrw_bannercnt + 2
9763"  else " Decho
9764"   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>"))
9765  endif
9766
9767  " bannercnt should index the line just after the banner
9768  if g:netrw_banner
9769   let w:netrw_bannercnt= w:netrw_bannercnt + 1
9770   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9771"   call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9772"  else " Decho
9773"   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>"))
9774  endif
9775
9776  " get list of files
9777"  call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
9778  if a:islocal
9779   NetrwKeepj call s:LocalListing()
9780  else " remote
9781   NetrwKeepj let badresult= s:NetrwRemoteListing()
9782   if badresult
9783"    call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9784"    call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9785    return
9786   endif
9787  endif
9788
9789  " manipulate the directory listing (hide, sort) {{{3
9790  if !exists("w:netrw_bannercnt")
9791   let w:netrw_bannercnt= 0
9792  endif
9793"  call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9794"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9795"  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>"))
9796
9797  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9798"   call Decho("manipulate directory listing (hide)",'~'.expand("<slnum>"))
9799"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9800   if g:netrw_hide && g:netrw_list_hide != ""
9801    NetrwKeepj call s:NetrwListHide()
9802   endif
9803   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9804"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9805
9806    if g:netrw_sort_by =~# "^n"
9807     " sort by name
9808"     call Decho("sort by name",'~'.expand("<slnum>"))
9809     NetrwKeepj call s:NetrwSetSort()
9810
9811     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9812"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9813      if g:netrw_sort_direction =~# 'n'
9814       " name: sort by name of file
9815       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9816      else
9817       " reverse direction sorting
9818       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9819      endif
9820     endif
9821
9822     " remove priority pattern prefix
9823"     call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9824     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9825     NetrwKeepj call histdel("/",-1)
9826
9827    elseif g:netrw_sort_by =~# "^ext"
9828     " exten: sort by extension
9829     "   The histdel(...,-1) calls remove the last search from the search history
9830"     call Decho("sort by extension",'~'.expand("<slnum>"))
9831     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9832     NetrwKeepj call histdel("/",-1)
9833     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9834     NetrwKeepj call histdel("/",-1)
9835     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9836     NetrwKeepj call histdel("/",-1)
9837     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9838"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9839      if g:netrw_sort_direction =~# 'n'
9840       " normal direction sorting
9841       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9842      else
9843       " reverse direction sorting
9844       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9845      endif
9846     endif
9847     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9848     NetrwKeepj call histdel("/",-1)
9849
9850    elseif a:islocal
9851     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9852"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9853      if g:netrw_sort_direction =~# 'n'
9854"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9855       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9856      else
9857"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9858       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9859      endif
9860"     call Decho("remove leading digits/ (sorting) information from listing",'~'.expand("<slnum>"))
9861     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9862     NetrwKeepj call histdel("/",-1)
9863     endif
9864    endif
9865
9866   elseif g:netrw_sort_direction =~# 'r'
9867"    call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9868    if !g:netrw_banner || w:netrw_bannercnt < line('$')
9869     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9870     call histdel("/",-1)
9871    endif
9872   endif
9873  endif
9874"  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>"))
9875
9876  " convert to wide/tree listing {{{3
9877"  call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9878"  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>"))
9879  NetrwKeepj call s:NetrwWideListing()
9880"  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>"))
9881  NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
9882"  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>"))
9883
9884  " resolve symbolic links if local and (thin or tree)
9885  if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
9886"   call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9887   sil! g/@$/call s:ShowLink()
9888  endif
9889
9890  if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
9891   " place cursor on the top-left corner of the file listing
9892"   call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9893   exe 'sil! '.w:netrw_bannercnt
9894   sil! NetrwKeepj norm! 0
9895"   call Decho("  tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9896  else
9897"   call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9898"   call Decho("  w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9899"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
9900"   call Decho("  g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
9901  endif
9902
9903  " record previous current directory
9904  let w:netrw_prvdir= b:netrw_curdir
9905"  call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
9906
9907  " save certain window-oriented variables into buffer-oriented variables {{{3
9908"  call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9909"  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>"))
9910  NetrwKeepj call s:SetBufWinVars()
9911"  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>"))
9912  NetrwKeepj call s:NetrwOptionsRestore("w:")
9913"  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>"))
9914
9915  " set display to netrw display settings
9916"  call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
9917  exe "setl ".g:netrw_bufsettings
9918"  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>"))
9919  if g:netrw_liststyle == s:LONGLIST
9920"   call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9921   exe "setl ts=".(g:netrw_maxfilenamelen+1)
9922  endif
9923"  call Decho("PerformListing buffer:",'~'.expand("<slnum>"))
9924"  call DechoBuf(bufnr("%"))
9925
9926  if exists("s:treecurpos")
9927"   call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
9928"   call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#8)",'~'.expand("<slnum>"))
9929"   call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9930   NetrwKeepj call winrestview(s:treecurpos)
9931   unlet s:treecurpos
9932  endif
9933
9934"  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>"))
9935"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9936"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
9937endfun
9938
9939" ---------------------------------------------------------------------
9940" s:SetupNetrwStatusLine: {{{2
9941fun! s:SetupNetrwStatusLine(statline)
9942"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
9943
9944  if !exists("s:netrw_setup_statline")
9945   let s:netrw_setup_statline= 1
9946"   call Decho("do first-time status line setup",'~'.expand("<slnum>"))
9947
9948   if !exists("s:netrw_users_stl")
9949    let s:netrw_users_stl= &stl
9950   endif
9951   if !exists("s:netrw_users_ls")
9952    let s:netrw_users_ls= &laststatus
9953   endif
9954
9955   " set up User9 highlighting as needed
9956   let keepa= @a
9957   redir @a
9958   try
9959    hi User9
9960   catch /^Vim\%((\a\{3,})\)\=:E411/
9961    if &bg == "dark"
9962     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
9963    else
9964     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
9965    endif
9966   endtry
9967   redir END
9968   let @a= keepa
9969  endif
9970
9971  " set up status line (may use User9 highlighting)
9972  " insure that windows have a statusline
9973  " make sure statusline is displayed
9974  let &stl=a:statline
9975  setl laststatus=2
9976"  call Decho("stl=".&stl,'~'.expand("<slnum>"))
9977  redraw
9978
9979"  call Dret("SetupNetrwStatusLine : stl=".&stl)
9980endfun
9981
9982" =========================================
9983"  Remote Directory Browsing Support:  {{{1
9984" =========================================
9985
9986" ---------------------------------------------------------------------
9987" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
9988"  This function assumes that a long listing will be received.  Size, time,
9989"  and reverse sorts will be requested of the server but not otherwise
9990"  enforced here.
9991fun! s:NetrwRemoteFtpCmd(path,listcmd)
9992"  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 : "???")))
9993"  call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9994  " sanity check: {{{3
9995  if !exists("w:netrw_method")
9996   if exists("b:netrw_method")
9997    let w:netrw_method= b:netrw_method
9998   else
9999    call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
10000"    call Dret("NetrwRemoteFtpCmd")
10001    return
10002   endif
10003  endif
10004
10005  " WinXX ftp uses unix style input, so set ff to unix	" {{{3
10006  let ffkeep= &ff
10007  setl ma ff=unix noro
10008"  call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
10009
10010  " clear off any older non-banner lines	" {{{3
10011  " note that w:netrw_bannercnt indexes the line after the banner
10012"  call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _  (clear off old non-banner lines)",'~'.expand("<slnum>"))
10013  exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
10014
10015  ".........................................
10016  if w:netrw_method == 2 || w:netrw_method == 5	" {{{3
10017   " ftp + <.netrc>:  Method #2
10018   if a:path != ""
10019    NetrwKeepj put ='cd \"'.a:path.'\"'
10020   endif
10021   if exists("g:netrw_ftpextracmd")
10022    NetrwKeepj put =g:netrw_ftpextracmd
10023"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
10024   endif
10025   NetrwKeepj call setline(line("$")+1,a:listcmd)
10026"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
10027   if exists("g:netrw_port") && g:netrw_port != ""
10028"    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>"))
10029    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)
10030   else
10031"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
10032    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
10033   endif
10034
10035  ".........................................
10036  elseif w:netrw_method == 3	" {{{3
10037   " ftp + machine,id,passwd,filename:  Method #3
10038    setl ff=unix
10039    if exists("g:netrw_port") && g:netrw_port != ""
10040     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
10041    else
10042     NetrwKeepj put ='open '.g:netrw_machine
10043    endif
10044
10045    " handle userid and password
10046    let host= substitute(g:netrw_machine,'\..*$','','')
10047"    call Decho("host<".host.">",'~'.expand("<slnum>"))
10048    if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
10049     call NetUserPass("ftp:".host)
10050    endif
10051    if exists("g:netrw_uid") && g:netrw_uid != ""
10052     if exists("g:netrw_ftp") && g:netrw_ftp == 1
10053      NetrwKeepj put =g:netrw_uid
10054      if exists("s:netrw_passwd") && s:netrw_passwd != ""
10055       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
10056      endif
10057     elseif exists("s:netrw_passwd")
10058      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
10059     endif
10060    endif
10061
10062   if a:path != ""
10063    NetrwKeepj put ='cd \"'.a:path.'\"'
10064   endif
10065   if exists("g:netrw_ftpextracmd")
10066    NetrwKeepj put =g:netrw_ftpextracmd
10067"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
10068   endif
10069   NetrwKeepj call setline(line("$")+1,a:listcmd)
10070
10071   " perform ftp:
10072   " -i       : turns off interactive prompting from ftp
10073   " -n  unix : DON'T use <.netrc>, even though it exists
10074   " -n  win32: quit being obnoxious about password
10075   if exists("w:netrw_bannercnt")
10076"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
10077    call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
10078"   else " Decho
10079"    call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
10080"    g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
10081   endif
10082
10083  ".........................................
10084  elseif w:netrw_method == 9	" {{{3
10085   " sftp username@machine: Method #9
10086   " s:netrw_sftp_cmd
10087   setl ff=unix
10088
10089   " restore settings
10090   let &ff= ffkeep
10091"   call Dret("NetrwRemoteFtpCmd")
10092   return
10093
10094  ".........................................
10095  else	" {{{3
10096   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
10097  endif
10098
10099  " cleanup for Windows " {{{3
10100  if has("win32") || has("win95") || has("win64") || has("win16")
10101   sil! NetrwKeepj %s/\r$//e
10102   NetrwKeepj call histdel("/",-1)
10103  endif
10104  if a:listcmd == "dir"
10105   " infer directory/link based on the file permission string
10106   sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
10107   sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
10108   NetrwKeepj call histdel("/",-1)
10109   NetrwKeepj call histdel("/",-1)
10110   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10111    exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
10112    NetrwKeepj call histdel("/",-1)
10113   endif
10114  endif
10115
10116  " ftp's listing doesn't seem to include ./ or ../ " {{{3
10117  if !search('^\.\/$\|\s\.\/$','wn')
10118   exe 'NetrwKeepj '.w:netrw_bannercnt
10119   NetrwKeepj put ='./'
10120  endif
10121  if !search('^\.\.\/$\|\s\.\.\/$','wn')
10122   exe 'NetrwKeepj '.w:netrw_bannercnt
10123   NetrwKeepj put ='../'
10124  endif
10125
10126  " restore settings " {{{3
10127  let &ff= ffkeep
10128"  call Dret("NetrwRemoteFtpCmd")
10129endfun
10130
10131" ---------------------------------------------------------------------
10132" s:NetrwRemoteListing: {{{2
10133fun! s:NetrwRemoteListing()
10134"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
10135
10136  if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
10137   let w:netrw_bannercnt= s:bannercnt
10138  endif
10139  if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
10140   let w:netrw_bannercnt= s:bannercnt
10141  endif
10142
10143  call s:RemotePathAnalysis(b:netrw_curdir)
10144
10145  " sanity check:
10146  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
10147"   call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
10148   if !executable("ftp")
10149"    call Decho("ftp is not executable",'~'.expand("<slnum>"))
10150    if !exists("g:netrw_quiet")
10151     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
10152    endif
10153    call s:NetrwOptionsRestore("w:")
10154"    call Dret("s:NetrwRemoteListing -1")
10155    return -1
10156   endif
10157
10158  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
10159"   call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
10160   if !exists("g:netrw_quiet")
10161    if g:netrw_list_cmd == ""
10162     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)
10163    else
10164     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
10165    endif
10166   endif
10167
10168   NetrwKeepj call s:NetrwOptionsRestore("w:")
10169"   call Dret("s:NetrwRemoteListing -1")
10170   return -1
10171  endif  " (remote handling sanity check)
10172"  call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
10173
10174  if exists("b:netrw_method")
10175"   call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
10176   let w:netrw_method= b:netrw_method
10177  endif
10178
10179  if s:method == "ftp"
10180   " use ftp to get remote file listing {{{3
10181"   call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
10182   let s:method  = "ftp"
10183   let listcmd = g:netrw_ftp_list_cmd
10184   if g:netrw_sort_by =~# '^t'
10185    let listcmd= g:netrw_ftp_timelist_cmd
10186   elseif g:netrw_sort_by =~# '^s'
10187    let listcmd= g:netrw_ftp_sizelist_cmd
10188   endif
10189"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
10190   call s:NetrwRemoteFtpCmd(s:path,listcmd)
10191"   exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
10192
10193   " report on missing file or directory messages
10194   if search('[Nn]o such file or directory\|Failed to change directory')
10195    let mesg= getline(".")
10196    if exists("w:netrw_bannercnt")
10197     setl ma
10198     exe w:netrw_bannercnt.",$d _"
10199     setl noma
10200    endif
10201    NetrwKeepj call s:NetrwOptionsRestore("w:")
10202    call netrw#ErrorMsg(s:WARNING,mesg,96)
10203"    call Dret("s:NetrwRemoteListing : -1")
10204    return -1
10205   endif
10206
10207   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10208    " shorten the listing
10209"    call Decho("generate short listing",'~'.expand("<slnum>"))
10210    exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
10211
10212    " cleanup
10213    if g:netrw_ftp_browse_reject != ""
10214     exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
10215     NetrwKeepj call histdel("/",-1)
10216    endif
10217    sil! NetrwKeepj %s/\r$//e
10218    NetrwKeepj call histdel("/",-1)
10219
10220    " if there's no ../ listed, then put ../ in
10221    let line1= line(".")
10222    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10223    let line2= search('\.\.\/\%(\s\|$\)','cnW')
10224"    call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2."  w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
10225    if line2 == 0
10226"     call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
10227     sil! NetrwKeepj put='../'
10228    endif
10229    exe "sil! NetrwKeepj ".line1
10230    sil! NetrwKeepj norm! 0
10231
10232"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
10233    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10234"     call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
10235     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
10236     NetrwKeepj call histdel("/",-1)
10237    else " normal ftp cleanup
10238"     call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
10239     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
10240     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
10241     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
10242     NetrwKeepj call histdel("/",-1)
10243     NetrwKeepj call histdel("/",-1)
10244     NetrwKeepj call histdel("/",-1)
10245    endif
10246   endif
10247
10248   else
10249   " use ssh to get remote file listing {{{3
10250"   call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
10251   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
10252"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
10253   if g:netrw_scp_cmd =~ '^pscp'
10254"    call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
10255    exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
10256    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
10257    sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
10258    sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
10259    sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
10260    NetrwKeepj call histdel("/",-1)
10261    NetrwKeepj call histdel("/",-1)
10262    NetrwKeepj call histdel("/",-1)
10263    if g:netrw_liststyle != s:LONGLIST
10264     sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
10265     NetrwKeepj call histdel("/",-1)
10266    endif
10267   else
10268    if s:path == ""
10269"     call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
10270     exe "NetrwKeepj keepalt r! ".listcmd
10271    else
10272"     call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
10273     exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
10274"     call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
10275    endif
10276   endif
10277
10278   " cleanup
10279   if g:netrw_ssh_browse_reject != ""
10280"    call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
10281    exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
10282    NetrwKeepj call histdel("/",-1)
10283   endif
10284  endif
10285
10286  if w:netrw_liststyle == s:LONGLIST
10287   " do a long listing; these substitutions need to be done prior to sorting {{{3
10288"   call Decho("fix long listing:",'~'.expand("<slnum>"))
10289
10290   if s:method == "ftp"
10291    " cleanup
10292    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10293    while getline('.') =~# g:netrw_ftp_browse_reject
10294     sil! NetrwKeepj d
10295    endwhile
10296    " if there's no ../ listed, then put ../ in
10297    let line1= line(".")
10298    sil! NetrwKeepj 1
10299    sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
10300    let line2= line(".")
10301    if line2 == 0
10302     if b:netrw_curdir != '/'
10303      exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
10304     endif
10305    endif
10306    exe "sil! NetrwKeepj ".line1
10307    sil! NetrwKeepj norm! 0
10308   endif
10309
10310   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10311"    call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
10312    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/'
10313   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
10314"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
10315    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
10316    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
10317    exe 'sil NetrwKeepj '.w:netrw_bannercnt
10318    NetrwKeepj call histdel("/",-1)
10319    NetrwKeepj call histdel("/",-1)
10320    NetrwKeepj call histdel("/",-1)
10321   endif
10322  endif
10323
10324"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
10325"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
10326"  endif " Decho
10327
10328"  call Dret("s:NetrwRemoteListing 0")
10329  return 0
10330endfun
10331
10332" ---------------------------------------------------------------------
10333" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
10334fun! s:NetrwRemoteRm(usrhost,path) range
10335"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
10336"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10337  let svpos= winsaveview()
10338"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10339
10340  let all= 0
10341  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10342   " remove all marked files
10343"   call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>"))
10344   for fname in s:netrwmarkfilelist_{bufnr("%")}
10345    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
10346    if ok =~# 'q\%[uit]'
10347     break
10348    elseif ok =~# 'a\%[ll]'
10349     let all= 1
10350    endif
10351   endfor
10352   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10353
10354  else
10355   " remove files specified by range
10356"   call Decho("remove files specified by range",'~'.expand("<slnum>"))
10357
10358   " preparation for removing multiple files/directories
10359   let keepsol = &l:sol
10360   setl nosol
10361   let ctr    = a:firstline
10362
10363   " remove multiple files and directories
10364   while ctr <= a:lastline
10365    exe "NetrwKeepj ".ctr
10366    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
10367    if ok =~# 'q\%[uit]'
10368     break
10369    elseif ok =~# 'a\%[ll]'
10370     let all= 1
10371    endif
10372    let ctr= ctr + 1
10373   endwhile
10374   let &l:sol = keepsol
10375  endif
10376
10377  " refresh the (remote) directory listing
10378"  call Decho("refresh remote directory listing",'~'.expand("<slnum>"))
10379  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10380"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10381  NetrwKeepj call winrestview(svpos)
10382
10383"  call Dret("s:NetrwRemoteRm")
10384endfun
10385
10386" ---------------------------------------------------------------------
10387" s:NetrwRemoteRmFile: {{{2
10388fun! s:NetrwRemoteRmFile(path,rmfile,all)
10389"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
10390
10391  let all= a:all
10392  let ok = ""
10393
10394  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
10395   " attempt to remove file
10396"    call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
10397   if !all
10398    echohl Statement
10399"    call Decho("case all=0:",'~'.expand("<slnum>"))
10400    call inputsave()
10401    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10402    call inputrestore()
10403    echohl NONE
10404    if ok == ""
10405     let ok="no"
10406    endif
10407    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10408    if ok =~# 'a\%[ll]'
10409     let all= 1
10410    endif
10411   endif
10412
10413   if all || ok =~# 'y\%[es]' || ok == ""
10414"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
10415    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10416"     call Decho("case ftp:",'~'.expand("<slnum>"))
10417     let path= a:path
10418     if path =~ '^\a\{3,}://'
10419      let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
10420     endif
10421     sil! NetrwKeepj .,$d _
10422     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
10423    else
10424"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
10425     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
10426"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10427     if !exists("b:netrw_curdir")
10428      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
10429      let ok="q"
10430     else
10431      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
10432"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10433"      call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
10434"      call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
10435      if remotedir != ""
10436       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
10437      else
10438       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
10439      endif
10440"      call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
10441      let ret= system(netrw_rm_cmd)
10442      if v:shell_error != 0
10443       if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
10444	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)
10445       else
10446        call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10447       endif
10448      elseif ret != 0
10449       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10450      endif
10451"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10452     endif
10453    endif
10454   elseif ok =~# 'q\%[uit]'
10455"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10456   endif
10457
10458  else
10459   " attempt to remove directory
10460"    call Decho("attempt to remove directory",'~'.expand("<slnum>"))
10461   if !all
10462    call inputsave()
10463    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10464    call inputrestore()
10465    if ok == ""
10466     let ok="no"
10467    endif
10468    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10469    if ok =~# 'a\%[ll]'
10470     let all= 1
10471    endif
10472   endif
10473
10474   if all || ok =~# 'y\%[es]' || ok == ""
10475    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10476     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
10477    else
10478     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
10479     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
10480"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
10481     let ret= system(netrw_rmdir_cmd)
10482"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10483
10484     if v:shell_error != 0
10485"      call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
10486      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
10487"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
10488      let ret= system(netrw_rmf_cmd)
10489"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10490
10491      if v:shell_error != 0 && !exists("g:netrw_quiet")
10492      	NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
10493      endif
10494     endif
10495    endif
10496
10497   elseif ok =~# 'q\%[uit]'
10498"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10499   endif
10500  endif
10501
10502"  call Dret("s:NetrwRemoteRmFile ".ok)
10503  return ok
10504endfun
10505
10506" ---------------------------------------------------------------------
10507" s:NetrwRemoteRename: rename a remote file or directory {{{2
10508fun! s:NetrwRemoteRename(usrhost,path) range
10509"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
10510
10511  " preparation for removing multiple files/directories
10512  let svpos      = winsaveview()
10513"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10514  let ctr        = a:firstline
10515  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10516
10517  " rename files given by the markfilelist
10518  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10519   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10520"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10521    if exists("subfrom")
10522     let newname= substitute(oldname,subfrom,subto,'')
10523"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10524    else
10525     call inputsave()
10526     let newname= input("Moving ".oldname." to : ",oldname)
10527     call inputrestore()
10528     if newname =~ '^s/'
10529      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10530      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10531      let newname = substitute(oldname,subfrom,subto,'')
10532"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10533     endif
10534    endif
10535
10536    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10537     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10538    else
10539     let oldname= s:ShellEscape(a:path.oldname)
10540     let newname= s:ShellEscape(a:path.newname)
10541"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10542     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10543    endif
10544
10545   endfor
10546   call s:NetrwUnMarkFile(1)
10547
10548  else
10549
10550  " attempt to rename files/directories
10551   let keepsol= &l:sol
10552   setl nosol
10553   while ctr <= a:lastline
10554    exe "NetrwKeepj ".ctr
10555
10556    let oldname= s:NetrwGetWord()
10557"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10558
10559    call inputsave()
10560    let newname= input("Moving ".oldname." to : ",oldname)
10561    call inputrestore()
10562
10563    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10564     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10565    else
10566     let oldname= s:ShellEscape(a:path.oldname)
10567     let newname= s:ShellEscape(a:path.newname)
10568"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10569     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10570    endif
10571
10572    let ctr= ctr + 1
10573   endwhile
10574   let &l:sol= keepsol
10575  endif
10576
10577  " refresh the directory
10578  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10579"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10580  NetrwKeepj call winrestview(svpos)
10581
10582"  call Dret("NetrwRemoteRename")
10583endfun
10584
10585" ==========================================
10586"  Local Directory Browsing Support:    {{{1
10587" ==========================================
10588
10589" ---------------------------------------------------------------------
10590" netrw#FileUrlEdit: handles editing file://* files {{{2
10591"   Should accept:   file://localhost/etc/fstab
10592"                    file:///etc/fstab
10593"                    file:///c:/WINDOWS/clock.avi
10594"                    file:///c|/WINDOWS/clock.avi
10595"                    file://localhost/c:/WINDOWS/clock.avi
10596"                    file://localhost/c|/WINDOWS/clock.avi
10597"                    file://c:/foo.txt
10598"                    file:///c:/foo.txt
10599" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
10600fun! netrw#FileUrlEdit(fname)
10601"  call Dfunc("netrw#FileUrlEdit(fname<".a:fname.">)")
10602  let fname = a:fname
10603  if fname =~ '^file://localhost/'
10604"   call Decho('converting file://localhost/   -to-  file:///','~'.expand("<slnum>"))
10605   let fname= substitute(fname,'^file://localhost/','file:///','')
10606"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10607  endif
10608  if (has("win32") || has("win95") || has("win64") || has("win16"))
10609   if fname  =~ '^file:///\=\a[|:]/'
10610"    call Decho('converting file:///\a|/   -to-  file://\a:/','~'.expand("<slnum>"))
10611    let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10612"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10613   endif
10614  endif
10615  let fname2396 = netrw#RFC2396(fname)
10616  let fname2396e= fnameescape(fname2396)
10617  let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
10618  if (has("win32") || has("win95") || has("win64") || has("win16"))
10619"   call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10620   if plainfname =~ '^/\+\a:'
10621"    call Decho('removing leading "/"s','~'.expand("<slnum>"))
10622    let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10623   endif
10624  endif
10625
10626"  call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10627"  call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
10628  exe "sil doau BufReadPre ".fname2396e
10629  exe 'NetrwKeepj keepalt edit '.plainfname
10630  exe 'sil! NetrwKeepj keepalt bdelete '.fnameescape(a:fname)
10631
10632"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10633"  call Dret("netrw#FileUrlEdit")
10634  exe "sil doau BufReadPost ".fname2396e
10635endfun
10636
10637" ---------------------------------------------------------------------
10638" netrw#LocalBrowseCheck: {{{2
10639fun! netrw#LocalBrowseCheck(dirname)
10640  " This function is called by netrwPlugin.vim's s:LocalBrowse(), s:NetrwRexplore(),
10641  " and by <cr> when atop a listed file/directory (via a buffer-local map)
10642  "
10643  " unfortunate interaction -- split window debugging can't be used here, must use
10644  "                            D-echoRemOn or D-echoTabOn as the BufEnter event triggers
10645  "                            another call to LocalBrowseCheck() when attempts to write
10646  "                            to the DBG buffer are made.
10647  "
10648  " The &ft == "netrw" test was installed because the BufEnter event
10649  " would hit when re-entering netrw windows, creating unexpected
10650  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
10651"  call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">)")
10652"  call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>"))
10653"  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>"))
10654"  call Dredir("ls!","netrw#LocalBrowseCheck")
10655"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10656"  call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
10657
10658  let ykeep= @@
10659  if isdirectory(s:NetrwFile(a:dirname))
10660"   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>"))
10661
10662   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10663"    call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10664"    call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10665    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10666
10667   elseif &ft == "netrw" && line("$") == 1
10668"    call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10669    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10670
10671   elseif exists("s:treeforceredraw")
10672"    call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10673    unlet s:treeforceredraw
10674    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10675   endif
10676"   call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10677"   call Dret("netrw#LocalBrowseCheck")
10678   return
10679  endif
10680
10681  " The following code wipes out currently unused netrw buffers
10682  "       IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10683  "   AND IF the listing style is not a tree listing
10684  if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
10685"   call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10686   let ibuf    = 1
10687   let buflast = bufnr("$")
10688   while ibuf <= buflast
10689    if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10690     exe "sil! keepj keepalt ".ibuf."bw!"
10691    endif
10692    let ibuf= ibuf + 1
10693   endwhile
10694  endif
10695  let @@= ykeep
10696"  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>"))
10697"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10698  " not a directory, ignore it
10699"  call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
10700endfun
10701
10702" ---------------------------------------------------------------------
10703" s:LocalBrowseRefresh: this function is called after a user has {{{2
10704" performed any shell command.  The idea is to cause all local-browsing
10705" buffers to be refreshed after a user has executed some shell command,
10706" on the chance that s/he removed/created a file/directory with it.
10707fun! s:LocalBrowseRefresh()
10708"  call Dfunc("s:LocalBrowseRefresh() tabpagenr($)=".tabpagenr("$"))
10709"  call Decho("s:netrw_browselist =".(exists("s:netrw_browselist")?  string(s:netrw_browselist)  : '<n/a>'),'~'.expand("<slnum>"))
10710"  call Decho("w:netrw_bannercnt  =".(exists("w:netrw_bannercnt")?   string(w:netrw_bannercnt)   : '<n/a>'),'~'.expand("<slnum>"))
10711
10712  " determine which buffers currently reside in a tab
10713  if !exists("s:netrw_browselist")
10714"   call Dret("s:LocalBrowseRefresh : browselist is empty")
10715   return
10716  endif
10717  if !exists("w:netrw_bannercnt")
10718"   call Dret("s:LocalBrowseRefresh : don't refresh when focus not on netrw window")
10719   return
10720  endif
10721  if exists("s:netrw_events") && s:netrw_events == 1
10722   " s:LocalFastBrowser gets called (indirectly) from a
10723   let s:netrw_events= 2
10724"   call Dret("s:LocalBrowseRefresh : avoid initial double refresh")
10725   return
10726  endif
10727  let itab       = 1
10728  let buftablist = []
10729  let ykeep      = @@
10730  while itab <= tabpagenr("$")
10731   let buftablist = buftablist + tabpagebuflist()
10732   let itab       = itab + 1
10733   sil! tabn
10734  endwhile
10735"  call Decho("buftablist".string(buftablist),'~'.expand("<slnum>"))
10736"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("<slnum>"))
10737  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10738  "   | refresh any netrw window
10739  "   | wipe out any non-displaying netrw buffer
10740  let curwinid = win_getid(winnr())
10741  let ibl    = 0
10742  for ibuf in s:netrw_browselist
10743"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("<slnum>"))
10744   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10745    " wipe out any non-displaying netrw buffer
10746    " (ibuf not shown in a current window AND
10747    "  ibuf not in any tab)
10748"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("<slnum>"))
10749    exe "sil! keepj bd ".fnameescape(ibuf)
10750    call remove(s:netrw_browselist,ibl)
10751"    call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10752    continue
10753   elseif index(tabpagebuflist(),ibuf) != -1
10754    " refresh any netrw buffer
10755"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>"))
10756    exe bufwinnr(ibuf)."wincmd w"
10757    if getline(".") =~# 'Quick Help'
10758     " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10759     " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10760     let g:netrw_quickhelp= g:netrw_quickhelp - 1
10761    endif
10762"    call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>"))
10763    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10764     NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10765    endif
10766    NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10767   endif
10768   let ibl= ibl + 1
10769"   call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("<slnum>"))
10770  endfor
10771"  call Decho("restore window: win_gotoid(".curwinid.")")
10772  call win_gotoid(curwinid)
10773  let @@= ykeep
10774
10775"  call Dret("s:LocalBrowseRefresh")
10776endfun
10777
10778" ---------------------------------------------------------------------
10779" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10780"
10781"     g:netrw_    Directory Is
10782"     fastbrowse  Local  Remote
10783"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
10784"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
10785"  fast   2         H      H
10786"
10787"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10788"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
10789"                       (re-using a buffer may not be as accurate)
10790"
10791"  s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds whena med or fast browsing
10792"                   =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10793"                       BufEnter may be first event, then a FocusGained event.  Ignore the first FocusGained event.
10794"                       If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10795"                   =2: autocmds installed (doesn't ignore any FocusGained events)
10796fun! s:LocalFastBrowser()
10797"  call Dfunc("s:LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
10798"  call Decho("s:netrw_events        ".(exists("s:netrw_events")? "exists"            : 'n/a'),'~'.expand("<slnum>"))
10799"  call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")?  "already installed" : "not installed"),'~'.expand("<slnum>"))
10800"  call Decho("autocmd: FocusGained  ".(exists("#FocusGained")?   "already installed" : "not installed"),'~'.expand("<slnum>"))
10801
10802  " initialize browselist, a list of buffer numbers that the local browser has used
10803  if !exists("s:netrw_browselist")
10804"   call Decho("initialize s:netrw_browselist",'~'.expand("<slnum>"))
10805   let s:netrw_browselist= []
10806  endif
10807
10808  " append current buffer to fastbrowse list
10809  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
10810"   call Decho("appendng current buffer to browselist",'~'.expand("<slnum>"))
10811   call add(s:netrw_browselist,bufnr("%"))
10812"   call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10813  endif
10814
10815  " enable autocmd events to handle refreshing/removing local browser buffers
10816  "    If local browse buffer is currently showing: refresh it
10817  "    If local browse buffer is currently hidden : wipe it
10818  "    g:netrw_fastbrowse=0 : slow   speed, never re-use directory listing
10819  "                      =1 : medium speed, re-use directory listing for remote only
10820  "                      =2 : fast   speed, always re-use directory listing when possible
10821  if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
10822   let s:netrw_events= 1
10823   augroup AuNetrwEvent
10824    au!
10825    if (has("win32") || has("win95") || has("win64") || has("win16"))
10826"     call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
10827     au ShellCmdPost			*	call s:LocalBrowseRefresh()
10828    else
10829"     call Decho("installing autocmds: ShellCmdPost FocusGained",'~'.expand("<slnum>"))
10830     au ShellCmdPost,FocusGained	*	call s:LocalBrowseRefresh()
10831    endif
10832   augroup END
10833
10834  " user must have changed fastbrowse to its fast setting, so remove
10835  " the associated autocmd events
10836  elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
10837"   call Decho("remove AuNetrwEvent autcmd group",'~'.expand("<slnum>"))
10838   unlet s:netrw_events
10839   augroup AuNetrwEvent
10840    au!
10841   augroup END
10842   augroup! AuNetrwEvent
10843  endif
10844
10845"  call Dret("s:LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
10846endfun
10847
10848" ---------------------------------------------------------------------
10849"  s:LocalListing: does the job of "ls" for local directories {{{2
10850fun! s:LocalListing()
10851"  call Dfunc("s:LocalListing()")
10852"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10853"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
10854"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10855
10856"  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
10857"  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
10858"  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>"))
10859
10860  " get the list of files contained in the current directory
10861  let dirname    = b:netrw_curdir
10862  let dirnamelen = strlen(b:netrw_curdir)
10863  let filelist   = s:NetrwGlob(dirname,"*",0)
10864  let filelist   = filelist + s:NetrwGlob(dirname,".*",0)
10865"  call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10866
10867  if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
10868"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10869  elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
10870    " include ../ in the glob() entry if its missing
10871"   call Decho("forcibly including on \"..\"",'~'.expand("<slnum>"))
10872   let filelist= filelist+[s:ComposePath(b:netrw_curdir,"../")]
10873"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10874  endif
10875
10876"  call Decho("before while: dirname   <".dirname.">",'~'.expand("<slnum>"))
10877"  call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>"))
10878"  call Decho("before while: filelist  =".string(filelist),'~'.expand("<slnum>"))
10879
10880  if get(g:, 'netrw_dynamic_maxfilenamelen', 0)
10881   let filelistcopy           = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10882   let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
10883"   call Decho("dynamic_maxfilenamelen: filenames             =".string(filelistcopy),'~'.expand("<slnum>"))
10884"   call Decho("dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen,'~'.expand("<slnum>"))
10885  endif
10886"  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>"))
10887
10888  for filename in filelist
10889"   call Decho(" ",'~'.expand("<slnum>"))
10890"   call Decho("for filename in filelist: filename<".filename.">",'~'.expand("<slnum>"))
10891
10892   if getftype(filename) == "link"
10893    " indicate a symbolic link
10894"    call Decho("indicate <".filename."> is a symbolic link with trailing @",'~'.expand("<slnum>"))
10895    let pfile= filename."@"
10896
10897   elseif getftype(filename) == "socket"
10898    " indicate a socket
10899"    call Decho("indicate <".filename."> is a socket with trailing =",'~'.expand("<slnum>"))
10900    let pfile= filename."="
10901
10902   elseif getftype(filename) == "fifo"
10903    " indicate a fifo
10904"    call Decho("indicate <".filename."> is a fifo with trailing |",'~'.expand("<slnum>"))
10905    let pfile= filename."|"
10906
10907   elseif isdirectory(s:NetrwFile(filename))
10908    " indicate a directory
10909"    call Decho("indicate <".filename."> is a directory with trailing /",'~'.expand("<slnum>"))
10910    let pfile= filename."/"
10911
10912   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10913    if (has("win32") || has("win95") || has("win64") || has("win16"))
10914     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10915      " indicate an executable
10916"      call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10917      let pfile= filename."*"
10918     else
10919      " normal file
10920      let pfile= filename
10921     endif
10922    elseif executable(filename)
10923     " indicate an executable
10924"     call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10925     let pfile= filename."*"
10926    else
10927     " normal file
10928     let pfile= filename
10929    endif
10930
10931   else
10932    " normal file
10933    let pfile= filename
10934   endif
10935"   call Decho("pfile<".pfile."> (after *@/ appending)",'~'.expand("<slnum>"))
10936
10937   if pfile =~ '//$'
10938    let pfile= substitute(pfile,'//$','/','e')
10939"    call Decho("change // to /: pfile<".pfile.">",'~'.expand("<slnum>"))
10940   endif
10941   let pfile= strpart(pfile,dirnamelen)
10942   let pfile= substitute(pfile,'^[/\\]','','e')
10943"   call Decho("filename<".filename.">",'~'.expand("<slnum>"))
10944"   call Decho("pfile   <".pfile.">",'~'.expand("<slnum>"))
10945
10946   if w:netrw_liststyle == s:LONGLIST
10947    let sz   = getfsize(filename)
10948    let fsz  = strpart("               ",1,15-strlen(sz)).sz
10949    if g:netrw_sizestyle =~# "[hH]"
10950     let sz= s:NetrwHumanReadable(sz)
10951    endif
10952    let longfile= printf("%-".(g:netrw_maxfilenamelen+1)."s",pfile)
10953    let pfile   = longfile.fsz." ".strftime(g:netrw_timefmt,getftime(filename))
10954"    call Decho("longlist support: sz=".sz." fsz=".fsz,'~'.expand("<slnum>"))
10955   endif
10956
10957   if     g:netrw_sort_by =~# "^t"
10958    " sort by time (handles time up to 1 quintillion seconds, US)
10959    " Decorate listing by prepending a timestamp/  .  Sorting will then be done based on time.
10960"    call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>"))
10961    let t  = getftime(filename)
10962    let ft = strpart("000000000000000000",1,18-strlen(t)).t
10963"    call Decho("exe NetrwKeepj put ='".ft.'/'.pfile."'",'~'.expand("<slnum>"))
10964    let ftpfile= ft.'/'.pfile
10965    sil! NetrwKeepj put=ftpfile
10966
10967   elseif g:netrw_sort_by =~ "^s"
10968    " sort by size (handles file sizes up to 1 quintillion bytes, US)
10969"    call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>"))
10970    let sz   = getfsize(filename)
10971    if g:netrw_sizestyle =~# "[hH]"
10972     let sz= s:NetrwHumanReadable(sz)
10973    endif
10974    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
10975"    call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>"))
10976    let fszpfile= fsz.'/'.pfile
10977    sil! NetrwKeepj put =fszpfile
10978
10979   else
10980    " sort by name
10981"    call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("<slnum>"))
10982    sil! NetrwKeepj put=pfile
10983   endif
10984"   call DechoBuf(bufnr("%"),"bufnr(%)")
10985  endfor
10986
10987  " cleanup any windows mess at end-of-line
10988  sil! NetrwKeepj g/^$/d
10989  sil! NetrwKeepj %s/\r$//e
10990  call histdel("/",-1)
10991"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
10992  exe "setl ts=".(g:netrw_maxfilenamelen+1)
10993
10994"  call Dret("s:LocalListing")
10995endfun
10996
10997" ---------------------------------------------------------------------
10998" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
10999fun! s:NetrwLocalExecute(cmd)
11000"  call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
11001  let ykeep= @@
11002  " sanity check
11003  if !executable(a:cmd)
11004   call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
11005   let @@= ykeep
11006"   call Dret("s:NetrwLocalExecute")
11007   return
11008  endif
11009
11010  let optargs= input(":!".a:cmd,"","file")
11011"  call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
11012  let result= system(a:cmd.optargs)
11013"  call Decho("result,'~'.expand("<slnum>"))
11014
11015  " strip any ansi escape sequences off
11016  let result = substitute(result,"\e\\[[0-9;]*m","","g")
11017
11018  " show user the result(s)
11019  echomsg result
11020  let @@= ykeep
11021
11022"  call Dret("s:NetrwLocalExecute")
11023endfun
11024
11025" ---------------------------------------------------------------------
11026" s:NetrwLocalRename: rename a local file or directory {{{2
11027fun! s:NetrwLocalRename(path) range
11028"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
11029
11030  " preparation for removing multiple files/directories
11031  let ykeep     = @@
11032  let ctr       = a:firstline
11033  let svpos     = winsaveview()
11034  let all       = 0
11035"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11036
11037  " rename files given by the markfilelist
11038  if exists("s:netrwmarkfilelist_{bufnr('%')}")
11039   for oldname in s:netrwmarkfilelist_{bufnr("%")}
11040"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
11041    if exists("subfrom")
11042     let newname= substitute(oldname,subfrom,subto,'')
11043"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
11044    else
11045     call inputsave()
11046     let newname= input("Moving ".oldname." to : ",oldname,"file")
11047     call inputrestore()
11048     if newname =~ ''
11049      " two ctrl-x's : ignore all of string preceding the ctrl-x's
11050      let newname = substitute(newname,'^.*','','')
11051     elseif newname =~ ''
11052      " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
11053      let newname = substitute(newname,'[^/]*','','')
11054     endif
11055     if newname =~ '^s/'
11056      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
11057      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
11058"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
11059      let newname = substitute(oldname,subfrom,subto,'')
11060     endif
11061    endif
11062    if !all && filereadable(newname)
11063     call inputsave()
11064      let response= input("File<".newname."> already exists; do you want to overwrite it? (y/all/n) ")
11065     call inputrestore()
11066     if response == "all"
11067      let all= 1
11068     elseif response != "y" && response != "yes"
11069      " refresh the directory
11070"      call Decho("refresh the directory listing",'~'.expand("<slnum>"))
11071      NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11072"      call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11073      NetrwKeepj call winrestview(svpos)
11074      let @@= ykeep
11075"      call Dret("NetrwLocalRename")
11076      return
11077     endif
11078    endif
11079    call rename(oldname,newname)
11080   endfor
11081   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
11082
11083  else
11084
11085   " attempt to rename files/directories
11086   while ctr <= a:lastline
11087    exe "NetrwKeepj ".ctr
11088
11089    " sanity checks
11090    if line(".") < w:netrw_bannercnt
11091     let ctr= ctr + 1
11092     continue
11093    endif
11094    let curword= s:NetrwGetWord()
11095    if curword == "./" || curword == "../"
11096     let ctr= ctr + 1
11097     continue
11098    endif
11099
11100    NetrwKeepj norm! 0
11101    let oldname= s:ComposePath(a:path,curword)
11102"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
11103
11104    call inputsave()
11105    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
11106    call inputrestore()
11107
11108    call rename(oldname,newname)
11109"    call Decho("renaming <".oldname."> to <".newname.">",'~'.expand("<slnum>"))
11110
11111    let ctr= ctr + 1
11112   endwhile
11113  endif
11114
11115  " refresh the directory
11116"  call Decho("refresh the directory listing",'~'.expand("<slnum>"))
11117  NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11118"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11119  NetrwKeepj call winrestview(svpos)
11120  let @@= ykeep
11121
11122"  call Dret("NetrwLocalRename")
11123endfun
11124
11125" ---------------------------------------------------------------------
11126" s:NetrwLocalRm: {{{2
11127fun! s:NetrwLocalRm(path) range
11128"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
11129"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
11130
11131  " preparation for removing multiple files/directories
11132  let ykeep = @@
11133  let ret   = 0
11134  let all   = 0
11135  let svpos = winsaveview()
11136"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11137
11138  if exists("s:netrwmarkfilelist_{bufnr('%')}")
11139   " remove all marked files
11140"   call Decho("remove all marked files",'~'.expand("<slnum>"))
11141   for fname in s:netrwmarkfilelist_{bufnr("%")}
11142    let ok= s:NetrwLocalRmFile(a:path,fname,all)
11143    if ok =~# 'q\%[uit]' || ok == "no"
11144     break
11145    elseif ok =~# 'a\%[ll]'
11146     let all= 1
11147    endif
11148   endfor
11149   call s:NetrwUnMarkFile(1)
11150
11151  else
11152  " remove (multiple) files and directories
11153"   call Decho("remove files in range [".a:firstline.",".a:lastline."]",'~'.expand("<slnum>"))
11154
11155   let keepsol= &l:sol
11156   setl nosol
11157   let ctr = a:firstline
11158   while ctr <= a:lastline
11159    exe "NetrwKeepj ".ctr
11160
11161    " sanity checks
11162    if line(".") < w:netrw_bannercnt
11163     let ctr= ctr + 1
11164     continue
11165    endif
11166    let curword= s:NetrwGetWord()
11167    if curword == "./" || curword == "../"
11168     let ctr= ctr + 1
11169     continue
11170    endif
11171    let ok= s:NetrwLocalRmFile(a:path,curword,all)
11172    if ok =~# 'q\%[uit]' || ok == "no"
11173     break
11174    elseif ok =~# 'a\%[ll]'
11175     let all= 1
11176    endif
11177    let ctr= ctr + 1
11178   endwhile
11179   let &l:sol= keepsol
11180  endif
11181
11182  " refresh the directory
11183"  call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>"))
11184  if bufname("%") != "NetrwMessage"
11185   NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
11186"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
11187   NetrwKeepj call winrestview(svpos)
11188  endif
11189  let @@= ykeep
11190
11191"  call Dret("s:NetrwLocalRm")
11192endfun
11193
11194" ---------------------------------------------------------------------
11195" s:NetrwLocalRmFile: remove file fname given the path {{{2
11196"                     Give confirmation prompt unless all==1
11197fun! s:NetrwLocalRmFile(path,fname,all)
11198"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
11199
11200  let all= a:all
11201  let ok = ""
11202  NetrwKeepj norm! 0
11203  let rmfile= s:NetrwFile(s:ComposePath(a:path,a:fname))
11204"  call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
11205
11206  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
11207   " attempt to remove file
11208"   call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
11209   if !all
11210    echohl Statement
11211    call inputsave()
11212    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11213    call inputrestore()
11214    echohl NONE
11215    if ok == ""
11216     let ok="no"
11217    endif
11218"    call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
11219    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11220"    call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
11221    if ok =~# 'a\%[ll]'
11222     let all= 1
11223    endif
11224   endif
11225
11226   if all || ok =~# 'y\%[es]' || ok == ""
11227    let ret= s:NetrwDelete(rmfile)
11228"    call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
11229   endif
11230
11231  else
11232   " attempt to remove directory
11233   if !all
11234    echohl Statement
11235    call inputsave()
11236    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11237    call inputrestore()
11238    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11239    if ok == ""
11240     let ok="no"
11241    endif
11242    if ok =~# 'a\%[ll]'
11243     let all= 1
11244    endif
11245   endif
11246   let rmfile= substitute(rmfile,'[\/]$','','e')
11247
11248   if all || ok =~# 'y\%[es]' || ok == ""
11249    if v:version < 704 || (v:version == 704 && !has("patch1107"))
11250" "    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>"))
11251     call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile))
11252" "    call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>"))
11253
11254     if v:shell_error != 0
11255" "     call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11256      let errcode= s:NetrwDelete(rmfile)
11257" "     call Decho("errcode=".errcode,'~'.expand("<slnum>"))
11258
11259      if errcode != 0
11260       if has("unix")
11261" "       call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11262	call system("rm ".s:ShellEscape(rmfile))
11263	if v:shell_error != 0 && !exists("g:netrw_quiet")
11264	 call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
11265	 let ok="no"
11266	endif
11267       elseif !exists("g:netrw_quiet")
11268	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
11269	let ok="no"
11270       endif
11271      endif
11272     endif
11273    else
11274     if delete(rmfile,"d")
11275      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
11276     endif
11277    endif
11278   endif
11279  endif
11280
11281"  call Dret("s:NetrwLocalRmFile ".ok)
11282  return ok
11283endfun
11284
11285" =====================================================================
11286" Support Functions: {{{1
11287
11288" ---------------------------------------------------------------------
11289" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
11290"   0: marked file list of current buffer
11291"   1: marked file target
11292fun! netrw#Access(ilist)
11293  if     a:ilist == 0
11294   if exists("s:netrwmarkfilelist_".bufnr('%'))
11295    return s:netrwmarkfilelist_{bufnr('%')}
11296   else
11297    return "no-list-buf#".bufnr('%')
11298   endif
11299  elseif a:ilist == 1
11300   return s:netrwmftgt
11301  endif
11302endfun
11303
11304" ---------------------------------------------------------------------
11305" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
11306fun! netrw#Call(funcname,...)
11307  return call("s:".a:funcname,a:000)
11308endfun
11309
11310" ---------------------------------------------------------------------
11311" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
11312"               I expect this function to be used in
11313"                 :PChkAssert netrw#Expose("netrwmarkfilelist")
11314"               for example.
11315fun! netrw#Expose(varname)
11316"   call Dfunc("netrw#Expose(varname<".a:varname.">)")
11317  if exists("s:".a:varname)
11318   exe "let retval= s:".a:varname
11319"   call Decho("retval=".retval,'~'.expand("<slnum>"))
11320   if exists("g:netrw_pchk")
11321"    call Decho("type(g:netrw_pchk=".g:netrw_pchk.")=".type(retval),'~'.expand("<slnum>"))
11322    if type(retval) == 3
11323     let retval = copy(retval)
11324     let i      = 0
11325     while i < len(retval)
11326      let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
11327      let i        = i + 1
11328     endwhile
11329    endif
11330"     call Dret("netrw#Expose ".string(retval)),'~'.expand("<slnum>"))
11331    return string(retval)
11332   else
11333"    call Decho("g:netrw_pchk doesn't exist",'~'.expand("<slnum>"))
11334   endif
11335  else
11336"   call Decho("s:".a:varname." doesn't exist",'~'.expand("<slnum>"))
11337   let retval= "n/a"
11338  endif
11339
11340"  call Dret("netrw#Expose ".string(retval))
11341  return retval
11342endfun
11343
11344" ---------------------------------------------------------------------
11345" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
11346fun! netrw#Modify(varname,newvalue)
11347"  call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
11348  exe "let s:".a:varname."= ".string(a:newvalue)
11349"  call Dret("netrw#Modify")
11350endfun
11351
11352" ---------------------------------------------------------------------
11353"  netrw#RFC2396: converts %xx into characters {{{2
11354fun! netrw#RFC2396(fname)
11355"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
11356  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
11357"  call Dret("netrw#RFC2396 ".fname)
11358  return fname
11359endfun
11360
11361" ---------------------------------------------------------------------
11362" netrw#UserMaps: supports user-specified maps {{{2
11363"                 see :help function()
11364"
11365"                 g:Netrw_UserMaps is a List with members such as:
11366"                       [[keymap sequence, function reference],...]
11367"
11368"                 The referenced function may return a string,
11369"                 	refresh : refresh the display
11370"                 	-other- : this string will be executed
11371"                 or it may return a List of strings.
11372"
11373"                 Each keymap-sequence will be set up with a nnoremap
11374"                 to invoke netrw#UserMaps(a:islocal).
11375"                 Related functions:
11376"                   netrw#Expose(varname)          -- see s:varname variables
11377"                   netrw#Modify(varname,newvalue) -- modify value of s:varname variable
11378"                   netrw#Call(funcname,...)       -- call internal netrw function with optional arguments
11379fun! netrw#UserMaps(islocal)
11380"  call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
11381"  call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
11382
11383   " set up usermaplist
11384   if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
11385"    call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
11386    for umap in g:Netrw_UserMaps
11387"     call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
11388"     call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
11389     " if umap[0] is a string and umap[1] is a string holding a function name
11390     if type(umap[0]) == 1 && type(umap[1]) == 1
11391"      call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
11392      exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
11393      else
11394       call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
11395     endif
11396    endfor
11397   endif
11398"  call Dret("netrw#UserMaps")
11399endfun
11400
11401" ---------------------------------------------------------------------
11402" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
11403fun! netrw#WinPath(path)
11404"  call Dfunc("netrw#WinPath(path<".a:path.">)")
11405  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
11406   " remove cygdrive prefix, if present
11407   let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
11408   " remove trailing slash (Win95)
11409   let path = substitute(path, '\(\\\|/\)$', '', 'g')
11410   " remove escaped spaces
11411   let path = substitute(path, '\ ', ' ', 'g')
11412   " convert slashes to backslashes
11413   let path = substitute(path, '/', '\', 'g')
11414  else
11415   let path= a:path
11416  endif
11417"  call Dret("netrw#WinPath <".path.">")
11418  return path
11419endfun
11420
11421" ---------------------------------------------------------------------
11422" s:NetrwBadd: adds marked files to buffer list or vice versa {{{2
11423"              cb : bl2mf=0  add marked files to buffer list
11424"              cB : bl2mf=1  use bufferlist to mark files
11425"              (mnemonic: cb = copy (marked files) to buffer list)
11426fun! s:NetrwBadd(islocal,bl2mf)
11427"  "  call Dfunc("s:NetrwBadd(islocal=".a:islocal." mf2bl=".mf2bl.")")
11428  if a:bl2mf
11429   " cB: add buffer list to marked files
11430   redir => bufl
11431    ls
11432   redir END
11433   let bufl = map(split(bufl,"\n"),'substitute(v:val,''^.\{-}"\(.*\)".\{-}$'',''\1'','''')')
11434   for fname in bufl
11435    call s:NetrwMarkFile(a:islocal,fname)
11436   endfor
11437  else
11438   " cb: add marked files to buffer list
11439   for fname in s:netrwmarkfilelist_{bufnr("%")}
11440" "   call Decho("badd ".fname,'~'.expand("<slnum>"))
11441    exe "badd ".fnameescape(fname)
11442   endfor
11443   let curbufnr = bufnr("%")
11444   let curdir   = s:NetrwGetCurdir(a:islocal)
11445   call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
11446  endif
11447"  call Dret("s:NetrwBadd")
11448endfun
11449
11450" ---------------------------------------------------------------------
11451"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
11452fun! s:ComposePath(base,subdir)
11453"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
11454
11455  if has("amiga")
11456"   call Decho("amiga",'~'.expand("<slnum>"))
11457   let ec = a:base[s:Strlen(a:base)-1]
11458   if ec != '/' && ec != ':'
11459    let ret = a:base."/" . a:subdir
11460   else
11461    let ret = a:base.a:subdir
11462   endif
11463
11464   " COMBAK: test on windows with changing to root directory: :e C:/
11465  elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11466"   call Decho("windows",'~'.expand("<slnum>"))
11467   let ret= a:subdir
11468
11469  elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11470"   call Decho("windows",'~'.expand("<slnum>"))
11471   if a:base =~ '[/\\]$'
11472    let ret= a:base.a:subdir
11473   else
11474    let ret= a:base.'/'.a:subdir
11475   endif
11476
11477  elseif a:base =~ '^\a\{3,}://'
11478"   call Decho("remote linux/macos",'~'.expand("<slnum>"))
11479   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
11480   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
11481   if a:subdir == '../'
11482    if curpath =~ '[^/]/[^/]\+/$'
11483     let curpath= substitute(curpath,'[^/]\+/$','','')
11484    else
11485     let curpath=""
11486    endif
11487    let ret= urlbase.curpath
11488   else
11489    let ret= urlbase.curpath.a:subdir
11490   endif
11491"   call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
11492"   call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
11493"   call Decho("ret<".ret.">",'~'.expand("<slnum>"))
11494
11495  else
11496"   call Decho("local linux/macos",'~'.expand("<slnum>"))
11497   let ret = substitute(a:base."/".a:subdir,"//","/","g")
11498   if a:base =~ '^//'
11499    " keeping initial '//' for the benefit of network share listing support
11500    let ret= '/'.ret
11501   endif
11502   let ret= simplify(ret)
11503  endif
11504
11505"  call Dret("s:ComposePath ".ret)
11506  return ret
11507endfun
11508
11509" ---------------------------------------------------------------------
11510" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
11511"   Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
11512fun! s:DeleteBookmark(fname)
11513"  call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
11514  call s:MergeBookmarks()
11515
11516  if exists("g:netrw_bookmarklist")
11517   let indx= index(g:netrw_bookmarklist,a:fname)
11518   if indx == -1
11519    let indx= 0
11520    while indx < len(g:netrw_bookmarklist)
11521     if g:netrw_bookmarklist[indx] =~ a:fname
11522      call remove(g:netrw_bookmarklist,indx)
11523      let indx= indx - 1
11524     endif
11525     let indx= indx + 1
11526    endwhile
11527   else
11528    " remove exact match
11529    call remove(g:netrw_bookmarklist,indx)
11530   endif
11531  endif
11532
11533"  call Dret("s:DeleteBookmark")
11534endfun
11535
11536" ---------------------------------------------------------------------
11537" s:FileReadable: o/s independent filereadable {{{2
11538fun! s:FileReadable(fname)
11539"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
11540
11541  if g:netrw_cygwin
11542   let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
11543  else
11544   let ret= filereadable(s:NetrwFile(a:fname))
11545  endif
11546
11547"  call Dret("s:FileReadable ".ret)
11548  return ret
11549endfun
11550
11551" ---------------------------------------------------------------------
11552"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
11553"                 Places correct suffix on end of temporary filename,
11554"                 using the suffix provided with fname
11555fun! s:GetTempfile(fname)
11556"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
11557
11558  if !exists("b:netrw_tmpfile")
11559   " get a brand new temporary filename
11560   let tmpfile= tempname()
11561"   call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
11562
11563   let tmpfile= substitute(tmpfile,'\','/','ge')
11564"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
11565
11566   " sanity check -- does the temporary file's directory exist?
11567   if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
11568"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11569    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
11570"    call Dret("s:GetTempfile getcwd<".getcwd().">")
11571    return ""
11572   endif
11573
11574   " let netrw#NetSource() know about the tmpfile
11575   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
11576"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
11577
11578   " o/s dependencies
11579   if g:netrw_cygwin != 0
11580    let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
11581   elseif has("win32") || has("win95") || has("win64") || has("win16")
11582    if !exists("+shellslash") || !&ssl
11583     let tmpfile = substitute(tmpfile,'/','\','g')
11584    endif
11585   else
11586    let tmpfile = tmpfile
11587   endif
11588   let b:netrw_tmpfile= tmpfile
11589"   call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
11590  else
11591   " re-use temporary filename
11592   let tmpfile= b:netrw_tmpfile
11593"   call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
11594  endif
11595
11596  " use fname's suffix for the temporary file
11597  if a:fname != ""
11598   if a:fname =~ '\.[^./]\+$'
11599"    call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11600    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11601     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11602    elseif a:fname =~ '.txz$'
11603     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11604    else
11605     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11606    endif
11607"    call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11608    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11609"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11610    let tmpfile .= suffix
11611"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11612    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
11613   endif
11614  endif
11615
11616"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11617"  call Dret("s:GetTempfile <".tmpfile.">")
11618  return tmpfile
11619endfun
11620
11621" ---------------------------------------------------------------------
11622" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
11623"               a correct command for use with a system() call
11624fun! s:MakeSshCmd(sshcmd)
11625"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
11626  if s:user == ""
11627   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
11628  else
11629   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
11630  endif
11631  if exists("g:netrw_port") && g:netrw_port != ""
11632   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
11633  elseif exists("s:port") && s:port != ""
11634   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
11635  else
11636   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
11637  endif
11638"  call Dret("s:MakeSshCmd <".sshcmd.">")
11639  return sshcmd
11640endfun
11641
11642" ---------------------------------------------------------------------
11643" s:MakeBookmark: enters a bookmark into Netrw's bookmark system   {{{2
11644fun! s:MakeBookmark(fname)
11645"  call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
11646
11647  if !exists("g:netrw_bookmarklist")
11648   let g:netrw_bookmarklist= []
11649  endif
11650
11651  if index(g:netrw_bookmarklist,a:fname) == -1
11652   " curdir not currently in g:netrw_bookmarklist, so include it
11653   if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11654    call add(g:netrw_bookmarklist,a:fname.'/')
11655   elseif a:fname !~ '/'
11656    call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11657   else
11658    call add(g:netrw_bookmarklist,a:fname)
11659   endif
11660   call sort(g:netrw_bookmarklist)
11661  endif
11662
11663"  call Dret("s:MakeBookmark")
11664endfun
11665
11666" ---------------------------------------------------------------------
11667" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11668fun! s:MergeBookmarks()
11669"  call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
11670  " get bookmarks from .netrwbook file
11671  let savefile= s:NetrwHome()."/.netrwbook"
11672  if filereadable(s:NetrwFile(savefile))
11673"   call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11674   NetrwKeepj call s:NetrwBookHistSave()
11675"   call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11676   NetrwKeepj call delete(savefile)
11677  endif
11678"  call Dret("s:MergeBookmarks")
11679endfun
11680
11681" ---------------------------------------------------------------------
11682" s:NetrwBMShow: {{{2
11683fun! s:NetrwBMShow()
11684"  call Dfunc("s:NetrwBMShow()")
11685  redir => bmshowraw
11686   menu
11687  redir END
11688  let bmshowlist = split(bmshowraw,'\n')
11689  if bmshowlist != []
11690   let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"')
11691   if bmshowfuncs != []
11692    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11693    if bmshowfunc =~# '^call.*BMShow()'
11694     exe "sil! NetrwKeepj ".bmshowfunc
11695    endif
11696   endif
11697  endif
11698"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
11699endfun
11700
11701" ---------------------------------------------------------------------
11702" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
11703fun! s:NetrwCursor()
11704  if !exists("w:netrw_liststyle")
11705   let w:netrw_liststyle= g:netrw_liststyle
11706  endif
11707"  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)
11708
11709  if &ft != "netrw"
11710   " if the current window isn't a netrw directory listing window, then use user cursorline/column
11711   " settings.  Affects when netrw is used to read/write a file using scp/ftp/etc.
11712"   call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
11713   let &l:cursorline   = s:netrw_usercul
11714   let &l:cursorcolumn = s:netrw_usercuc
11715
11716  elseif g:netrw_cursor == 4
11717   " all styles: cursorline, cursorcolumn
11718"   call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
11719   setl cursorline
11720   setl cursorcolumn
11721
11722  elseif g:netrw_cursor == 3
11723   " thin-long-tree: cursorline, user's cursorcolumn
11724   " wide          : cursorline, cursorcolumn
11725   if w:netrw_liststyle == s:WIDELIST
11726"    call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11727    setl cursorline
11728    setl cursorcolumn
11729   else
11730"    call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11731    setl cursorline
11732    let &l:cursorcolumn   = s:netrw_usercuc
11733   endif
11734
11735  elseif g:netrw_cursor == 2
11736   " thin-long-tree: cursorline, user's cursorcolumn
11737   " wide          : cursorline, user's cursorcolumn
11738"   call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11739   let &l:cursorcolumn = s:netrw_usercuc
11740   setl cursorline
11741
11742  elseif g:netrw_cursor == 1
11743   " thin-long-tree: user's cursorline, user's cursorcolumn
11744   " wide          : cursorline,        user's cursorcolumn
11745   let &l:cursorcolumn = s:netrw_usercuc
11746   if w:netrw_liststyle == s:WIDELIST
11747"    call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11748    setl cursorline
11749   else
11750"    call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11751    let &l:cursorline   = s:netrw_usercul
11752   endif
11753
11754  else
11755   " all styles: user's cursorline, user's cursorcolumn
11756"   call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11757   let &l:cursorline   = s:netrw_usercul
11758   let &l:cursorcolumn = s:netrw_usercuc
11759  endif
11760
11761"  call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
11762endfun
11763
11764" ---------------------------------------------------------------------
11765" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11766fun! s:RestoreCursorline()
11767"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
11768  if exists("s:netrw_usercul")
11769   let &l:cursorline   = s:netrw_usercul
11770  endif
11771  if exists("s:netrw_usercuc")
11772   let &l:cursorcolumn = s:netrw_usercuc
11773  endif
11774"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
11775endfun
11776
11777" ---------------------------------------------------------------------
11778" s:NetrwDelete: Deletes a file. {{{2
11779"           Uses Steve Hall's idea to insure that Windows paths stay
11780"           acceptable.  No effect on Unix paths.
11781"  Examples of use:  let result= s:NetrwDelete(path)
11782fun! s:NetrwDelete(path)
11783"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
11784
11785  let path = netrw#WinPath(a:path)
11786  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
11787   if exists("+shellslash")
11788    let sskeep= &shellslash
11789    setl noshellslash
11790    let result      = delete(path)
11791    let &shellslash = sskeep
11792   else
11793"    call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11794    let result= delete(path)
11795   endif
11796  else
11797"   call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11798   let result= delete(path)
11799  endif
11800  if result < 0
11801   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
11802  endif
11803
11804"  call Dret("s:NetrwDelete ".result)
11805  return result
11806endfun
11807
11808" ---------------------------------------------------------------------
11809" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
11810fun! s:NetrwEnew(...)
11811"  call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
11812"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
11813
11814  " grab a function-local-variable copy of buffer variables
11815"  call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
11816  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
11817  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
11818  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
11819  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
11820  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11821  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
11822  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
11823  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
11824  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11825  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11826  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
11827  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
11828  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
11829  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
11830  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
11831  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
11832
11833  NetrwKeepj call s:NetrwOptionsRestore("w:")
11834"  call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>"))
11835  " when tree listing uses file TreeListing... a new buffer is made.
11836  " Want the old buffer to be unlisted.
11837  " COMBAK: this causes a problem, see P43
11838"  setl nobl
11839  let netrw_keepdiff= &l:diff
11840  noswapfile NetrwKeepj keepalt enew!
11841  let &l:diff= netrw_keepdiff
11842"  call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
11843  NetrwKeepj call s:NetrwOptionsSave("w:")
11844
11845  " copy function-local-variables to buffer variable equivalents
11846"  call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
11847  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
11848  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
11849  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
11850  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
11851  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
11852  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
11853  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
11854  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
11855  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11856  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11857  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
11858  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
11859  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
11860  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
11861  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
11862  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
11863
11864  if a:0 > 0
11865   let b:netrw_curdir= a:1
11866   if b:netrw_curdir =~ '/$'
11867    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11868     setl nobl
11869     file NetrwTreeListing
11870     setl nobl bt=nowrite bh=hide
11871     nno <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
11872     nno <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
11873    else
11874     call s:NetrwBufRename(b:netrw_curdir)
11875    endif
11876   endif
11877  endif
11878
11879"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
11880endfun
11881
11882" ---------------------------------------------------------------------
11883" s:NetrwExe: executes a string using "!" {{{2
11884fun! s:NetrwExe(cmd)
11885"  call Dfunc("s:NetrwExe(a:cmd<".a:cmd.">)")
11886  if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin
11887"    call Decho("using win32:",expand("<slnum>"))
11888    let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
11889    set shell& shellcmdflag& shellxquote& shellxescape&
11890    set shellquote& shellpipe& shellredir& shellslash&
11891    exe a:cmd
11892    let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
11893  else
11894"   call Decho("exe ".a:cmd,'~'.expand("<slnum>"))
11895   exe a:cmd
11896  endif
11897  if v:shell_error
11898   call netrw#ErrorMsg(s:WARNING,"shell signalled an error",106)
11899  endif
11900"  call Dret("s:NetrwExe : v:shell_error=".v:shell_error)
11901endfun
11902
11903" ---------------------------------------------------------------------
11904" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
11905fun! s:NetrwInsureWinVars()
11906  if !exists("w:netrw_liststyle")
11907"   call Dfunc("s:NetrwInsureWinVars() win#".winnr())
11908   let curbuf = bufnr("%")
11909   let curwin = winnr()
11910   let iwin   = 1
11911   while iwin <= winnr("$")
11912    exe iwin."wincmd w"
11913    if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
11914     " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
11915     let winvars= w:
11916     break
11917    endif
11918    let iwin= iwin + 1
11919   endwhile
11920   exe "keepalt ".curwin."wincmd w"
11921   if exists("winvars")
11922"    call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
11923    for k in keys(winvars)
11924     let w:{k}= winvars[k]
11925    endfor
11926   endif
11927"   call Dret("s:NetrwInsureWinVars win#".winnr())
11928  endif
11929endfun
11930
11931" ---------------------------------------------------------------------
11932" s:NetrwLcd: handles changing the (local) directory {{{2
11933"   Returns: 0=success
11934"           -1=failed
11935fun! s:NetrwLcd(newdir)
11936"  call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
11937
11938  let err472= 0
11939  try
11940   exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
11941  catch /^Vim\%((\a\+)\)\=:E344/
11942     " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
11943     " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
11944     " 'root' (ie. '\').  The share name may start with either backslashes ('\\Foo') or
11945     " forward slashes ('//Foo'), depending on whether backslashes have been converted to
11946     " forward slashes by earlier code; so check for both.
11947     if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
11948       if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
11949         let dirname = '\'
11950	 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
11951       endif
11952     endif
11953  catch /^Vim\%((\a\+)\)\=:E472/
11954   let err472= 1
11955  endtry
11956
11957  if err472
11958   call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
11959   if exists("w:netrw_prvdir")
11960    let a:newdir= w:netrw_prvdir
11961   else
11962    call s:NetrwOptionsRestore("w:")
11963"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
11964    exe "setl ".g:netrw_bufsettings
11965"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11966    let a:newdir= dirname
11967   endif
11968"   call Dret("s:NetrwBrowse -1 : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
11969   return -1
11970  endif
11971
11972"  call Dret("s:NetrwLcd 0")
11973  return 0
11974endfun
11975
11976" ------------------------------------------------------------------------
11977" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
11978" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
11979fun! s:NetrwSaveWordPosn()
11980"  call Dfunc("NetrwSaveWordPosn()")
11981  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
11982"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
11983endfun
11984
11985" ---------------------------------------------------------------------
11986" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
11987"                       1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
11988fun! s:NetrwHumanReadable(sz)
11989"  call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
11990
11991  if g:netrw_sizestyle == 'h'
11992   if a:sz >= 1000000000
11993    let sz = printf("%.1f",a:sz/1000000000.0)."g"
11994   elseif a:sz >= 10000000
11995    let sz = printf("%d",a:sz/1000000)."m"
11996   elseif a:sz >= 1000000
11997    let sz = printf("%.1f",a:sz/1000000.0)."m"
11998   elseif a:sz >= 10000
11999    let sz = printf("%d",a:sz/1000)."k"
12000   elseif a:sz >= 1000
12001    let sz = printf("%.1f",a:sz/1000.0)."k"
12002   else
12003    let sz= a:sz
12004   endif
12005
12006  elseif g:netrw_sizestyle == 'H'
12007   if a:sz >= 1073741824
12008    let sz = printf("%.1f",a:sz/1073741824.0)."G"
12009   elseif a:sz >= 10485760
12010    let sz = printf("%d",a:sz/1048576)."M"
12011   elseif a:sz >= 1048576
12012    let sz = printf("%.1f",a:sz/1048576.0)."M"
12013   elseif a:sz >= 10240
12014    let sz = printf("%d",a:sz/1024)."K"
12015   elseif a:sz >= 1024
12016    let sz = printf("%.1f",a:sz/1024.0)."K"
12017   else
12018    let sz= a:sz
12019   endif
12020
12021  else
12022   let sz= a:sz
12023  endif
12024
12025"  call Dret("s:NetrwHumanReadable ".sz)
12026  return sz
12027endfun
12028
12029" ---------------------------------------------------------------------
12030" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
12031"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
12032fun! s:NetrwRestoreWordPosn()
12033"  call Dfunc("NetrwRestoreWordPosn()")
12034  sil! call search(s:netrw_saveword,'w')
12035"  call Dret("NetrwRestoreWordPosn")
12036endfun
12037
12038" ---------------------------------------------------------------------
12039" s:RestoreBufVars: {{{2
12040fun! s:RestoreBufVars()
12041"  call Dfunc("s:RestoreBufVars()")
12042
12043  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
12044  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
12045  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
12046  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
12047  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
12048  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
12049
12050"  call Dret("s:RestoreBufVars")
12051endfun
12052
12053" ---------------------------------------------------------------------
12054" s:RemotePathAnalysis: {{{2
12055fun! s:RemotePathAnalysis(dirname)
12056"  call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
12057
12058  "                method   ://    user  @      machine      :port            /path
12059  let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
12060  let s:method  = substitute(a:dirname,dirpat,'\1','')
12061  let s:user    = substitute(a:dirname,dirpat,'\3','')
12062  let s:machine = substitute(a:dirname,dirpat,'\4','')
12063  let s:port    = substitute(a:dirname,dirpat,'\5','')
12064  let s:path    = substitute(a:dirname,dirpat,'\6','')
12065  let s:fname   = substitute(s:path,'^.*/\ze.','','')
12066  if s:machine =~ '@'
12067   let dirpat    = '^\(.*\)@\(.\{-}\)$'
12068   let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')
12069   let s:machine = substitute(s:machine,dirpat,'\2','')
12070  endif
12071
12072"  call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
12073"  call Decho("set up s:user   <".s:user   .">",'~'.expand("<slnum>"))
12074"  call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
12075"  call Decho("set up s:port   <".s:port.">",'~'.expand("<slnum>"))
12076"  call Decho("set up s:path   <".s:path   .">",'~'.expand("<slnum>"))
12077"  call Decho("set up s:fname  <".s:fname  .">",'~'.expand("<slnum>"))
12078
12079"  call Dret("s:RemotePathAnalysis")
12080endfun
12081
12082" ---------------------------------------------------------------------
12083" s:RemoteSystem: runs a command on a remote host using ssh {{{2
12084"                 Returns status
12085" Runs system() on
12086"    [cd REMOTEDIRPATH;] a:cmd
12087" Note that it doesn't do s:ShellEscape(a:cmd)!
12088fun! s:RemoteSystem(cmd)
12089"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
12090  if !executable(g:netrw_ssh_cmd)
12091   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
12092  elseif !exists("b:netrw_curdir")
12093   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
12094  else
12095   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
12096   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
12097   if remotedir != ""
12098    let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
12099   else
12100    let cmd= cmd.' '
12101   endif
12102   let cmd= cmd.a:cmd
12103"   call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
12104   let ret= system(cmd)
12105  endif
12106"  call Dret("s:RemoteSystem ".ret)
12107  return ret
12108endfun
12109
12110" ---------------------------------------------------------------------
12111" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
12112fun! s:RestoreWinVars()
12113"  call Dfunc("s:RestoreWinVars()")
12114  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
12115  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
12116  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
12117  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
12118  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
12119  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
12120  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
12121  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
12122  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
12123  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
12124  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
12125  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
12126  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
12127  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
12128  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
12129  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
12130  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
12131  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
12132"  call Dret("s:RestoreWinVars")
12133endfun
12134
12135" ---------------------------------------------------------------------
12136" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
12137"
12138"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
12139"             is true) and a command, :Rexplore, which call this function.
12140"
12141"             s:netrw_posn is set up by s:NetrwBrowseChgDir()
12142"
12143"             s:rexposn_BUFNR used to save/restore cursor position
12144fun! s:NetrwRexplore(islocal,dirname)
12145  if exists("s:netrwdrag")
12146   return
12147  endif
12148"  call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
12149"  call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
12150"  call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
12151
12152  if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
12153   " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
12154"   call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
12155   exe "NetrwKeepj e ".w:netrw_rexfile
12156   unlet w:netrw_rexfile
12157"   call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%").">  (ft=".&ft.")")
12158   return
12159"  else " Decho
12160"   call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
12161"   call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
12162  endif
12163
12164  " ---------------------------
12165  " :Rex issued while in a file
12166  " ---------------------------
12167
12168  " record current file so :Rex can return to it from netrw
12169  let w:netrw_rexfile= expand("%")
12170"  call Decho("set w:netrw_rexfile<".w:netrw_rexfile.">  (win#".winnr().")",'~'.expand("<slnum>"))
12171
12172  if !exists("w:netrw_rexlocal")
12173"   call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
12174   return
12175  endif
12176"  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>"))
12177  if w:netrw_rexlocal
12178   NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
12179  else
12180   NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
12181  endif
12182  if exists("s:initbeval")
12183   setl beval
12184  endif
12185  if exists("s:rexposn_".bufnr("%"))
12186"   call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
12187   " restore position in directory listing
12188"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
12189   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
12190   if exists("s:rexposn_".bufnr('%'))
12191    unlet s:rexposn_{bufnr('%')}
12192   endif
12193  else
12194"   call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
12195  endif
12196
12197  if has("syntax") && exists("g:syntax_on") && g:syntax_on
12198   if exists("s:explore_match")
12199    exe "2match netrwMarkFile /".s:explore_match."/"
12200   endif
12201  endif
12202
12203"  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>"))
12204"  call Dret("s:NetrwRexplore : ft=".&ft)
12205endfun
12206
12207" ---------------------------------------------------------------------
12208" s:SaveBufVars: save selected b: variables to s: variables {{{2
12209"                use s:RestoreBufVars() to restore b: variables from s: variables
12210fun! s:SaveBufVars()
12211"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
12212
12213  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
12214  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
12215  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
12216  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
12217  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
12218  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
12219
12220"  call Dret("s:SaveBufVars")
12221endfun
12222
12223" ---------------------------------------------------------------------
12224" s:SavePosn: saves position associated with current buffer into a dictionary {{{2
12225fun! s:SavePosn(posndict)
12226"  call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12227
12228  if !exists("a:posndict[bufnr('%')]")
12229   let a:posndict[bufnr("%")]= []
12230  endif
12231"  call Decho("before push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12232  call add(a:posndict[bufnr("%")],winsaveview())
12233"  call Decho("after  push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12234
12235"  call Dret("s:SavePosn posndict")
12236  return a:posndict
12237endfun
12238
12239" ---------------------------------------------------------------------
12240" s:RestorePosn: restores position associated with current buffer using dictionary {{{2
12241fun! s:RestorePosn(posndict)
12242"  call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12243  if exists("a:posndict")
12244   if has_key(a:posndict,bufnr("%"))
12245"    call Decho("before pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12246    let posnlen= len(a:posndict[bufnr("%")])
12247    if posnlen > 0
12248     let posnlen= posnlen - 1
12249"     call Decho("restoring posn posndict[".bufnr("%")."][".posnlen."]=".string(a:posndict[bufnr("%")][posnlen]),'~'.expand("<slnum>"))
12250     call winrestview(a:posndict[bufnr("%")][posnlen])
12251     call remove(a:posndict[bufnr("%")],posnlen)
12252"     call Decho("after  pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12253    endif
12254   endif
12255  endif
12256"  call Dret("s:RestorePosn")
12257endfun
12258
12259" ---------------------------------------------------------------------
12260" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
12261fun! s:SaveWinVars()
12262"  call Dfunc("s:SaveWinVars() win#".winnr())
12263  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
12264  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
12265  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
12266  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
12267  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
12268  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
12269  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
12270  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
12271  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
12272  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
12273  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
12274  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
12275  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
12276  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
12277  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
12278  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
12279  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
12280  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
12281"  call Dret("s:SaveWinVars")
12282endfun
12283
12284" ---------------------------------------------------------------------
12285" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
12286"   To allow separate windows to have their own activities, such as
12287"   Explore **/pattern, several variables have been made window-oriented.
12288"   However, when the user splits a browser window (ex: ctrl-w s), these
12289"   variables are not inherited by the new window.  SetBufWinVars() and
12290"   UseBufWinVars() get around that.
12291fun! s:SetBufWinVars()
12292"  call Dfunc("s:SetBufWinVars() win#".winnr())
12293  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
12294  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
12295  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
12296  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
12297  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
12298  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
12299  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
12300  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
12301  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
12302  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
12303"  call Dret("s:SetBufWinVars")
12304endfun
12305
12306" ---------------------------------------------------------------------
12307" s:SetRexDir: set directory for :Rexplore {{{2
12308fun! s:SetRexDir(islocal,dirname)
12309"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
12310  let w:netrw_rexdir         = a:dirname
12311  let w:netrw_rexlocal       = a:islocal
12312  let s:rexposn_{bufnr("%")} = winsaveview()
12313"  call Decho("setting w:netrw_rexdir  =".w:netrw_rexdir,'~'.expand("<slnum>"))
12314"  call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>"))
12315"  call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
12316"  call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>"))
12317"  call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
12318endfun
12319
12320" ---------------------------------------------------------------------
12321" s:ShowLink: used to modify thin and tree listings to show links {{{2
12322fun! s:ShowLink()
12323" "  call Dfunc("s:ShowLink()")
12324" "  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
12325" "  call Decho(printf("line#%4d: %s",line("."),getline(".")),'~'.expand("<slnum>"))
12326  if exists("b:netrw_curdir")
12327   norm! $?\a
12328   let fname   = b:netrw_curdir.'/'.s:NetrwGetWord()
12329   let resname = resolve(fname)
12330" "   call Decho("fname         <".fname.">",'~'.expand("<slnum>"))
12331" "   call Decho("resname       <".resname.">",'~'.expand("<slnum>"))
12332" "   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
12333   if resname =~ '^\M'.b:netrw_curdir.'/'
12334    let dirlen  = strlen(b:netrw_curdir)
12335    let resname = strpart(resname,dirlen+1)
12336" "    call Decho("resname<".resname.">  (b:netrw_curdir elided)",'~'.expand("<slnum>"))
12337   endif
12338   let modline = getline(".")."\t --> ".resname
12339" "   call Decho("fname  <".fname.">",'~'.expand("<slnum>"))
12340" "   call Decho("modline<".modline.">",'~'.expand("<slnum>"))
12341   setl noro ma
12342   call setline(".",modline)
12343   setl ro noma nomod
12344  endif
12345" "  call Dret("s:ShowLink".((exists("fname")? ' : '.fname : 'n/a')))
12346endfun
12347
12348" ---------------------------------------------------------------------
12349" s:ShowStyle: {{{2
12350fun! s:ShowStyle()
12351  if !exists("w:netrw_liststyle")
12352   let liststyle= g:netrw_liststyle
12353  else
12354   let liststyle= w:netrw_liststyle
12355  endif
12356  if     liststyle == s:THINLIST
12357   return s:THINLIST.":thin"
12358  elseif liststyle == s:LONGLIST
12359   return s:LONGLIST.":long"
12360  elseif liststyle == s:WIDELIST
12361   return s:WIDELIST.":wide"
12362  elseif liststyle == s:TREELIST
12363   return s:TREELIST.":tree"
12364  else
12365   return 'n/a'
12366  endif
12367endfun
12368
12369" ---------------------------------------------------------------------
12370" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
12371"           Solution from Nicolai Weibull, vim docs (:help strlen()),
12372"           Tony Mechelynck, and my own invention.
12373fun! s:Strlen(x)
12374"  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
12375
12376  if v:version >= 703 && exists("*strdisplaywidth")
12377   let ret= strdisplaywidth(a:x)
12378
12379  elseif type(g:Align_xstrlen) == 1
12380   " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
12381   exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
12382
12383  elseif g:Align_xstrlen == 1
12384   " number of codepoints (Latin a + combining circumflex is two codepoints)
12385   " (comment from TM, solution from NW)
12386   let ret= strlen(substitute(a:x,'.','c','g'))
12387
12388  elseif g:Align_xstrlen == 2
12389   " number of spacing codepoints (Latin a + combining circumflex is one spacing
12390   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
12391   " (comment from TM, solution from TM)
12392   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
12393
12394  elseif g:Align_xstrlen == 3
12395   " virtual length (counting, for instance, tabs as anything between 1 and
12396   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
12397   " preceded by lam, one otherwise, etc.)
12398   " (comment from TM, solution from me)
12399   let modkeep= &l:mod
12400   exe "norm! o\<esc>"
12401   call setline(line("."),a:x)
12402   let ret= virtcol("$") - 1
12403   d
12404   NetrwKeepj norm! k
12405   let &l:mod= modkeep
12406
12407  else
12408   " at least give a decent default
12409    let ret= strlen(a:x)
12410  endif
12411"  "" call Dret("s:Strlen ".ret)
12412  return ret
12413endfun
12414
12415" ---------------------------------------------------------------------
12416" s:ShellEscape: shellescape(), or special windows handling {{{2
12417fun! s:ShellEscape(s, ...)
12418  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
12419    return printf('"%s"', substitute(a:s, '"', '""', 'g'))
12420  endif
12421  let f = a:0 > 0 ? a:1 : 0
12422  return shellescape(a:s, f)
12423endfun
12424
12425" ---------------------------------------------------------------------
12426" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
12427fun! s:TreeListMove(dir)
12428"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
12429  let curline      = getline('.')
12430  let prvline      = (line(".") > 1)?         getline(line(".")-1) : ''
12431  let nxtline      = (line(".") < line("$"))? getline(line(".")+1) : ''
12432  let curindent    = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
12433  let indentm1     = substitute(curindent,'^'.s:treedepthstring,'','')
12434  let treedepthchr = substitute(s:treedepthstring,' ','','g')
12435  let stopline     = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
12436"  call Decho("prvline  <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
12437"  call Decho("curline  <".curline."> #".line(".")    , '~'.expand("<slnum>"))
12438"  call Decho("nxtline  <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
12439"  call Decho("curindent<".curindent.">"              , '~'.expand("<slnum>"))
12440"  call Decho("indentm1 <".indentm1.">"               , '~'.expand("<slnum>"))
12441  "  COMBAK : need to handle when on a directory
12442  "  COMBAK : need to handle ]] and ][.  In general, needs work!!!
12443  if curline !~ '/$'
12444   if     a:dir == '[[' && prvline != ''
12445    NetrwKeepj norm! 0
12446    let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
12447"    call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
12448   elseif a:dir == '[]' && nxtline != ''
12449    NetrwKeepj norm! 0
12450"    call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>"))
12451    let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
12452    if nl != 0
12453     NetrwKeepj norm! k
12454    else
12455     NetrwKeepj norm! G
12456    endif
12457"    call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
12458   endif
12459  endif
12460
12461"  call Dret("s:TreeListMove")
12462endfun
12463
12464" ---------------------------------------------------------------------
12465" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
12466"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
12467"                      can't be called except via emenu.  But due to locale, that menu line may not be called
12468"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
12469fun! s:UpdateBuffersMenu()
12470"  call Dfunc("s:UpdateBuffersMenu()")
12471  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
12472   try
12473    sil emenu Buffers.Refresh\ menu
12474   catch /^Vim\%((\a\+)\)\=:E/
12475    let v:errmsg= ""
12476    sil NetrwKeepj call s:NetrwBMShow()
12477   endtry
12478  endif
12479"  call Dret("s:UpdateBuffersMenu")
12480endfun
12481
12482" ---------------------------------------------------------------------
12483" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
12484"              Matching function to s:SetBufWinVars()
12485fun! s:UseBufWinVars()
12486"  call Dfunc("s:UseBufWinVars()")
12487  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
12488  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
12489  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
12490  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
12491  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
12492  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
12493  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
12494  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
12495  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
12496  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
12497"  call Dret("s:UseBufWinVars")
12498endfun
12499
12500" ---------------------------------------------------------------------
12501" s:UserMaps: supports user-defined UserMaps {{{2
12502"               * calls a user-supplied funcref(islocal,curdir)
12503"               * interprets result
12504"             See netrw#UserMaps()
12505fun! s:UserMaps(islocal,funcname)
12506"  call Dfunc("s:UserMaps(islocal=".a:islocal.",funcname<".a:funcname.">)")
12507
12508  if !exists("b:netrw_curdir")
12509   let b:netrw_curdir= getcwd()
12510  endif
12511  let Funcref = function(a:funcname)
12512  let result  = Funcref(a:islocal)
12513
12514  if     type(result) == 1
12515   " if result from user's funcref is a string...
12516"   call Decho("result string from user funcref<".result.">",'~'.expand("<slnum>"))
12517   if result == "refresh"
12518"    call Decho("refreshing display",'~'.expand("<slnum>"))
12519    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12520   elseif result != ""
12521"    call Decho("executing result<".result.">",'~'.expand("<slnum>"))
12522    exe result
12523   endif
12524
12525  elseif type(result) == 3
12526   " if result from user's funcref is a List...
12527"   call Decho("result List from user funcref<".string(result).">",'~'.expand("<slnum>"))
12528   for action in result
12529    if action == "refresh"
12530"     call Decho("refreshing display",'~'.expand("<slnum>"))
12531     call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12532    elseif action != ""
12533"     call Decho("executing action<".action.">",'~'.expand("<slnum>"))
12534     exe action
12535    endif
12536   endfor
12537  endif
12538
12539"  call Dret("s:UserMaps")
12540endfun
12541
12542" ==========================
12543" Settings Restoration: {{{1
12544" ==========================
12545let &cpo= s:keepcpo
12546unlet s:keepcpo
12547
12548" ===============
12549" Modelines: {{{1
12550" ===============
12551" vim:ts=8 fdm=marker
12552