xref: /vim-8.2.3635/runtime/autoload/netrw.vim (revision cf2d8dee)
1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		Feb 16, 2016
4" Version:	155	ASTRO-ONLY
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"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore(,'~'.expand("<slnum>"))
17"
18"  But be doers of the Word, and not only hearers, deluding your own selves {{{1
19"  (James 1:22 RSV)
20" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
21" Load Once: {{{1
22if &cp || exists("g:loaded_netrw")
23  finish
24endif
25" netrw requires vim having patch 213; netrw will benefit from vim's having patch#656, too
26if v:version < 704 || !has("patch213")
27 if !exists("s:needpatch213")
28  unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch 213"
29 endif
30 let s:needpatch213= 1
31 finish
32endif
33let g:loaded_netrw = "v155"
34if !exists("s:NOTE")
35 let s:NOTE    = 0
36 let s:WARNING = 1
37 let s:ERROR   = 2
38endif
39
40let s:keepcpo= &cpo
41setl cpo&vim
42"let g:dechofuncname= 1
43"DechoRemOn
44"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw,'~'.expand("<slnum>"))
45
46" ======================
47"  Netrw Variables: {{{1
48" ======================
49
50" ---------------------------------------------------------------------
51" netrw#ErrorMsg: {{{2
52"   0=note     = s:NOTE
53"   1=warning  = s:WARNING
54"   2=error    = s:ERROR
55"   Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number)
56"          netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number)
57"          (this function can optionally take a list of messages)
58"  Jan 19, 2016 : max errnum currently is 103
59fun! netrw#ErrorMsg(level,msg,errnum)
60"  call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
61
62  if a:level < g:netrw_errorlvl
63"   call Dret("netrw#ErrorMsg : suppressing level=".a:level." since g:netrw_errorlvl=".g:netrw_errorlvl)
64   return
65  endif
66
67  if a:level == 1
68   let level= "**warning** (netrw) "
69  elseif a:level == 2
70   let level= "**error** (netrw) "
71  else
72   let level= "**note** (netrw) "
73  endif
74"  call Decho("level=".level,'~'.expand("<slnum>"))
75
76  if g:netrw_use_errorwindow
77   " (default) netrw creates a one-line window to show error/warning
78   " messages (reliably displayed)
79
80   " record current window number
81   let s:winBeforeErr= winnr()
82"   call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>"))
83
84   " getting messages out reliably is just plain difficult!
85   " This attempt splits the current window, creating a one line window.
86   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
87"    call Decho("write to NetrwMessage buffer",'~'.expand("<slnum>"))
88    exe bufwinnr("NetrwMessage")."wincmd w"
89"    call Decho("setl ma noro",'~'.expand("<slnum>"))
90    setl ma noro
91    if type(a:msg) == 3
92     for msg in a:msg
93      NetrwKeepj call setline(line("$")+1,level.msg)
94     endfor
95    else
96     NetrwKeepj call setline(line("$")+1,level.a:msg)
97    endif
98    NetrwKeepj $
99   else
100"    call Decho("create a NetrwMessage buffer window",'~'.expand("<slnum>"))
101    bo 1split
102    sil! call s:NetrwEnew()
103    sil! NetrwKeepj call s:NetrwSafeOptions()
104    setl bt=nofile
105    NetrwKeepj file NetrwMessage
106"    call Decho("setl ma noro",'~'.expand("<slnum>"))
107    setl ma noro
108    if type(a:msg) == 3
109     for msg in a:msg
110      NetrwKeepj call setline(line("$")+1,level.msg)
111     endfor
112    else
113     NetrwKeepj call setline(line("$"),level.a:msg)
114    endif
115    NetrwKeepj $
116   endif
117"   call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr(),'~'.expand("<slnum>"))
118   if &fo !~ '[ta]'
119    syn clear
120    syn match netrwMesgNote	"^\*\*note\*\*"
121    syn match netrwMesgWarning	"^\*\*warning\*\*"
122    syn match netrwMesgError	"^\*\*error\*\*"
123    hi link netrwMesgWarning WarningMsg
124    hi link netrwMesgError   Error
125   endif
126"   call Decho("setl noma ro bh=wipe",'~'.expand("<slnum>"))
127   setl ro nomod noma bh=wipe
128
129  else
130   " (optional) netrw will show messages using echomsg.  Even if the
131   " message doesn't appear, at least it'll be recallable via :messages
132"   redraw!
133   if a:level == s:WARNING
134    echohl WarningMsg
135   elseif a:level == s:ERROR
136    echohl Error
137   endif
138
139   if type(a:msg) == 3
140     for msg in a:msg
141      unsilent echomsg level.msg
142     endfor
143   else
144    unsilent echomsg level.a:msg
145   endif
146
147"   call Decho("echomsg ***netrw*** ".a:msg,'~'.expand("<slnum>"))
148   echohl None
149  endif
150
151"  call Dret("netrw#ErrorMsg")
152endfun
153
154" ---------------------------------------------------------------------
155" s:NetrwInit: initializes variables if they haven't been defined {{{2
156"            Loosely,  varname = value.
157fun s:NetrwInit(varname,value)
158" call Decho("varname<".a:varname."> value=".a:value,'~'.expand("<slnum>"))
159  if !exists(a:varname)
160   if type(a:value) == 0
161    exe "let ".a:varname."=".a:value
162   elseif type(a:value) == 1 && a:value =~ '^[{[]'
163    exe "let ".a:varname."=".a:value
164   elseif type(a:value) == 1
165    exe "let ".a:varname."="."'".a:value."'"
166   else
167    exe "let ".a:varname."=".a:value
168   endif
169  endif
170endfun
171
172" ---------------------------------------------------------------------
173"  Netrw Constants: {{{2
174call s:NetrwInit("g:netrw_dirhist_cnt",0)
175if !exists("s:LONGLIST")
176 call s:NetrwInit("s:THINLIST",0)
177 call s:NetrwInit("s:LONGLIST",1)
178 call s:NetrwInit("s:WIDELIST",2)
179 call s:NetrwInit("s:TREELIST",3)
180 call s:NetrwInit("s:MAXLIST" ,4)
181endif
182
183" ---------------------------------------------------------------------
184" Default values for netrw's global protocol variables {{{2
185call s:NetrwInit("g:netrw_use_errorwindow",1)
186
187if !exists("g:netrw_dav_cmd")
188 if executable("cadaver")
189  let g:netrw_dav_cmd	= "cadaver"
190 elseif executable("curl")
191  let g:netrw_dav_cmd	= "curl"
192 else
193  let g:netrw_dav_cmd   = ""
194 endif
195endif
196if !exists("g:netrw_fetch_cmd")
197 if executable("fetch")
198  let g:netrw_fetch_cmd	= "fetch -o"
199 else
200  let g:netrw_fetch_cmd	= ""
201 endif
202endif
203if !exists("g:netrw_file_cmd")
204 if executable("elinks")
205  call s:NetrwInit("g:netrw_file_cmd","elinks")
206 elseif executable("links")
207  call s:NetrwInit("g:netrw_file_cmd","links")
208 endif
209endif
210if !exists("g:netrw_ftp_cmd")
211  let g:netrw_ftp_cmd	= "ftp"
212endif
213let s:netrw_ftp_cmd= g:netrw_ftp_cmd
214if !exists("g:netrw_ftp_options")
215 let g:netrw_ftp_options= "-i -n"
216endif
217if !exists("g:netrw_http_cmd")
218 if executable("elinks")
219  let g:netrw_http_cmd = "elinks"
220  call s:NetrwInit("g:netrw_http_xcmd","-source >")
221 elseif executable("links")
222  let g:netrw_http_cmd = "links"
223  call s:NetrwInit("g:netrw_http_xcmd","-source >")
224 elseif executable("curl")
225  let g:netrw_http_cmd	= "curl"
226  call s:NetrwInit("g:netrw_http_xcmd","-o")
227 elseif executable("wget")
228  let g:netrw_http_cmd	= "wget"
229  call s:NetrwInit("g:netrw_http_xcmd","-q -O")
230 elseif executable("fetch")
231  let g:netrw_http_cmd	= "fetch"
232  call s:NetrwInit("g:netrw_http_xcmd","-o")
233 else
234  let g:netrw_http_cmd	= ""
235 endif
236endif
237call s:NetrwInit("g:netrw_http_put_cmd","curl -T")
238call s:NetrwInit("g:netrw_keepj","keepj")
239call s:NetrwInit("g:netrw_rcp_cmd"  , "rcp")
240call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
241if !exists("g:netrw_scp_cmd")
242 if executable("scp")
243  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
244 elseif executable("pscp")
245  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable('c:\private.ppk')
246   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -i c:\private.ppk')
247  else
248   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
249  endif
250 else
251  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
252 endif
253endif
254
255call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
256call s:NetrwInit("g:netrw_ssh_cmd"  , "ssh")
257
258if (has("win32") || has("win95") || has("win64") || has("win16"))
259  \ && exists("g:netrw_use_nt_rcp")
260  \ && g:netrw_use_nt_rcp
261  \ && executable( $SystemRoot .'/system32/rcp.exe')
262 let s:netrw_has_nt_rcp = 1
263 let s:netrw_rcpmode    = '-b'
264else
265 let s:netrw_has_nt_rcp = 0
266 let s:netrw_rcpmode    = ''
267endif
268
269" ---------------------------------------------------------------------
270" Default values for netrw's global variables {{{2
271" Cygwin Detection ------- {{{3
272if !exists("g:netrw_cygwin")
273 if has("win32") || has("win95") || has("win64") || has("win16")
274  if  has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
275   let g:netrw_cygwin= 1
276  else
277   let g:netrw_cygwin= 0
278  endif
279 else
280  let g:netrw_cygwin= 0
281 endif
282endif
283" Default values - a-c ---------- {{{3
284call s:NetrwInit("g:netrw_alto"        , &sb)
285call s:NetrwInit("g:netrw_altv"        , &spr)
286call s:NetrwInit("g:netrw_banner"      , 1)
287call s:NetrwInit("g:netrw_browse_split", 0)
288call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro nornu")
289call s:NetrwInit("g:netrw_chgwin"      , -1)
290call s:NetrwInit("g:netrw_compress"    , "gzip")
291call s:NetrwInit("g:netrw_ctags"       , "ctags")
292if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
293 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
294 let g:netrw_cursor= g:netrw_cursorline
295endif
296call s:NetrwInit("g:netrw_cursor"      , 2)
297let s:netrw_usercul = &cursorline
298let s:netrw_usercuc = &cursorcolumn
299call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
300" Default values - d-g ---------- {{{3
301call s:NetrwInit("s:didstarstar",0)
302call s:NetrwInit("g:netrw_dirhist_cnt"      , 0)
303call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }')
304call s:NetrwInit("g:netrw_dirhistmax"       , 10)
305call s:NetrwInit("g:netrw_errorlvl"  , s:NOTE)
306call s:NetrwInit("g:netrw_fastbrowse"       , 1)
307call s:NetrwInit("g:netrw_ftp_browse_reject", '^total\s\+\d\+$\|^Trying\s\+\d\+.*$\|^KERBEROS_V\d rejected\|^Security extensions not\|No such file\|: connect to address [0-9a-fA-F:]*: No route to host$')
308if !exists("g:netrw_ftp_list_cmd")
309 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
310  let g:netrw_ftp_list_cmd     = "ls -lF"
311  let g:netrw_ftp_timelist_cmd = "ls -tlF"
312  let g:netrw_ftp_sizelist_cmd = "ls -slF"
313 else
314  let g:netrw_ftp_list_cmd     = "dir"
315  let g:netrw_ftp_timelist_cmd = "dir"
316  let g:netrw_ftp_sizelist_cmd = "dir"
317 endif
318endif
319call s:NetrwInit("g:netrw_ftpmode",'binary')
320" Default values - h-lh ---------- {{{3
321call s:NetrwInit("g:netrw_hide",1)
322if !exists("g:netrw_ignorenetrc")
323 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
324  let g:netrw_ignorenetrc= 1
325 else
326  let g:netrw_ignorenetrc= 0
327 endif
328endif
329call s:NetrwInit("g:netrw_keepdir",1)
330if !exists("g:netrw_list_cmd")
331 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
332  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
333   " provide a pscp-based listing command
334   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
335  endif
336  if exists("g:netrw_list_cmd_options")
337   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
338  else
339   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
340  endif
341 elseif executable(g:netrw_ssh_cmd)
342  " provide a scp-based default listing command
343  if exists("g:netrw_list_cmd_options")
344   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
345  else
346   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
347  endif
348 else
349"  call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
350  let g:netrw_list_cmd= ""
351 endif
352endif
353call s:NetrwInit("g:netrw_list_hide","")
354" Default values - lh-lz ---------- {{{3
355if exists("g:netrw_local_copycmd")
356 let g:netrw_localcopycmd= g:netrw_local_copycmd
357 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_copycmd is deprecated in favor of g:netrw_localcopycmd",84)
358endif
359if !exists("g:netrw_localcmdshell")
360 let g:netrw_localcmdshell= ""
361endif
362if !exists("g:netrw_localcopycmd")
363 if has("win32") || has("win95") || has("win64") || has("win16")
364  if g:netrw_cygwin
365   let g:netrw_localcopycmd= "cp"
366  else
367   let g:netrw_localcopycmd= expand("$COMSPEC")." /c copy"
368  endif
369 elseif has("unix") || has("macunix")
370  let g:netrw_localcopycmd= "cp"
371 else
372  let g:netrw_localcopycmd= ""
373 endif
374endif
375if !exists("g:netrw_localcopydircmd")
376 if has("win32") || has("win95") || has("win64") || has("win16")
377  if g:netrw_cygwin
378   let g:netrw_localcopydircmd= "cp -R"
379  else
380   let g:netrw_localcopycmd= expand("$COMSPEC")." /c xcopy /e /c /h /i /k"
381  endif
382 elseif has("unix") || has("macunix")
383  let g:netrw_localcopydircmd= "cp -R"
384 else
385  let g:netrw_localcopycmd= ""
386 endif
387endif
388if exists("g:netrw_local_mkdir")
389 let g:netrw_localmkdir= g:netrw_local_mkdir
390 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
391endif
392if has("win32") || has("win95") || has("win64") || has("win16")
393  if g:netrw_cygwin
394   call s:NetrwInit("g:netrw_localmkdir","mkdir")
395  else
396   let g:netrw_localmkdir= expand("$COMSPEC")." /c mkdir"
397  endif
398else
399 call s:NetrwInit("g:netrw_localmkdir","mkdir")
400endif
401call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
402if exists("g:netrw_local_movecmd")
403 let g:netrw_localmovecmd= g:netrw_local_movecmd
404 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
405endif
406if !exists("g:netrw_localmovecmd")
407 if has("win32") || has("win95") || has("win64") || has("win16")
408  if g:netrw_cygwin
409   let g:netrw_localmovecmd= "mv"
410  else
411   let g:netrw_localmovecmd= expand("$COMSPEC")." /c move"
412  endif
413 elseif has("unix") || has("macunix")
414  let g:netrw_localmovecmd= "mv"
415 else
416  let g:netrw_localmovecmd= ""
417 endif
418endif
419if v:version < 704 || !has("patch1109")
420 if exists("g:netrw_local_rmdir")
421  let g:netrw_localrmdir= g:netrw_local_rmdir
422  call netrw#ErrorMsg(s:NOTE,"g:netrw_local_rmdir is deprecated in favor of g:netrw_localrmdir",86)
423 endif
424 if has("win32") || has("win95") || has("win64") || has("win16")
425   if g:netrw_cygwin
426    call s:NetrwInit("g:netrw_localrmdir","rmdir")
427   else
428    let g:netrw_localrmdir= expand("$COMSPEC")." /c rmdir"
429   endif
430 else
431  call s:NetrwInit("g:netrw_localrmdir","rmdir")
432 endif
433endif
434call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
435" sanity checks
436if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
437 let g:netrw_liststyle= s:THINLIST
438endif
439if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
440 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
441endif
442" Default values - m-r ---------- {{{3
443call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
444call s:NetrwInit("g:netrw_maxfilenamelen", 32)
445call s:NetrwInit("g:netrw_menu"          , 1)
446call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
447call s:NetrwInit("g:netrw_mousemaps"     , (exists("+mouse") && &mouse =~ '[anh]'))
448call s:NetrwInit("g:netrw_retmap"        , 0)
449if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
450 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
451elseif has("win32") || has("win95") || has("win64") || has("win16")
452 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
453else
454 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
455endif
456call s:NetrwInit("g:netrw_preview"       , 0)
457call s:NetrwInit("g:netrw_scpport"       , "-P")
458call s:NetrwInit("g:netrw_servername"    , "NETRWSERVER")
459call s:NetrwInit("g:netrw_sshport"       , "-p")
460call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
461call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
462call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
463call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
464" Default values - q-s ---------- {{{3
465call s:NetrwInit("g:netrw_quickhelp",0)
466let s:QuickHelp= ["-:go up dir  D:delete  R:rename  s:sort-by  x:special",
467   \              "(create new)  %:file  d:directory",
468   \              "(windows split&open) o:horz  v:vert  p:preview",
469   \              "i:style  qf:file info  O:obtain  r:reverse",
470   \              "(marks)  mf:mark file  mt:set target  mm:move  mc:copy",
471   \              "(bookmarks)  mb:make  mB:delete  qb:list  gb:go to",
472   \              "(history)  qb:list  u:go up  U:go down",
473   \              "(targets)  mt:target Tb:use bookmark  Th:use history"]
474" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
475call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
476if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
477 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
478else
479 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
480endif
481call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
482call s:NetrwInit("g:netrw_sort_options"  , "")
483call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
484if !exists("g:netrw_sort_sequence")
485 if has("unix")
486  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
487 else
488  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
489 endif
490endif
491call s:NetrwInit("g:netrw_special_syntax"   , 0)
492call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
493call s:NetrwInit("g:netrw_use_noswf"        , 1)
494call s:NetrwInit("g:netrw_sizestyle"        ,"b")
495" Default values - t-w ---------- {{{3
496call s:NetrwInit("g:netrw_timefmt","%c")
497if !exists("g:netrw_xstrlen")
498 if exists("g:Align_xstrlen")
499  let g:netrw_xstrlen= g:Align_xstrlen
500 elseif exists("g:drawit_xstrlen")
501  let g:netrw_xstrlen= g:drawit_xstrlen
502 elseif &enc == "latin1" || !has("multi_byte")
503  let g:netrw_xstrlen= 0
504 else
505  let g:netrw_xstrlen= 1
506 endif
507endif
508call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
509call s:NetrwInit("g:netrw_win95ftp",1)
510call s:NetrwInit("g:netrw_winsize",50)
511call s:NetrwInit("g:netrw_wiw",1)
512if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
513" ---------------------------------------------------------------------
514" Default values for netrw's script variables: {{{2
515call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
516if has("win32") || has("win95") || has("win64") || has("win16")
517 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
518else
519 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
520endif
521call s:NetrwInit("g:netrw_menu_escape",'.&? \')
522call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
523call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
524if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
525 let s:treedepthstring= "│ "
526else
527 let s:treedepthstring= "| "
528endif
529
530" BufEnter event ignored by decho when following variable is true
531"  Has a side effect that doau BufReadPost doesn't work, so
532"  files read by network transfer aren't appropriately highlighted.
533"let g:decho_bufenter = 1	"Decho
534
535" ======================
536"  Netrw Initialization: {{{1
537" ======================
538if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
539" call Decho("installed beval events",'~'.expand("<slnum>"))
540 let &l:bexpr = "netrw#BalloonHelp()"
541 au FileType netrw	setl beval
542 au WinLeave *		if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
543 au VimEnter * 		let s:initbeval= &beval
544"else " Decho
545" if v:version < 700           | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>"))     | endif
546" if !has("balloon_eval")      | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>"))        | endif
547" if exists("s:initbeval")     | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>"))                | endif
548" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>"))            | endif
549" if !has("syntax")            | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
550" if exists("g:syntax_on")     | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>"))                | endif
551endif
552au WinEnter *	if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
553
554if g:netrw_keepj =~ "keepj"
555 com! -nargs=*	NetrwKeepj	keepj <args>
556else
557 let g:netrw_keepj= ""
558 com! -nargs=*	NetrwKeepj	<args>
559endif
560
561" ==============================
562"  Netrw Utility Functions: {{{1
563" ==============================
564
565" ---------------------------------------------------------------------
566" netrw#BalloonHelp: {{{2
567if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
568" call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
569 fun! netrw#BalloonHelp()
570   if &ft != "netrw"
571    return ""
572   endif
573   if !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
574    let mesg= ""
575   elseif     v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
576    let mesg = "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
577   elseif     getline(v:beval_lnum) =~ '^"\s*/'
578    let mesg = "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
579   elseif     v:beval_text == "Sorted" || v:beval_text == "by"
580    let mesg = 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
581   elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
582    let mesg = "S: edit sorting sequence"
583   elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
584    let mesg = "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
585   elseif v:beval_text == "Quick" || v:beval_text == "Help"
586    let mesg = "Help: press <F1>"
587   elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
588    let mesg = "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
589   else
590    let mesg= ""
591   endif
592   return mesg
593 endfun
594"else " Decho
595" if v:version < 700            |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
596" if !has("balloon_eval")       |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>"))       |endif
597" if !has("syntax")             |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>"))                  |endif
598" if !exists("g:syntax_on")     |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>"))                  |endif
599" if  exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>"))           |endif
600endif
601
602" ------------------------------------------------------------------------
603" netrw#Explore: launch the local browser in the directory of the current file {{{2
604"          indx:  == -1: Nexplore
605"                 == -2: Pexplore
606"                 ==  +: this is overloaded:
607"                      * If Nexplore/Pexplore is in use, then this refers to the
608"                        indx'th item in the w:netrw_explore_list[] of items which
609"                        matched the */pattern **/pattern *//pattern **//pattern
610"                      * If Hexplore or Vexplore, then this will override
611"                        g:netrw_winsize to specify the qty of rows or columns the
612"                        newly split window should have.
613"          dosplit==0: the window will be split iff the current file has been modified and hidden not set
614"          dosplit==1: the window will be split before running the local browser
615"          style == 0: Explore     style == 1: Explore!
616"                == 2: Hexplore    style == 3: Hexplore!
617"                == 4: Vexplore    style == 5: Vexplore!
618"                == 6: Texplore
619fun! netrw#Explore(indx,dosplit,style,...)
620"  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)
621"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
622  if !exists("b:netrw_curdir")
623   let b:netrw_curdir= getcwd()
624"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
625  endif
626
627  " record current file for Rexplore's benefit
628  if &ft != "netrw"
629   let w:netrw_rexfile= expand("%:p")
630  endif
631
632  " record current directory
633  let curdir     = simplify(b:netrw_curdir)
634  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
635  if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
636   let curdir= substitute(curdir,'\','/','g')
637  endif
638"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">",'~'.expand("<slnum>"))
639
640  " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
641  " will end up with backslashes here.  Solution: strip off backslashes that precede white space and
642  " try Explore again.
643  if a:0 > 0
644"   call Decho('considering retry: a:1<'.a:1.'>: '.
645     \ ((a:1 =~ "\\\s")?                   'has backslash whitespace' : 'does not have backslash whitespace').', '.
646     \ ((filereadable(s:NetrwFile(a:1)))?  'is readable'              : 'is not readable').', '.
647     \ ((isdirectory(s:NetrwFile(a:1))))?  'is a directory'           : 'is not a directory',
648     \ '~'.expand("<slnum>"))
649   if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
650"    call Decho("re-trying Explore with <".substitute(a:1,'\\\(\s\)','\1','g').">",'~'.expand("<slnum>"))
651    call netrw#Explore(a:indx,a:dosplit,a:style,substitute(a:1,'\\\(\s\)','\1','g'))
652"    call Dret("netrw#Explore : returning from retry")
653    return
654"   else " Decho
655"    call Decho("retry not needed",'~'.expand("<slnum>"))
656   endif
657  endif
658
659  " save registers
660  if has("clipboard")
661   sil! let keepregstar = @*
662   sil! let keepregplus = @+
663  endif
664  sil! let keepregslash= @/
665
666  " if   dosplit
667  " -or- file has been modified AND file not hidden when abandoned
668  " -or- Texplore used
669  if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
670"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified",'~'.expand("<slnum>"))
671   call s:SaveWinVars()
672   let winsz= g:netrw_winsize
673   if a:indx > 0
674    let winsz= a:indx
675   endif
676
677   if a:style == 0      " Explore, Sexplore
678"    call Decho("style=0: Explore or Sexplore",'~'.expand("<slnum>"))
679    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
680    if winsz == 0|let winsz= ""|endif
681    exe "noswapfile ".winsz."wincmd s"
682"    call Decho("exe noswapfile ".winsz."wincmd s",'~'.expand("<slnum>"))
683
684   elseif a:style == 1  "Explore!, Sexplore!
685"    call Decho("style=1: Explore! or Sexplore!",'~'.expand("<slnum>"))
686    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
687    if winsz == 0|let winsz= ""|endif
688    exe "keepalt noswapfile ".winsz."wincmd v"
689"    call Decho("exe keepalt noswapfile ".winsz."wincmd v",'~'.expand("<slnum>"))
690
691   elseif a:style == 2  " Hexplore
692"    call Decho("style=2: Hexplore",'~'.expand("<slnum>"))
693    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
694    if winsz == 0|let winsz= ""|endif
695    exe "keepalt noswapfile bel ".winsz."wincmd s"
696"    call Decho("exe keepalt noswapfile bel ".winsz."wincmd s",'~'.expand("<slnum>"))
697
698   elseif a:style == 3  " Hexplore!
699"    call Decho("style=3: Hexplore!",'~'.expand("<slnum>"))
700    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
701    if winsz == 0|let winsz= ""|endif
702    exe "keepalt noswapfile abo ".winsz."wincmd s"
703"    call Decho("exe keepalt noswapfile abo ".winsz."wincmd s",'~'.expand("<slnum>"))
704
705   elseif a:style == 4  " Vexplore
706"    call Decho("style=4: Vexplore",'~'.expand("<slnum>"))
707    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
708    if winsz == 0|let winsz= ""|endif
709    exe "keepalt noswapfile lefta ".winsz."wincmd v"
710"    call Decho("exe keepalt noswapfile lefta ".winsz."wincmd v",'~'.expand("<slnum>"))
711
712   elseif a:style == 5  " Vexplore!
713"    call Decho("style=5: Vexplore!",'~'.expand("<slnum>"))
714    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
715    if winsz == 0|let winsz= ""|endif
716    exe "keepalt noswapfile rightb ".winsz."wincmd v"
717"    call Decho("exe keepalt noswapfile rightb ".winsz."wincmd v",'~'.expand("<slnum>"))
718
719   elseif a:style == 6  " Texplore
720    call s:SaveBufVars()
721"    call Decho("style  = 6: Texplore",'~'.expand("<slnum>"))
722    exe "keepalt tabnew ".fnameescape(curdir)
723"    call Decho("exe keepalt tabnew ".fnameescape(curdir),'~'.expand("<slnum>"))
724    call s:RestoreBufVars()
725   endif
726   call s:RestoreWinVars()
727"  else " Decho
728"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6",'~'.expand("<slnum>"))
729  endif
730  NetrwKeepj norm! 0
731
732  if a:0 > 0
733"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">",'~'.expand("<slnum>"))
734   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
735"    call Decho("..case a:1<".a:1.">: starts with ~ and unix or cygwin",'~'.expand("<slnum>"))
736    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
737"    call Decho("..using dirname<".dirname.">  (case: ~ && unix||cygwin)",'~'.expand("<slnum>"))
738   elseif a:1 == '.'
739"    call Decho("..case a:1<".a:1.">: matches .",'~'.expand("<slnum>"))
740    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
741    if dirname !~ '/$'
742     let dirname= dirname."/"
743    endif
744"    call Decho("..using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")",'~'.expand("<slnum>"))
745   elseif a:1 =~ '\$'
746"    call Decho("..case a:1<".a:1.">: matches ending $",'~'.expand("<slnum>"))
747    let dirname= simplify(expand(a:1))
748"    call Decho("..using user-specified dirname<".dirname."> with $env-var",'~'.expand("<slnum>"))
749   elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
750"    call Decho("..case a:1<".a:1.">: other, not pattern or filepattern",'~'.expand("<slnum>"))
751    let dirname= simplify(a:1)
752"    call Decho("..using user-specified dirname<".dirname.">",'~'.expand("<slnum>"))
753   else
754"    call Decho("..case a:1: pattern or filepattern",'~'.expand("<slnum>"))
755    let dirname= a:1
756   endif
757  else
758   " clear explore
759"   call Decho("case a:0=".a:0.": clearing Explore list",'~'.expand("<slnum>"))
760   call s:NetrwClearExplore()
761"   call Dret("netrw#Explore : cleared list")
762   return
763  endif
764
765"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
766  if dirname =~ '\.\./\=$'
767   let dirname= simplify(fnamemodify(dirname,':p:h'))
768  elseif dirname =~ '\.\.' || dirname == '.'
769   let dirname= simplify(fnamemodify(dirname,':p'))
770  endif
771"  call Decho("dirname<".dirname.">  (after simplify)",'~'.expand("<slnum>"))
772
773  if dirname =~ '^\*//'
774   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
775"   call Decho("case starpat=1: Explore *//pattern",'~'.expand("<slnum>"))
776   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
777   let starpat= 1
778"   call Decho("..Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
779   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
780
781  elseif dirname =~ '^\*\*//'
782   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
783"   call Decho("case starpat=2: Explore **//pattern",'~'.expand("<slnum>"))
784   let pattern= substitute(dirname,'^\*\*//','','')
785   let starpat= 2
786"   call Decho("..Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
787
788  elseif dirname =~ '/\*\*/'
789   " handle .../**/.../filepat
790"   call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
791   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
792   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
793    let b:netrw_curdir = prefixdir
794   else
795    let b:netrw_curdir= getcwd().'/'.prefixdir
796   endif
797   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
798   let starpat= 4
799"   call Decho("..pwd<".getcwd()."> dirname<".dirname.">",'~'.expand("<slnum>"))
800"   call Decho("..case Explore ../**/../filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
801
802  elseif dirname =~ '^\*/'
803   " case starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
804   let starpat= 3
805"   call Decho("case starpat=3: Explore */filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
806
807  elseif dirname=~ '^\*\*/'
808   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
809   let starpat= 4
810"   call Decho("case starpat=4: Explore **/filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
811
812  else
813   let starpat= 0
814"   call Decho("case starpat=0: default",'~'.expand("<slnum>"))
815  endif
816
817  if starpat == 0 && a:indx >= 0
818   " [Explore Hexplore Vexplore Sexplore] [dirname]
819"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname.">, handles Explore Hexplore Vexplore Sexplore",'~'.expand("<slnum>"))
820   if dirname == ""
821    let dirname= curfiledir
822"    call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>"))
823   endif
824   if dirname =~ '^scp://' || dirname =~ '^ftp://'
825    call netrw#Nread(2,dirname)
826   else
827    if dirname == ""
828     let dirname= getcwd()
829    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
830     " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
831     " depending on whether backslashes have been converted to forward slashes by earlier code).
832     if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
833      let dirname= b:netrw_curdir."/".dirname
834     endif
835    elseif dirname !~ '^/'
836     let dirname= b:netrw_curdir."/".dirname
837    endif
838"    call Decho("..calling LocalBrowseCheck(dirname<".dirname.">)",'~'.expand("<slnum>"))
839    call netrw#LocalBrowseCheck(dirname)
840"    call Decho(" modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
841"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
842   endif
843   if exists("w:netrw_bannercnt")
844    " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
845    " If one wants to return the same place in the netrw window, use :Rex instead.
846    exe w:netrw_bannercnt
847   endif
848
849"   call Decho("curdir<".curdir.">",'~'.expand("<slnum>"))
850   " ---------------------------------------------------------------------
851   " Jan 24, 2013: not sure why the following was present.  See P08-Ingelrest
852"   if has("win32") || has("win95") || has("win64") || has("win16")
853"    NetrwKeepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
854"   else
855"    NetrwKeepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
856"   endif
857   " ---------------------------------------------------------------------
858
859  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
860  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
861  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
862  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
863  elseif a:indx <= 0
864   " Nexplore, Pexplore, Explore: handle starpat
865"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx,'~'.expand("<slnum>"))
866   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
867"    call Decho("..set up <s-up> and <s-down> maps",'~'.expand("<slnum>"))
868    let s:didstarstar= 1
869    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
870    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
871   endif
872
873   if has("path_extra")
874"    call Decho("..starpat=".starpat.": has +path_extra",'~'.expand("<slnum>"))
875    if !exists("w:netrw_explore_indx")
876     let w:netrw_explore_indx= 0
877    endif
878
879    let indx = a:indx
880"    call Decho("..starpat=".starpat.": set indx= [a:indx=".indx."]",'~'.expand("<slnum>"))
881
882    if indx == -1
883     " Nexplore
884"     call Decho("..case Nexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
885     if !exists("w:netrw_explore_list") " sanity check
886      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
887      if has("clipboard")
888       sil! let @* = keepregstar
889       sil! let @+ = keepregstar
890      endif
891      sil! let @/ = keepregslash
892"      call Dret("netrw#Explore")
893      return
894     endif
895     let indx= w:netrw_explore_indx
896     if indx < 0                        | let indx= 0                           | endif
897     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
898     let curfile= w:netrw_explore_list[indx]
899"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
900     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
901      let indx= indx + 1
902"      call Decho("....indx=".indx." (Nexplore while loop)",'~'.expand("<slnum>"))
903     endwhile
904     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
905"     call Decho("....Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
906
907    elseif indx == -2
908     " Pexplore
909"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
910     if !exists("w:netrw_explore_list") " sanity check
911      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
912      if has("clipboard")
913       sil! let @* = keepregstar
914       sil! let @+ = keepregstar
915      endif
916      sil! let @/ = keepregslash
917"      call Dret("netrw#Explore")
918      return
919     endif
920     let indx= w:netrw_explore_indx
921     if indx < 0                        | let indx= 0                           | endif
922     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
923     let curfile= w:netrw_explore_list[indx]
924"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
925     while indx >= 0 && curfile == w:netrw_explore_list[indx]
926      let indx= indx - 1
927"      call Decho("....indx=".indx." (Pexplore while loop)",'~'.expand("<slnum>"))
928     endwhile
929     if indx < 0                        | let indx= 0                           | endif
930"     call Decho("....Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
931
932    else
933     " Explore -- initialize
934     " build list of files to Explore with Nexplore/Pexplore
935"     call Decho("..starpat=".starpat.": case Explore: initialize (indx=".indx.")",'~'.expand("<slnum>"))
936     NetrwKeepj keepalt call s:NetrwClearExplore()
937     let w:netrw_explore_indx= 0
938     if !exists("b:netrw_curdir")
939      let b:netrw_curdir= getcwd()
940     endif
941"     call Decho("....starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
942
943     " switch on starpat to build the w:netrw_explore_list of files
944     if starpat == 1
945      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
946"      call Decho("..case starpat=".starpat.": build *//pattern list  (curdir-only srch for files containing pattern)  &hls=".&hls,'~'.expand("<slnum>"))
947"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
948      try
949       exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
950      catch /^Vim\%((\a\+)\)\=:E480/
951       keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
952"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
953       return
954      endtry
955      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
956      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
957
958     elseif starpat == 2
959      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
960"      call Decho("..case starpat=".starpat.": build **//pattern list  (recursive descent files containing pattern)",'~'.expand("<slnum>"))
961"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
962      try
963       exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
964      catch /^Vim\%((\a\+)\)\=:E480/
965       keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
966       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
967       if has("clipboard")
968        sil! let @* = keepregstar
969        sil! let @+ = keepregstar
970       endif
971       sil! let @/ = keepregslash
972"       call Dret("netrw#Explore : no files matched pattern")
973       return
974      endtry
975      let s:netrw_curdir       = b:netrw_curdir
976      let w:netrw_explore_list = getqflist()
977      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
978      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
979
980     elseif starpat == 3
981      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
982"      call Decho("..case starpat=".starpat.": build */filepat list  (curdir-only srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
983      let filepat= substitute(dirname,'^\*/','','')
984      let filepat= substitute(filepat,'^[%#<]','\\&','')
985"      call Decho("....b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
986"      call Decho("....filepat<".filepat.">",'~'.expand("<slnum>"))
987      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
988      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
989
990     elseif starpat == 4
991      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
992"      call Decho("..case starpat=".starpat.": build **/filepat list  (recursive descent srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
993      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
994      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
995     endif " switch on starpat to build w:netrw_explore_list
996
997     let w:netrw_explore_listlen = len(w:netrw_explore_list)
998"     call Decho("....w:netrw_explore_list<".string(w:netrw_explore_list).">",'~'.expand("<slnum>"))
999"     call Decho("....w:netrw_explore_listlen=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1000
1001     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1002      keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1003      if has("clipboard")
1004       sil! let @* = keepregstar
1005       sil! let @+ = keepregstar
1006      endif
1007      sil! let @/ = keepregslash
1008"      call Dret("netrw#Explore : no files matched")
1009      return
1010     endif
1011    endif  " if indx ... endif
1012
1013    " NetrwStatusLine support - for exploring support
1014    let w:netrw_explore_indx= indx
1015"    call Decho("....w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1016
1017    " wrap the indx around, but issue a note
1018    if indx >= w:netrw_explore_listlen || indx < 0
1019"     call Decho("....wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")",'~'.expand("<slnum>"))
1020     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1021     let w:netrw_explore_indx= indx
1022     keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
1023    endif
1024
1025    exe "let dirfile= w:netrw_explore_list[".indx."]"
1026"    call Decho("....dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">",'~'.expand("<slnum>"))
1027    let newdir= substitute(dirfile,'/[^/]*$','','e')
1028"    call Decho("....newdir<".newdir.">",'~'.expand("<slnum>"))
1029
1030"    call Decho("....calling LocalBrowseCheck(newdir<".newdir.">)",'~'.expand("<slnum>"))
1031    call netrw#LocalBrowseCheck(newdir)
1032    if !exists("w:netrw_liststyle")
1033     let w:netrw_liststyle= g:netrw_liststyle
1034    endif
1035    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1036     keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1037    else
1038     keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1039    endif
1040    let w:netrw_explore_mtchcnt = indx + 1
1041    let w:netrw_explore_bufnr   = bufnr("%")
1042    let w:netrw_explore_line    = line(".")
1043    keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
1044"    call Decho("....explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line,'~'.expand("<slnum>"))
1045
1046   else
1047"    call Decho("..your vim does not have +path_extra",'~'.expand("<slnum>"))
1048    if !exists("g:netrw_quiet")
1049     keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1050    endif
1051    if has("clipboard")
1052     sil! let @* = keepregstar
1053     sil! let @+ = keepregstar
1054    endif
1055    sil! let @/ = keepregslash
1056"    call Dret("netrw#Explore : missing +path_extra")
1057    return
1058   endif
1059
1060  else
1061"   call Decho("..default case: Explore newdir<".dirname.">",'~'.expand("<slnum>"))
1062   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1063    sil! unlet w:netrw_treedict
1064    sil! unlet w:netrw_treetop
1065   endif
1066   let newdir= dirname
1067   if !exists("b:netrw_curdir")
1068    NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1069   else
1070    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
1071   endif
1072  endif
1073
1074  " visual display of **/ **// */ Exploration files
1075"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"),'~'.expand("<slnum>"))
1076"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">",'~'.expand("<slnum>"))
1077  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
1078"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"),'~'.expand("<slnum>"))
1079   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1080    " only update match list when current directory isn't the same as before
1081"    call Decho("only update match list when current directory not the same as before",'~'.expand("<slnum>"))
1082    let s:explore_prvdir = b:netrw_curdir
1083    let s:explore_match  = ""
1084    let dirlen           = strlen(b:netrw_curdir)
1085    if b:netrw_curdir !~ '/$'
1086     let dirlen= dirlen + 1
1087    endif
1088    let prvfname= ""
1089    for fname in w:netrw_explore_list
1090"     call Decho("fname<".fname.">",'~'.expand("<slnum>"))
1091     if fname =~ '^'.b:netrw_curdir
1092      if s:explore_match == ""
1093       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1094      else
1095       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1096      endif
1097     elseif fname !~ '^/' && fname != prvfname
1098      if s:explore_match == ""
1099       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1100      else
1101       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1102      endif
1103     endif
1104     let prvfname= fname
1105    endfor
1106"    call Decho("explore_match<".s:explore_match.">",'~'.expand("<slnum>"))
1107    exe "2match netrwMarkFile /".s:explore_match."/"
1108   endif
1109   echo "<s-up>==Pexplore  <s-down>==Nexplore"
1110  else
1111   2match none
1112   if exists("s:explore_match")  | unlet s:explore_match  | endif
1113   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
1114   echo " "
1115"   call Decho("cleared explore match list",'~'.expand("<slnum>"))
1116  endif
1117
1118  " since Explore may be used to initialize netrw's browser,
1119  " there's no danger of a late FocusGained event on initialization.
1120  " Consequently, set s:netrw_events to 2.
1121  let s:netrw_events= 2
1122  if has("clipboard")
1123   sil! let @* = keepregstar
1124   sil! let @+ = keepregstar
1125  endif
1126  sil! let @/ = keepregslash
1127"  call Dret("netrw#Explore : @/<".@/.">")
1128endfun
1129
1130" ---------------------------------------------------------------------
1131" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
1132fun! netrw#Lexplore(count,rightside,...)
1133"  call Dfunc("netrw#Lexplore(count=".a:count."rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
1134  let curwin= winnr()
1135
1136  if a:0 > 0 && a:1 != ""
1137   " if a netrw window is already on the left-side of the tab
1138   " and a directory has been specified, explore with that
1139   " directory.
1140   let a1 = expand(a:1)
1141"   call Decho("a:1<".a:1.">  curwin#".curwin,'~'.expand("<slnum>"))
1142   exe "1wincmd w"
1143   if &ft == "netrw"
1144"    call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
1145    exe "Explore ".fnameescape(a1)
1146    exe curwin."wincmd w"
1147    if exists("t:netrw_lexposn")
1148"     call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
1149     unlet t:netrw_lexposn
1150    endif
1151"    call Dret("netrw#Lexplore")
1152    return
1153   endif
1154   exe curwin."wincmd w"
1155  else
1156   let a1= ""
1157  endif
1158
1159  if exists("t:netrw_lexbufnr")
1160   " check if t:netrw_lexbufnr refers to a netrw window
1161   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1162  else
1163   let lexwinnr= 0
1164  endif
1165
1166  if lexwinnr > 0
1167   " close down netrw explorer window
1168"  call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
1169   exe lexwinnr."wincmd w"
1170   let g:netrw_winsize = -winwidth(0)
1171   let t:netrw_lexposn = winsaveview()
1172"   call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1173"   call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
1174   close
1175   if lexwinnr < curwin
1176    let curwin= curwin - 1
1177   endif
1178   exe curwin."wincmd w"
1179   unlet t:netrw_lexbufnr
1180
1181  else
1182   " open netrw explorer window
1183"   call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
1184   exe "1wincmd w"
1185   let keep_altv    = g:netrw_altv
1186   let g:netrw_altv = 0
1187   if a:count != 0
1188    let netrw_winsize   = g:netrw_winsize
1189    let g:netrw_winsize = a:count
1190   endif
1191   let curfile= expand("%")
1192"   call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
1193   exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1194   if a:0 > 0 && a1 != ""
1195"    call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
1196    exe "Explore ".fnameescape(a1)
1197   elseif curfile =~ '^\a\{3,}://'
1198"    call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
1199    exe "Explore ".substitute(curfile,'[^/\\]*$','','')
1200   else
1201"    call Decho("case 3: Explore .",'~'.expand("<slnum>"))
1202    Explore .
1203   endif
1204   if a:count != 0
1205    let g:netrw_winsize = netrw_winsize
1206   endif
1207   setlocal winfixwidth
1208   let g:netrw_altv     = keep_altv
1209   let t:netrw_lexbufnr = bufnr("%")
1210   if exists("t:netrw_lexposn")
1211"    call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1212"    call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1213    call winrestview(t:netrw_lexposn)
1214    unlet t:netrw_lexposn
1215   endif
1216  endif
1217
1218  " set up default window for editing via <cr>
1219  if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
1220   if a:rightside
1221    let g:netrw_chgwin= 1
1222   else
1223    let g:netrw_chgwin= 2
1224   endif
1225  endif
1226
1227"  call Dret("netrw#Lexplore")
1228endfun
1229
1230" ---------------------------------------------------------------------
1231" netrw#Clean: remove netrw {{{2
1232" supports :NetrwClean  -- remove netrw from first directory on runtimepath
1233"          :NetrwClean! -- remove netrw from all directories on runtimepath
1234fun! netrw#Clean(sys)
1235"  call Dfunc("netrw#Clean(sys=".a:sys.")")
1236
1237  if a:sys
1238   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
1239  else
1240   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
1241  endif
1242"  call Decho("choice=".choice,'~'.expand("<slnum>"))
1243  let diddel= 0
1244  let diddir= ""
1245
1246  if choice == 1
1247   for dir in split(&rtp,',')
1248    if filereadable(dir."/plugin/netrwPlugin.vim")
1249"     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1250     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
1251     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1252     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
1253     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
1254     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
1255     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
1256     let diddir= dir
1257     let diddel= diddel + 1
1258     if !a:sys|break|endif
1259    endif
1260   endfor
1261  endif
1262
1263   echohl WarningMsg
1264  if diddel == 0
1265   echomsg "netrw is either not installed or not removable"
1266  elseif diddel == 1
1267   echomsg "removed one copy of netrw from <".diddir.">"
1268  else
1269   echomsg "removed ".diddel." copies of netrw"
1270  endif
1271   echohl None
1272
1273"  call Dret("netrw#Clean")
1274endfun
1275
1276" ---------------------------------------------------------------------
1277" netrw#MakeTgt: make a target out of the directory name provided {{{2
1278fun! netrw#MakeTgt(dname)
1279"  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1280   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
1281  let svpos               = winsaveview()
1282"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1283  let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
1284"  call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
1285  if s:netrwmftgt_islocal
1286   let netrwmftgt= simplify(a:dname)
1287  else
1288   let netrwmftgt= a:dname
1289  endif
1290  if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
1291   " re-selected target, so just clear it
1292   unlet s:netrwmftgt s:netrwmftgt_islocal
1293  else
1294   let s:netrwmftgt= netrwmftgt
1295  endif
1296  if g:netrw_fastbrowse <= 1
1297   call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
1298  endif
1299"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
1300  call winrestview(svpos)
1301"  call Dret("netrw#MakeTgt")
1302endfun
1303
1304" ---------------------------------------------------------------------
1305" netrw#Obtain: {{{2
1306"   netrw#Obtain(islocal,fname[,tgtdirectory])
1307"     islocal=0  obtain from remote source
1308"            =1  obtain from local source
1309"     fname  :   a filename or a list of filenames
1310"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
1311fun! netrw#Obtain(islocal,fname,...)
1312"  call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
1313  " NetrwStatusLine support - for obtaining support
1314
1315  if type(a:fname) == 1
1316   let fnamelist= [ a:fname ]
1317  elseif type(a:fname) == 3
1318   let fnamelist= a:fname
1319  else
1320   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1321"   call Dret("netrw#Obtain")
1322   return
1323  endif
1324"  call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
1325  if a:0 > 0
1326   let tgtdir= a:1
1327  else
1328   let tgtdir= getcwd()
1329  endif
1330"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
1331
1332  if exists("b:netrw_islocal") && b:netrw_islocal
1333   " obtain a file from local b:netrw_curdir to (local) tgtdir
1334"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1335   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1336    let topath= s:ComposePath(tgtdir,"")
1337    if (has("win32") || has("win95") || has("win64") || has("win16"))
1338     " transfer files one at time
1339"     call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1340     for fname in fnamelist
1341"      call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1342      call system(g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1343      if v:shell_error != 0
1344       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1345"       call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1346       return
1347      endif
1348     endfor
1349    else
1350     " transfer files with one command
1351"     call Decho("transfer files with one command",'~'.expand("<slnum>"))
1352     let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1353"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1354     call system(g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1355     if v:shell_error != 0
1356      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1357"      call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1358      return
1359     endif
1360    endif
1361   elseif !exists("b:netrw_curdir")
1362    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
1363   else
1364    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
1365   endif
1366
1367  else
1368   " obtain files from remote b:netrw_curdir to local tgtdir
1369"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1370   if type(a:fname) == 1
1371    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
1372   endif
1373   call s:NetrwMethod(b:netrw_curdir)
1374
1375   if b:netrw_method == 4
1376    " obtain file using scp
1377"    call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1378    if exists("g:netrw_port") && g:netrw_port != ""
1379     let useport= " ".g:netrw_scpport." ".g:netrw_port
1380    else
1381     let useport= ""
1382    endif
1383    if b:netrw_fname =~ '/'
1384     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1385    else
1386     let path= ""
1387    endif
1388    let filelist= join(map(deepcopy(fnamelist),'s:ShellEscape(g:netrw_machine.":".path.v:val,1)'))
1389    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
1390
1391   elseif b:netrw_method == 2
1392    " obtain file using ftp + .netrc
1393"     call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1394     call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1395     let tmpbufnr= bufnr("%")
1396     setl ff=unix
1397     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1398      NetrwKeepj put =g:netrw_ftpmode
1399"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1400     endif
1401
1402     if exists("b:netrw_fname") && b:netrw_fname != ""
1403      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1404"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1405     endif
1406
1407     if exists("g:netrw_ftpextracmd")
1408      NetrwKeepj put =g:netrw_ftpextracmd
1409"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1410     endif
1411     for fname in fnamelist
1412      call setline(line("$")+1,'get "'.fname.'"')
1413"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1414     endfor
1415     if exists("g:netrw_port") && g:netrw_port != ""
1416      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1417     else
1418      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1419     endif
1420     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1421     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1422      let debugkeep= &debug
1423      setl debug=msg
1424      call netrw#ErrorMsg(s:ERROR,getline(1),4)
1425      let &debug= debugkeep
1426     endif
1427
1428   elseif b:netrw_method == 3
1429    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1430"    call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1431    call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1432    let tmpbufnr= bufnr("%")
1433    setl ff=unix
1434
1435    if exists("g:netrw_port") && g:netrw_port != ""
1436     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1437"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1438    else
1439     NetrwKeepj put ='open '.g:netrw_machine
1440"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1441    endif
1442
1443    if exists("g:netrw_uid") && g:netrw_uid != ""
1444     if exists("g:netrw_ftp") && g:netrw_ftp == 1
1445      NetrwKeepj put =g:netrw_uid
1446"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1447      if exists("s:netrw_passwd") && s:netrw_passwd != ""
1448       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1449      endif
1450"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1451     elseif exists("s:netrw_passwd")
1452      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1453"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1454     endif
1455    endif
1456
1457    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1458     NetrwKeepj put =g:netrw_ftpmode
1459"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1460    endif
1461
1462    if exists("b:netrw_fname") && b:netrw_fname != ""
1463     NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1464"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1465    endif
1466
1467    if exists("g:netrw_ftpextracmd")
1468     NetrwKeepj put =g:netrw_ftpextracmd
1469"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1470    endif
1471
1472    if exists("g:netrw_ftpextracmd")
1473     NetrwKeepj put =g:netrw_ftpextracmd
1474"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1475    endif
1476    for fname in fnamelist
1477     NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1478    endfor
1479"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1480
1481    " perform ftp:
1482    " -i       : turns off interactive prompting from ftp
1483    " -n  unix : DON'T use <.netrc>, even though it exists
1484    " -n  win32: quit being obnoxious about password
1485    NetrwKeepj norm! 1Gdd
1486    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1487    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1488    if getline(1) !~ "^$"
1489"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1490     if !exists("g:netrw_quiet")
1491      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1492     endif
1493    endif
1494
1495   elseif b:netrw_method == 9
1496    " obtain file using sftp
1497"    call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1498    if a:fname =~ '/'
1499     let localfile= substitute(a:fname,'^.*/','','')
1500    else
1501     let localfile= a:fname
1502    endif
1503    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))
1504
1505   elseif !exists("b:netrw_method") || b:netrw_method < 0
1506    " probably a badly formed url; protocol not recognized
1507"    call Dret("netrw#Obtain : unsupported method")
1508    return
1509
1510   else
1511    " protocol recognized but not supported for Obtain (yet?)
1512    if !exists("g:netrw_quiet")
1513     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1514    endif
1515"    call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1516    return
1517   endif
1518
1519   " restore status line
1520   if type(a:fname) == 1 && exists("s:netrw_users_stl")
1521    NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
1522   endif
1523
1524  endif
1525
1526  " cleanup
1527  if exists("tmpbufnr")
1528   if bufnr("%") != tmpbufnr
1529    exe tmpbufnr."bw!"
1530   else
1531    q!
1532   endif
1533  endif
1534
1535"  call Dret("netrw#Obtain")
1536endfun
1537
1538" ---------------------------------------------------------------------
1539" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1540fun! netrw#Nread(mode,fname)
1541"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
1542  let svpos= winsaveview()
1543"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1544  call netrw#NetRead(a:mode,a:fname)
1545"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1546  call winrestview(svpos)
1547
1548  if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
1549   if exists("w:netrw_bannercnt")
1550    " start with cursor just after the banner
1551    exe w:netrw_bannercnt
1552   endif
1553  endif
1554"  call Dret("netrw#Nread")
1555endfun
1556
1557" ------------------------------------------------------------------------
1558" s:NetrwOptionRestore: restore options (based on prior s:NetrwOptionSave) {{{2
1559fun! s:NetrwOptionRestore(vt)
1560"  call Dfunc("s:NetrwOptionRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
1561"  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>"))
1562  if !exists("{a:vt}netrw_optionsave")
1563   if exists("s:nbcd_curpos_{bufnr('%')}")
1564"    call Decho("restoring posn to s:nbcd_curpos_".bufnr('%')."<".string(s:nbcd_curpos_{bufnr('%')}).">",'~'.expand("<slnum>"))
1565    NetrwKeepj call winrestview(s:nbcd_curpos_{bufnr('%')})
1566"    call Decho("win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
1567"    call Decho("unlet s:nbcd_curpos_".bufnr('%'),'~'.expand("<slnum>"))
1568    unlet s:nbcd_curpos_{bufnr('%')}
1569   else
1570"    call Decho("no previous position",'~'.expand("<slnum>"))
1571   endif
1572"   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>"))
1573"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1574"   call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist")
1575   return
1576  endif
1577  unlet {a:vt}netrw_optionsave
1578
1579  if exists("+acd")
1580   if exists("{a:vt}netrw_acdkeep")
1581"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1582    let curdir = getcwd()
1583    let &l:acd = {a:vt}netrw_acdkeep
1584    unlet {a:vt}netrw_acdkeep
1585    if &l:acd
1586     call s:NetrwLcd(curdir)
1587    endif
1588   endif
1589  endif
1590  if exists("{a:vt}netrw_aikeep")   |let &l:ai     = {a:vt}netrw_aikeep      |unlet {a:vt}netrw_aikeep   |endif
1591  if exists("{a:vt}netrw_awkeep")   |let &l:aw     = {a:vt}netrw_awkeep      |unlet {a:vt}netrw_awkeep   |endif
1592  if exists("{a:vt}netrw_blkeep")   |let &l:bl     = {a:vt}netrw_blkeep      |unlet {a:vt}netrw_blkeep   |endif
1593  if exists("{a:vt}netrw_btkeep")   |let &l:bt     = {a:vt}netrw_btkeep      |unlet {a:vt}netrw_btkeep   |endif
1594  if exists("{a:vt}netrw_bombkeep") |let &l:bomb   = {a:vt}netrw_bombkeep    |unlet {a:vt}netrw_bombkeep |endif
1595  if exists("{a:vt}netrw_cedit")    |let &cedit    = {a:vt}netrw_cedit       |unlet {a:vt}netrw_cedit    |endif
1596  if exists("{a:vt}netrw_cikeep")   |let &l:ci     = {a:vt}netrw_cikeep      |unlet {a:vt}netrw_cikeep   |endif
1597  if exists("{a:vt}netrw_cinkeep")  |let &l:cin    = {a:vt}netrw_cinkeep     |unlet {a:vt}netrw_cinkeep  |endif
1598  if exists("{a:vt}netrw_cinokeep") |let &l:cino   = {a:vt}netrw_cinokeep    |unlet {a:vt}netrw_cinokeep |endif
1599  if exists("{a:vt}netrw_comkeep")  |let &l:com    = {a:vt}netrw_comkeep     |unlet {a:vt}netrw_comkeep  |endif
1600  if exists("{a:vt}netrw_cpokeep")  |let &l:cpo    = {a:vt}netrw_cpokeep     |unlet {a:vt}netrw_cpokeep  |endif
1601  if exists("{a:vt}netrw_diffkeep") |let &l:diff   = {a:vt}netrw_diffkeep    |unlet {a:vt}netrw_diffkeep |endif
1602  if exists("{a:vt}netrw_fenkeep")  |let &l:fen    = {a:vt}netrw_fenkeep     |unlet {a:vt}netrw_fenkeep  |endif
1603  if exists("g:netrw_ffkep") && g:netrw_ffkeep
1604   if exists("{a:vt}netrw_ffkeep")   |let &l:ff     = {a:vt}netrw_ffkeep      |unlet {a:vt}netrw_ffkeep   |endif
1605  endif
1606  if exists("{a:vt}netrw_fokeep")   |let &l:fo     = {a:vt}netrw_fokeep      |unlet {a:vt}netrw_fokeep   |endif
1607  if exists("{a:vt}netrw_gdkeep")   |let &l:gd     = {a:vt}netrw_gdkeep      |unlet {a:vt}netrw_gdkeep   |endif
1608  if exists("{a:vt}netrw_hidkeep")  |let &l:hidden = {a:vt}netrw_hidkeep     |unlet {a:vt}netrw_hidkeep  |endif
1609  if exists("{a:vt}netrw_imkeep")   |let &l:im     = {a:vt}netrw_imkeep      |unlet {a:vt}netrw_imkeep   |endif
1610  if exists("{a:vt}netrw_iskkeep")  |let &l:isk    = {a:vt}netrw_iskkeep     |unlet {a:vt}netrw_iskkeep  |endif
1611  if exists("{a:vt}netrw_lskeep")   |let &l:ls     = {a:vt}netrw_lskeep      |unlet {a:vt}netrw_lskeep   |endif
1612  if exists("{a:vt}netrw_makeep")   |let &l:ma     = {a:vt}netrw_makeep      |unlet {a:vt}netrw_makeep   |endif
1613  if exists("{a:vt}netrw_magickeep")|let &l:magic  = {a:vt}netrw_magickeep   |unlet {a:vt}netrw_magickeep|endif
1614  if exists("{a:vt}netrw_modkeep")  |let &l:mod    = {a:vt}netrw_modkeep     |unlet {a:vt}netrw_modkeep  |endif
1615  if exists("{a:vt}netrw_nukeep")   |let &l:nu     = {a:vt}netrw_nukeep      |unlet {a:vt}netrw_nukeep   |endif
1616  if exists("{a:vt}netrw_rnukeep")  |let &l:rnu    = {a:vt}netrw_rnukeep     |unlet {a:vt}netrw_rnukeep  |endif
1617  if exists("{a:vt}netrw_repkeep")  |let &l:report = {a:vt}netrw_repkeep     |unlet {a:vt}netrw_repkeep  |endif
1618  if exists("{a:vt}netrw_rokeep")   |let &l:ro     = {a:vt}netrw_rokeep      |unlet {a:vt}netrw_rokeep   |endif
1619  if exists("{a:vt}netrw_selkeep")  |let &l:sel    = {a:vt}netrw_selkeep     |unlet {a:vt}netrw_selkeep  |endif
1620  if exists("{a:vt}netrw_spellkeep")|let &l:spell  = {a:vt}netrw_spellkeep   |unlet {a:vt}netrw_spellkeep|endif
1621  if has("clipboard")
1622   if exists("{a:vt}netrw_starkeep") |let @*        = {a:vt}netrw_starkeep    |unlet {a:vt}netrw_starkeep |endif
1623  endif
1624  " Problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1625"  if exists("{a:vt}netrw_tskeep")   |let &l:ts     = {a:vt}netrw_tskeep      |unlet {a:vt}netrw_tskeep   |endif
1626  if exists("{a:vt}netrw_twkeep")   |let &l:tw     = {a:vt}netrw_twkeep      |unlet {a:vt}netrw_twkeep   |endif
1627  if exists("{a:vt}netrw_wigkeep")  |let &l:wig    = {a:vt}netrw_wigkeep     |unlet {a:vt}netrw_wigkeep  |endif
1628  if exists("{a:vt}netrw_wrapkeep") |let &l:wrap   = {a:vt}netrw_wrapkeep    |unlet {a:vt}netrw_wrapkeep |endif
1629  if exists("{a:vt}netrw_writekeep")|let &l:write  = {a:vt}netrw_writekeep   |unlet {a:vt}netrw_writekeep|endif
1630  if exists("s:yykeep")             |let  @@       = s:yykeep                |unlet s:yykeep             |endif
1631  if exists("{a:vt}netrw_swfkeep")
1632   if &directory == ""
1633    " user hasn't specified a swapfile directory;
1634    " netrw will temporarily set the swapfile directory
1635    " to the current directory as returned by getcwd().
1636    let &l:directory= getcwd()
1637    sil! let &l:swf = {a:vt}netrw_swfkeep
1638    setl directory=
1639    unlet {a:vt}netrw_swfkeep
1640   elseif &l:swf != {a:vt}netrw_swfkeep
1641    if !g:netrw_use_noswf
1642     " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1643     sil! let &l:swf= {a:vt}netrw_swfkeep
1644    endif
1645    unlet {a:vt}netrw_swfkeep
1646   endif
1647  endif
1648  if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
1649   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1650   if exists("{a:vt}netrw_dirkeep")
1651    call s:NetrwLcd(dirkeep)
1652    unlet {a:vt}netrw_dirkeep
1653   endif
1654  endif
1655  if has("clipboard")
1656   if exists("{a:vt}netrw_regstar") |sil! let @*= {a:vt}netrw_regstar |unlet {a:vt}netrw_regstar |endif
1657  endif
1658  if exists("{a:vt}netrw_regslash")|sil! let @/= {a:vt}netrw_regslash|unlet {a:vt}netrw_regslash|endif
1659  if exists("s:nbcd_curpos_{bufnr('%')}")
1660"   call Decho("restoring posn to s:nbcd_curpos_".bufnr('%')."<".string(s:nbcd_curpos_{bufnr('%')}).">",'~'.expand("<slnum>"))
1661   NetrwKeepj call winrestview(s:nbcd_curpos_{bufnr('%')})
1662"   call Decho("unlet s:nbcd_curpos_".bufnr('%'),'~'.expand("<slnum>"))
1663   if exists("s:nbcd_curpos_".bufnr('%'))
1664    unlet s:nbcd_curpos_{bufnr('%')}
1665   endif
1666  else
1667"   call Decho("no previous position",'~'.expand("<slnum>"))
1668  endif
1669
1670"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1671"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
1672"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1673"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
1674"  call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
1675  " Moved the filetype detect here from NetrwGetFile() because remote files
1676  " were having their filetype detect-generated settings overwritten by
1677  " NetrwOptionRestore.
1678  if &ft != "netrw"
1679"   call Decho("filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1680   filetype detect
1681  endif
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:NetrwOptionRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
1684endfun
1685
1686" ---------------------------------------------------------------------
1687" s:NetrwOptionSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1688"             Options get restored by s:NetrwOptionRestore()
1689"  06/08/07 : removed call to NetrwSafeOptions(), either placed
1690"             immediately after NetrwOptionSave() calls in NetRead
1691"             and NetWrite, or after the s:NetrwEnew() call in
1692"             NetrwBrowse.
1693"             vt: normally its "w:" or "s:" (a variable type)
1694fun! s:NetrwOptionSave(vt)
1695"  call Dfunc("s:NetrwOptionSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1696"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1697"  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>"))
1698
1699  if !exists("{a:vt}netrw_optionsave")
1700   let {a:vt}netrw_optionsave= 1
1701  else
1702"   call Dret("s:NetrwOptionSave : options already saved")
1703   return
1704  endif
1705"  call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
1706
1707  " Save current settings and current directory
1708"  call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
1709  let s:yykeep          = @@
1710  if exists("&l:acd")|let {a:vt}netrw_acdkeep  = &l:acd|endif
1711  let {a:vt}netrw_aikeep    = &l:ai
1712  let {a:vt}netrw_awkeep    = &l:aw
1713  let {a:vt}netrw_bhkeep    = &l:bh
1714  let {a:vt}netrw_blkeep    = &l:bl
1715  let {a:vt}netrw_btkeep    = &l:bt
1716  let {a:vt}netrw_bombkeep  = &l:bomb
1717  let {a:vt}netrw_cedit     = &cedit
1718  let {a:vt}netrw_cikeep    = &l:ci
1719  let {a:vt}netrw_cinkeep   = &l:cin
1720  let {a:vt}netrw_cinokeep  = &l:cino
1721  let {a:vt}netrw_comkeep   = &l:com
1722  let {a:vt}netrw_cpokeep   = &l:cpo
1723  let {a:vt}netrw_diffkeep  = &l:diff
1724  let {a:vt}netrw_fenkeep   = &l:fen
1725  if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
1726   let {a:vt}netrw_ffkeep    = &l:ff
1727  endif
1728  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
1729  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
1730  let {a:vt}netrw_hidkeep   = &l:hidden
1731  let {a:vt}netrw_imkeep    = &l:im
1732  let {a:vt}netrw_iskkeep   = &l:isk
1733  let {a:vt}netrw_lskeep    = &l:ls
1734  let {a:vt}netrw_makeep    = &l:ma
1735  let {a:vt}netrw_magickeep = &l:magic
1736  let {a:vt}netrw_modkeep   = &l:mod
1737  let {a:vt}netrw_nukeep    = &l:nu
1738  let {a:vt}netrw_rnukeep   = &l:rnu
1739  let {a:vt}netrw_repkeep   = &l:report
1740  let {a:vt}netrw_rokeep    = &l:ro
1741  let {a:vt}netrw_selkeep   = &l:sel
1742  let {a:vt}netrw_spellkeep = &l:spell
1743  if !g:netrw_use_noswf
1744   let {a:vt}netrw_swfkeep  = &l:swf
1745  endif
1746  if has("clipboard")
1747   let {a:vt}netrw_starkeep = @*
1748  endif
1749  let {a:vt}netrw_tskeep    = &l:ts
1750  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
1751  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
1752  let {a:vt}netrw_wrapkeep  = &l:wrap
1753  let {a:vt}netrw_writekeep = &l:write
1754
1755  " save a few selected netrw-related variables
1756"  call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
1757  if g:netrw_keepdir
1758   let {a:vt}netrw_dirkeep  = getcwd()
1759  endif
1760  if has("clipboard")
1761   if &go =~# 'a' | sil! let {a:vt}netrw_regstar = @* | endif
1762  endif
1763  sil! let {a:vt}netrw_regslash= @/
1764
1765"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>"))
1766"  call Dret("s:NetrwOptionSave : tab#".tabpagenr()." win#".winnr())
1767endfun
1768
1769" ------------------------------------------------------------------------
1770" s:NetrwSafeOptions: sets options to help netrw do its job {{{2
1771"                     Use  s:NetrwSaveOptions() to save user settings
1772"                     Use  s:NetrwOptionRestore() to restore user settings
1773fun! s:NetrwSafeOptions()
1774"  call Dfunc("s:NetrwSafeOptions() win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1775"  call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1776"  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>"))
1777  if exists("+acd") | setl noacd | endif
1778  setl noai
1779  setl noaw
1780  setl nobl
1781  setl nobomb
1782  setl bt=nofile
1783  setl noci
1784  setl nocin
1785  setl bh=hide
1786  setl cino=
1787  setl com=
1788  setl cpo-=a
1789  setl cpo-=A
1790  setl fo=nroql2
1791  setl nohid
1792  setl noim
1793  setl isk+=@ isk+=* isk+=/
1794  setl magic
1795  if g:netrw_use_noswf
1796   setl noswf
1797  endif
1798  setl report=10000
1799  setl sel=inclusive
1800  setl nospell
1801  setl tw=0
1802  setl wig=
1803  setl cedit&
1804  call s:NetrwCursor()
1805
1806  " allow the user to override safe options
1807"  call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
1808  if &ft == "netrw"
1809"   call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1810   sil! keepalt NetrwKeepj doau FileType netrw
1811  endif
1812
1813"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1814"  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>"))
1815"  call Dret("s:NetrwSafeOptions")
1816endfun
1817
1818" ---------------------------------------------------------------------
1819" NetrwStatusLine: {{{2
1820fun! NetrwStatusLine()
1821
1822" vvv NetrwStatusLine() debugging vvv
1823"  let g:stlmsg=""
1824"  if !exists("w:netrw_explore_bufnr")
1825"   let g:stlmsg="!X<explore_bufnr>"
1826"  elseif w:netrw_explore_bufnr != bufnr("%")
1827"   let g:stlmsg="explore_bufnr!=".bufnr("%")
1828"  endif
1829"  if !exists("w:netrw_explore_line")
1830"   let g:stlmsg=" !X<explore_line>"
1831"  elseif w:netrw_explore_line != line(".")
1832"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1833"  endif
1834"  if !exists("w:netrw_explore_list")
1835"   let g:stlmsg=" !X<explore_list>"
1836"  endif
1837" ^^^ NetrwStatusLine() debugging ^^^
1838
1839  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")
1840   " restore user's status line
1841   let &stl        = s:netrw_users_stl
1842   let &laststatus = s:netrw_users_ls
1843   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1844   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1845   return ""
1846  else
1847   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
1848  endif
1849endfun
1850
1851" ---------------------------------------------------------------------
1852"  Netrw Transfer Functions: {{{1
1853" ===============================
1854
1855" ------------------------------------------------------------------------
1856" netrw#NetRead: responsible for reading a file over the net {{{2
1857"   mode: =0 read remote file and insert before current line
1858"         =1 read remote file and insert after current line
1859"         =2 replace with remote file
1860"         =3 obtain file, but leave in temporary format
1861fun! netrw#NetRead(mode,...)
1862"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
1863
1864  " NetRead: save options {{{3
1865  call s:NetrwOptionSave("w:")
1866  call s:NetrwSafeOptions()
1867  call s:RestoreCursorline()
1868  " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
1869  " However, this setting is not wanted for a remote editing session.  The buffer should be "nofile", still.
1870  setl bl
1871"  call Decho("(netrw#NetRead) buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
1872
1873  " NetRead: interpret mode into a readcmd {{{3
1874  if     a:mode == 0 " read remote file before current line
1875   let readcmd = "0r"
1876  elseif a:mode == 1 " read file after current line
1877   let readcmd = "r"
1878  elseif a:mode == 2 " replace with remote file
1879   let readcmd = "%r"
1880  elseif a:mode == 3 " skip read of file (leave as temporary)
1881   let readcmd = "t"
1882  else
1883   exe a:mode
1884   let readcmd = "r"
1885  endif
1886  let ichoice = (a:0 == 0)? 0 : 1
1887"  call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
1888
1889  " NetRead: get temporary filename {{{3
1890  let tmpfile= s:GetTempfile("")
1891  if tmpfile == ""
1892"   call Dret("netrw#NetRead : unable to get a tempfile!")
1893   return
1894  endif
1895
1896  while ichoice <= a:0
1897
1898   " attempt to repeat with previous host-file-etc
1899   if exists("b:netrw_lastfile") && a:0 == 0
1900"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
1901    let choice = b:netrw_lastfile
1902    let ichoice= ichoice + 1
1903
1904   else
1905    exe "let choice= a:" . ichoice
1906"    call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
1907
1908    if match(choice,"?") == 0
1909     " give help
1910     echomsg 'NetRead Usage:'
1911     echomsg ':Nread machine:path                         uses rcp'
1912     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
1913     echomsg ':Nread "machine id password path"           uses ftp'
1914     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
1915     echomsg ':Nread fetch://machine/path                 uses fetch'
1916     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
1917     echomsg ':Nread http://[user@]machine/path           uses http  wget'
1918     echomsg ':Nread file:///path           		  uses elinks'
1919     echomsg ':Nread https://[user@]machine/path          uses http  wget'
1920     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
1921     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
1922     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
1923     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
1924     sleep 4
1925     break
1926
1927    elseif match(choice,'^"') != -1
1928     " Reconstruct Choice if choice starts with '"'
1929"     call Decho("reconstructing choice",'~'.expand("<slnum>"))
1930     if match(choice,'"$') != -1
1931      " case "..."
1932      let choice= strpart(choice,1,strlen(choice)-2)
1933     else
1934       "  case "... ... ..."
1935      let choice      = strpart(choice,1,strlen(choice)-1)
1936      let wholechoice = ""
1937
1938      while match(choice,'"$') == -1
1939       let wholechoice = wholechoice . " " . choice
1940       let ichoice     = ichoice + 1
1941       if ichoice > a:0
1942       	if !exists("g:netrw_quiet")
1943	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
1944	endif
1945"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
1946        return
1947       endif
1948       let choice= a:{ichoice}
1949      endwhile
1950      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
1951     endif
1952    endif
1953   endif
1954
1955"   call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
1956   let ichoice= ichoice + 1
1957
1958   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
1959   call s:NetrwMethod(choice)
1960   if !exists("b:netrw_method") || b:netrw_method < 0
1961"    call Dfunc("netrw#NetRead : unsupported method")
1962    return
1963   endif
1964   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
1965
1966   " Check whether or not NetrwBrowse() should be handling this request
1967"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
1968   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
1969"    call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
1970    NetrwKeepj call s:NetrwBrowse(0,choice)
1971"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
1972    return
1973   endif
1974
1975   " ============
1976   " NetRead: Perform Protocol-Based Read {{{3
1977   " ===========================
1978   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
1979    echo "(netrw) Processing your read request..."
1980   endif
1981
1982   ".........................................
1983   " NetRead: (rcp)  NetRead Method #1 {{{3
1984   if  b:netrw_method == 1 " read with rcp
1985"    call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
1986   " ER: nothing done with g:netrw_uid yet?
1987   " ER: on Win2K" rcp machine[.user]:file tmpfile
1988   " ER: when machine contains '.' adding .user is required (use $USERNAME)
1989   " ER: the tmpfile is full path: rcp sees C:\... as host C
1990   if s:netrw_has_nt_rcp == 1
1991    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
1992     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
1993    else
1994     " Any way needed it machine contains a '.'
1995     let uid_machine = g:netrw_machine .'.'. $USERNAME
1996    endif
1997   else
1998    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
1999     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2000    else
2001     let uid_machine = g:netrw_machine
2002    endif
2003   endif
2004   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))
2005   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2006   let b:netrw_lastfile = choice
2007
2008   ".........................................
2009   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
2010   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
2011"     call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2012     let netrw_fname= b:netrw_fname
2013     NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2014     let filtbuf= bufnr("%")
2015     setl ff=unix
2016     NetrwKeepj put =g:netrw_ftpmode
2017"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2018     if exists("g:netrw_ftpextracmd")
2019      NetrwKeepj put =g:netrw_ftpextracmd
2020"      call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2021     endif
2022     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2023"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2024     if exists("g:netrw_port") && g:netrw_port != ""
2025      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2026     else
2027      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2028     endif
2029     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2030     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2031      let debugkeep = &debug
2032      setl debug=msg
2033      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2034      let &debug    = debugkeep
2035     endif
2036     call s:SaveBufVars()
2037     keepj bd!
2038     if bufname("%") == "" && getline("$") == "" && line('$') == 1
2039      " needed when one sources a file in a nolbl setting window via ftp
2040      q!
2041     endif
2042     call s:RestoreBufVars()
2043     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2044     let b:netrw_lastfile = choice
2045
2046   ".........................................
2047   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
2048   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
2049    " Construct execution string (four lines) which will be passed through filter
2050"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2051    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2052    NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2053    let filtbuf= bufnr("%")
2054    setl ff=unix
2055    if exists("g:netrw_port") && g:netrw_port != ""
2056     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2057"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2058    else
2059     NetrwKeepj put ='open '.g:netrw_machine
2060"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2061    endif
2062
2063    if exists("g:netrw_uid") && g:netrw_uid != ""
2064     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2065      NetrwKeepj put =g:netrw_uid
2066"       call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2067      if exists("s:netrw_passwd")
2068       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2069      endif
2070"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2071     elseif exists("s:netrw_passwd")
2072      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2073"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2074     endif
2075    endif
2076
2077    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2078     NetrwKeepj put =g:netrw_ftpmode
2079"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2080    endif
2081    if exists("g:netrw_ftpextracmd")
2082     NetrwKeepj put =g:netrw_ftpextracmd
2083"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2084    endif
2085    NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2086"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2087
2088    " perform ftp:
2089    " -i       : turns off interactive prompting from ftp
2090    " -n  unix : DON'T use <.netrc>, even though it exists
2091    " -n  win32: quit being obnoxious about password
2092    NetrwKeepj norm! 1Gdd
2093    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2094    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2095    if getline(1) !~ "^$"
2096"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2097     if !exists("g:netrw_quiet")
2098      call netrw#ErrorMsg(s:ERROR,getline(1),5)
2099     endif
2100    endif
2101    call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2102    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2103    let b:netrw_lastfile = choice
2104
2105   ".........................................
2106   " NetRead: (scp) NetRead Method #4 {{{3
2107   elseif     b:netrw_method  == 4	" read with scp
2108"    call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2109    if exists("g:netrw_port") && g:netrw_port != ""
2110     let useport= " ".g:netrw_scpport." ".g:netrw_port
2111    else
2112     let useport= ""
2113    endif
2114    " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2115    " This is workaround to avoid mis-handle windows local-path:
2116    if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
2117      let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2118    else
2119      let tmpfile_get = tmpfile
2120    endif
2121    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile_get,1))
2122    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2123    let b:netrw_lastfile = choice
2124
2125   ".........................................
2126   " NetRead: (http) NetRead Method #5 (wget) {{{3
2127   elseif     b:netrw_method  == 5
2128"    call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2129    if g:netrw_http_cmd == ""
2130     if !exists("g:netrw_quiet")
2131      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2132     endif
2133"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2134     return
2135    endif
2136
2137    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2138     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2139"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2140     if exists("g:netrw_http_xcmd")
2141      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))
2142     else
2143      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))
2144     endif
2145     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2146
2147    else
2148     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2149"     call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2150     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2151     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2152"     call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2153"     call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2154     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))
2155     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2156"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2157     exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2158    endif
2159    let b:netrw_lastfile = choice
2160"    call Decho("setl ro",'~'.expand("<slnum>"))
2161    setl ro nomod
2162
2163   ".........................................
2164   " NetRead: (dav) NetRead Method #6 {{{3
2165   elseif     b:netrw_method  == 6
2166"    call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2167
2168    if !executable(g:netrw_dav_cmd)
2169     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2170"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2171     return
2172    endif
2173    if g:netrw_dav_cmd =~ "curl"
2174     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2175    else
2176     " Construct execution string (four lines) which will be passed through filter
2177     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2178     new
2179     setl ff=unix
2180     if exists("g:netrw_port") && g:netrw_port != ""
2181      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2182     else
2183      NetrwKeepj put ='open '.g:netrw_machine
2184     endif
2185     if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2186      NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2187     endif
2188     NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2189     NetrwKeepj put ='quit'
2190
2191     " perform cadaver operation:
2192     NetrwKeepj norm! 1Gdd
2193     call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2194     keepj bd!
2195    endif
2196    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2197    let b:netrw_lastfile = choice
2198
2199   ".........................................
2200   " NetRead: (rsync) NetRead Method #7 {{{3
2201   elseif     b:netrw_method  == 7
2202"    call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2203    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2204    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2205    let b:netrw_lastfile = choice
2206
2207   ".........................................
2208   " NetRead: (fetch) NetRead Method #8 {{{3
2209   "    fetch://[user@]host[:http]/path
2210   elseif     b:netrw_method  == 8
2211"    call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2212    if g:netrw_fetch_cmd == ""
2213     if !exists("g:netrw_quiet")
2214      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2215     endif
2216"     call Dret("NetRead")
2217     return
2218    endif
2219    if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2220     let netrw_option= "http"
2221    else
2222     let netrw_option= "ftp"
2223    endif
2224"    call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2225
2226    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2227     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))
2228    else
2229     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))
2230    endif
2231
2232    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2233    let b:netrw_lastfile = choice
2234"    call Decho("setl ro",'~'.expand("<slnum>"))
2235    setl ro nomod
2236
2237   ".........................................
2238   " NetRead: (sftp) NetRead Method #9 {{{3
2239   elseif     b:netrw_method  == 9
2240"    call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2241    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2242    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2243    let b:netrw_lastfile = choice
2244
2245   ".........................................
2246   " NetRead: (file) NetRead Method #10 {{{3
2247  elseif      b:netrw_method == 10 && exists("g:netrw_file_cmd")
2248"   "    call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2249   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2250   let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2251   let b:netrw_lastfile = choice
2252
2253   ".........................................
2254   " NetRead: Complain {{{3
2255   else
2256    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
2257   endif
2258  endwhile
2259
2260  " NetRead: cleanup {{{3
2261  if exists("b:netrw_method")
2262"   call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2263   unlet b:netrw_method
2264   unlet b:netrw_fname
2265  endif
2266  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
2267"   call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2268   NetrwKeepj call s:NetrwDelete(tmpfile)
2269  endif
2270  NetrwKeepj call s:NetrwOptionRestore("w:")
2271
2272"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
2273endfun
2274
2275" ------------------------------------------------------------------------
2276" netrw#NetWrite: responsible for writing a file over the net {{{2
2277fun! netrw#NetWrite(...) range
2278"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
2279
2280  " NetWrite: option handling {{{3
2281  let mod= 0
2282  call s:NetrwOptionSave("w:")
2283  call s:NetrwSafeOptions()
2284
2285  " NetWrite: Get Temporary Filename {{{3
2286  let tmpfile= s:GetTempfile("")
2287  if tmpfile == ""
2288"   call Dret("netrw#NetWrite : unable to get a tempfile!")
2289   return
2290  endif
2291
2292  if a:0 == 0
2293   let ichoice = 0
2294  else
2295   let ichoice = 1
2296  endif
2297
2298  let curbufname= expand("%")
2299"  call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
2300  if &binary
2301   " For binary writes, always write entire file.
2302   " (line numbers don't really make sense for that).
2303   " Also supports the writing of tar and zip files.
2304"   call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2305   exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2306  elseif g:netrw_cygwin
2307   " write (selected portion of) file to temporary
2308   let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2309"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2310   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
2311  else
2312   " write (selected portion of) file to temporary
2313"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2314   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2315  endif
2316
2317  if curbufname == ""
2318   " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2319   " on the temporary file's name.  Deletion of the temporary file during
2320   " cleanup then causes an error message.
2321   0file!
2322  endif
2323
2324  " NetWrite: while choice loop: {{{3
2325  while ichoice <= a:0
2326
2327   " Process arguments: {{{4
2328   " attempt to repeat with previous host-file-etc
2329   if exists("b:netrw_lastfile") && a:0 == 0
2330"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2331    let choice = b:netrw_lastfile
2332    let ichoice= ichoice + 1
2333   else
2334    exe "let choice= a:" . ichoice
2335
2336    " Reconstruct Choice when choice starts with '"'
2337    if match(choice,"?") == 0
2338     echomsg 'NetWrite Usage:"'
2339     echomsg ':Nwrite machine:path                        uses rcp'
2340     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
2341     echomsg ':Nwrite "machine id password path"          uses ftp'
2342     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
2343     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
2344     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
2345     echomsg ':Nwrite rcp://machine/path                  uses rcp'
2346     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
2347     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2348     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
2349     sleep 4
2350     break
2351
2352    elseif match(choice,"^\"") != -1
2353     if match(choice,"\"$") != -1
2354       " case "..."
2355      let choice=strpart(choice,1,strlen(choice)-2)
2356     else
2357      "  case "... ... ..."
2358      let choice      = strpart(choice,1,strlen(choice)-1)
2359      let wholechoice = ""
2360
2361      while match(choice,"\"$") == -1
2362       let wholechoice= wholechoice . " " . choice
2363       let ichoice    = ichoice + 1
2364       if choice > a:0
2365       	if !exists("g:netrw_quiet")
2366	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2367	endif
2368"        call Dret("netrw#NetWrite")
2369        return
2370       endif
2371       let choice= a:{ichoice}
2372      endwhile
2373      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2374     endif
2375    endif
2376   endif
2377   let ichoice= ichoice + 1
2378"   call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
2379
2380   " Determine method of write (ftp, rcp, etc) {{{4
2381   NetrwKeepj call s:NetrwMethod(choice)
2382   if !exists("b:netrw_method") || b:netrw_method < 0
2383"    call Dfunc("netrw#NetWrite : unsupported method")
2384    return
2385   endif
2386
2387   " =============
2388   " NetWrite: Perform Protocol-Based Write {{{3
2389   " ============================
2390   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2391    echo "(netrw) Processing your write request..."
2392"    call Decho("(netrw) Processing your write request...",'~'.expand("<slnum>"))
2393   endif
2394
2395   ".........................................
2396   " NetWrite: (rcp) NetWrite Method #1 {{{3
2397   if  b:netrw_method == 1
2398"    call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2399    if s:netrw_has_nt_rcp == 1
2400     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2401      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2402     else
2403      let uid_machine = g:netrw_machine .'.'. $USERNAME
2404     endif
2405    else
2406     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2407      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2408     else
2409      let uid_machine = g:netrw_machine
2410     endif
2411    endif
2412    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))
2413    let b:netrw_lastfile = choice
2414
2415   ".........................................
2416   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2417   elseif b:netrw_method == 2
2418"    call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2419    let netrw_fname = b:netrw_fname
2420
2421    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2422    let bhkeep      = &l:bh
2423    let curbuf      = bufnr("%")
2424    setl bh=hide
2425    keepj keepalt enew
2426
2427"    call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2428    setl ff=unix
2429    NetrwKeepj put =g:netrw_ftpmode
2430"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2431    if exists("g:netrw_ftpextracmd")
2432     NetrwKeepj put =g:netrw_ftpextracmd
2433"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2434    endif
2435    NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2436"    call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2437    if exists("g:netrw_port") && g:netrw_port != ""
2438     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2439    else
2440"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2441     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2442    endif
2443    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2444    if getline(1) !~ "^$"
2445     if !exists("g:netrw_quiet")
2446      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2447     endif
2448     let mod=1
2449    endif
2450
2451    " remove enew buffer (quietly)
2452    let filtbuf= bufnr("%")
2453    exe curbuf."b!"
2454    let &l:bh            = bhkeep
2455    exe filtbuf."bw!"
2456
2457    let b:netrw_lastfile = choice
2458
2459   ".........................................
2460   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2461   elseif b:netrw_method == 3
2462    " Construct execution string (three or more lines) which will be passed through filter
2463"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2464    let netrw_fname = b:netrw_fname
2465    let bhkeep      = &l:bh
2466
2467    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2468    let curbuf      = bufnr("%")
2469    setl bh=hide
2470    keepj keepalt enew
2471    setl ff=unix
2472
2473    if exists("g:netrw_port") && g:netrw_port != ""
2474     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2475"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2476    else
2477     NetrwKeepj put ='open '.g:netrw_machine
2478"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2479    endif
2480    if exists("g:netrw_uid") && g:netrw_uid != ""
2481     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2482      NetrwKeepj put =g:netrw_uid
2483"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2484      if exists("s:netrw_passwd") && s:netrw_passwd != ""
2485       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2486      endif
2487"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2488     elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2489      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2490"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2491     endif
2492    endif
2493    NetrwKeepj put =g:netrw_ftpmode
2494"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2495    if exists("g:netrw_ftpextracmd")
2496     NetrwKeepj put =g:netrw_ftpextracmd
2497"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2498    endif
2499    NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2500"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2501    " save choice/id/password for future use
2502    let b:netrw_lastfile = choice
2503
2504    " perform ftp:
2505    " -i       : turns off interactive prompting from ftp
2506    " -n  unix : DON'T use <.netrc>, even though it exists
2507    " -n  win32: quit being obnoxious about password
2508    NetrwKeepj norm! 1Gdd
2509    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2510    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2511    if getline(1) !~ "^$"
2512     if  !exists("g:netrw_quiet")
2513      call netrw#ErrorMsg(s:ERROR,getline(1),15)
2514     endif
2515     let mod=1
2516    endif
2517
2518    " remove enew buffer (quietly)
2519    let filtbuf= bufnr("%")
2520    exe curbuf."b!"
2521    let &l:bh= bhkeep
2522    exe filtbuf."bw!"
2523
2524   ".........................................
2525   " NetWrite: (scp) NetWrite Method #4 {{{3
2526   elseif     b:netrw_method == 4
2527"    call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2528    if exists("g:netrw_port") && g:netrw_port != ""
2529     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2530    else
2531     let useport= ""
2532    endif
2533    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2534    let b:netrw_lastfile = choice
2535
2536   ".........................................
2537   " NetWrite: (http) NetWrite Method #5 {{{3
2538   elseif     b:netrw_method == 5
2539"    call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2540    let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2541    if executable(curl)
2542     let url= g:netrw_choice
2543     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2544    elseif !exists("g:netrw_quiet")
2545     call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd".">".",16)
2546    endif
2547
2548   ".........................................
2549   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2550   elseif     b:netrw_method == 6
2551"    call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2552
2553    " Construct execution string (four lines) which will be passed through filter
2554    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2555    let bhkeep      = &l:bh
2556
2557    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2558    let curbuf      = bufnr("%")
2559    setl bh=hide
2560    keepj keepalt enew
2561
2562    setl ff=unix
2563    if exists("g:netrw_port") && g:netrw_port != ""
2564     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2565    else
2566     NetrwKeepj put ='open '.g:netrw_machine
2567    endif
2568    if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2569     NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2570    endif
2571    NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2572
2573    " perform cadaver operation:
2574    NetrwKeepj norm! 1Gdd
2575    call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2576
2577    " remove enew buffer (quietly)
2578    let filtbuf= bufnr("%")
2579    exe curbuf."b!"
2580    let &l:bh            = bhkeep
2581    exe filtbuf."bw!"
2582
2583    let b:netrw_lastfile = choice
2584
2585   ".........................................
2586   " NetWrite: (rsync) NetWrite Method #7 {{{3
2587   elseif     b:netrw_method == 7
2588"    call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2589    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2590    let b:netrw_lastfile = choice
2591
2592   ".........................................
2593   " NetWrite: (sftp) NetWrite Method #9 {{{3
2594   elseif     b:netrw_method == 9
2595"    call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2596    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2597    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2598     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2599    else
2600     let uid_machine = g:netrw_machine
2601    endif
2602
2603    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2604    let bhkeep = &l:bh
2605    let curbuf = bufnr("%")
2606    setl bh=hide
2607    keepj keepalt enew
2608
2609    setl ff=unix
2610    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2611"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2612    let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2613    call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2614    let filtbuf= bufnr("%")
2615    exe curbuf."b!"
2616    let &l:bh            = bhkeep
2617    exe filtbuf."bw!"
2618    let b:netrw_lastfile = choice
2619
2620   ".........................................
2621   " NetWrite: Complain {{{3
2622   else
2623    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2624    let leavemod= 1
2625   endif
2626  endwhile
2627
2628  " NetWrite: Cleanup: {{{3
2629"  call Decho("cleanup",'~'.expand("<slnum>"))
2630  if s:FileReadable(tmpfile)
2631"   call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2632   call s:NetrwDelete(tmpfile)
2633  endif
2634  call s:NetrwOptionRestore("w:")
2635
2636  if a:firstline == 1 && a:lastline == line("$")
2637   " restore modifiability; usually equivalent to set nomod
2638   let &mod= mod
2639"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2640  elseif !exists("leavemod")
2641   " indicate that the buffer has not been modified since last written
2642"   call Decho("set nomod",'~'.expand("<slnum>"))
2643   setl nomod
2644"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2645  endif
2646
2647"  call Dret("netrw#NetWrite")
2648endfun
2649
2650" ---------------------------------------------------------------------
2651" netrw#NetSource: source a remotely hosted vim script {{{2
2652" uses NetRead to get a copy of the file into a temporarily file,
2653"              then sources that file,
2654"              then removes that file.
2655fun! netrw#NetSource(...)
2656"  call Dfunc("netrw#NetSource() a:0=".a:0)
2657  if a:0 > 0 && a:1 == '?'
2658   " give help
2659   echomsg 'NetSource Usage:'
2660   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
2661   echomsg ':Nsource fetch://machine/path                 uses fetch'
2662   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2663   echomsg ':Nsource http[s]://[user@]machine/path        uses http  wget'
2664   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
2665   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
2666   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
2667   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2668   sleep 4
2669  else
2670   let i= 1
2671   while i <= a:0
2672    call netrw#NetRead(3,a:{i})
2673"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2674    if s:FileReadable(s:netrw_tmpfile)
2675"     call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2676     exe "so ".fnameescape(s:netrw_tmpfile)
2677"     call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2678     if delete(s:netrw_tmpfile)
2679      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2680     endif
2681     unlet s:netrw_tmpfile
2682    else
2683     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2684    endif
2685    let i= i + 1
2686   endwhile
2687  endif
2688"  call Dret("netrw#NetSource")
2689endfun
2690
2691" ---------------------------------------------------------------------
2692" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2693"                   (implements the :Ntree command)
2694fun! netrw#SetTreetop(...)
2695"  call Dfunc("netrw#SetTreetop(".((a:0 > 0)? a:1 : "").") a:0=".a:0)
2696
2697  " clear out the current tree
2698  if exists("w:netrw_treetop")
2699"   call Decho("clearing out current tree",'~'.expand("<slnum>"))
2700   let inittreetop= w:netrw_treetop
2701   unlet w:netrw_treetop
2702  endif
2703  if exists("w:netrw_treedict")
2704"   call Decho("freeing w:netrw_treedict",'~'.expand("<slnum>"))
2705   unlet w:netrw_treedict
2706  endif
2707
2708  if a:1 == "" && exists("inittreetop")
2709   let treedir= s:NetrwTreePath(inittreetop)
2710"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2711  else
2712   if isdirectory(s:NetrwFile(a:1))
2713"    call Decho("a:1<".a:1."> is a directory",'~'.expand("<slnum>"))
2714    let treedir= a:1
2715   elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2716    let treedir= b:netrw_curdir."/".a:1
2717"    call Decho("a:1<".a:1."> is NOT a directory, trying treedir<".treedir.">",'~'.expand("<slnum>"))
2718   else
2719    " normally the cursor is left in the message window.
2720    " However, here this results in the directory being listed in the message window, which is not wanted.
2721    let netrwbuf= bufnr("%")
2722    call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2723    exe bufwinnr(netrwbuf)."wincmd w"
2724    let treedir= "."
2725   endif
2726  endif
2727"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2728  let islocal= expand("%") !~ '^\a\{3,}://'
2729"  call Decho("islocal=".islocal,'~'.expand("<slnum>"))
2730  if islocal
2731   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir))
2732  else
2733   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir))
2734  endif
2735"  call Dret("netrw#SetTreetop")
2736endfun
2737
2738" ===========================================
2739" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
2740"    readcmd == %r : replace buffer with newly read file
2741"            == 0r : read file at top of buffer
2742"            == r  : read file after current line
2743"            == t  : leave file in temporary form (ie. don't read into buffer)
2744fun! s:NetrwGetFile(readcmd, tfile, method)
2745"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
2746
2747  " readcmd=='t': simply do nothing
2748  if a:readcmd == 't'
2749"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2750"   call Dret("NetrwGetFile : skip read of <".a:tfile.">")
2751   return
2752  endif
2753
2754  " get name of remote filename (ie. url and all)
2755  let rfile= bufname("%")
2756"  call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
2757
2758  if exists("*NetReadFixup")
2759   " for the use of NetReadFixup (not otherwise used internally)
2760   let line2= line("$")
2761  endif
2762
2763  if a:readcmd[0] == '%'
2764  " get file into buffer
2765"   call Decho("get file into buffer",'~'.expand("<slnum>"))
2766
2767   " rename the current buffer to the temp file (ie. tfile)
2768   if g:netrw_cygwin
2769    let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2770   else
2771    let tfile= a:tfile
2772   endif
2773"   call Decho("exe sil! keepalt file ".fnameescape(tfile),'~'.expand("<slnum>"))
2774   exe "sil! keepalt file ".fnameescape(tfile)
2775
2776   " edit temporary file (ie. read the temporary file in)
2777   if     rfile =~ '\.zip$'
2778"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2779    call zip#Browse(tfile)
2780   elseif rfile =~ '\.tar$'
2781"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2782    call tar#Browse(tfile)
2783   elseif rfile =~ '\.tar\.gz$'
2784"    call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2785    call tar#Browse(tfile)
2786   elseif rfile =~ '\.tar\.bz2$'
2787"    call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2788    call tar#Browse(tfile)
2789   elseif rfile =~ '\.tar\.xz$'
2790"    call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2791    call tar#Browse(tfile)
2792   elseif rfile =~ '\.txz$'
2793"    call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2794    call tar#Browse(tfile)
2795   else
2796"    call Decho("edit temporary file",'~'.expand("<slnum>"))
2797    NetrwKeepj e!
2798   endif
2799
2800   " rename buffer back to remote filename
2801"   call Decho("exe sil! keepalt file ".fnameescape(rfile),'~'.expand("<slnum>"))
2802   exe "sil! NetrwKeepj keepalt file ".fnameescape(rfile)
2803
2804   " Detect filetype of local version of remote file.
2805   " Note that isk must not include a "/" for scripts.vim
2806   " to process this detection correctly.
2807"   call Decho("detect filetype of local version of remote file",'~'.expand("<slnum>"))
2808   let iskkeep= &l:isk
2809   setl isk-=/
2810   let &l:isk= iskkeep
2811"   call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!")
2812   let line1 = 1
2813   let line2 = line("$")
2814
2815  elseif !&ma
2816   " attempting to read a file after the current line in the file, but the buffer is not modifiable
2817   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2818"   call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2819   return
2820
2821  elseif s:FileReadable(a:tfile)
2822   " read file after current line
2823"   call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2824   let curline = line(".")
2825   let lastline= line("$")
2826"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline,'~'.expand("<slnum>"))
2827   exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2828   let line1= curline + 1
2829   let line2= line("$") - lastline + 1
2830
2831  else
2832   " not readable
2833"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2834"   call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2835   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2836"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2837   return
2838  endif
2839
2840  " User-provided (ie. optional) fix-it-up command
2841  if exists("*NetReadFixup")
2842"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2843   NetrwKeepj call NetReadFixup(a:method, line1, line2)
2844"  else " Decho
2845"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2846  endif
2847
2848  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
2849   " update the Buffers menu
2850   NetrwKeepj call s:UpdateBuffersMenu()
2851  endif
2852
2853"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
2854
2855 " make sure file is being displayed
2856"  redraw!
2857
2858"  call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2859"  call Dret("NetrwGetFile")
2860endfun
2861
2862" ------------------------------------------------------------------------
2863" s:NetrwMethod:  determine method of transfer {{{2
2864" Input:
2865"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
2866" Output:
2867"  b:netrw_method= 1: rcp
2868"                  2: ftp + <.netrc>
2869"	           3: ftp + machine, id, password, and [path]filename
2870"	           4: scp
2871"	           5: http[s] (wget)
2872"	           6: dav
2873"	           7: rsync
2874"	           8: fetch
2875"	           9: sftp
2876"	          10: file
2877"  g:netrw_machine= hostname
2878"  b:netrw_fname  = filename
2879"  g:netrw_port   = optional port number (for ftp)
2880"  g:netrw_choice = copy of input url (choice)
2881fun! s:NetrwMethod(choice)
2882"   call Dfunc("NetrwMethod(a:choice<".a:choice.">)")
2883
2884   " sanity check: choice should have at least three slashes in it
2885   if strlen(substitute(a:choice,'[^/]','','g')) < 3
2886    call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
2887    let b:netrw_method = -1
2888"    call Dret("NetrwMethod : incorrect url format<".a:choice.">")
2889    return
2890   endif
2891
2892   " record current g:netrw_machine, if any
2893   " curmachine used if protocol == ftp and no .netrc
2894   if exists("g:netrw_machine")
2895    let curmachine= g:netrw_machine
2896"    call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
2897   else
2898    let curmachine= "N O T A HOST"
2899   endif
2900   if exists("g:netrw_port")
2901    let netrw_port= g:netrw_port
2902   endif
2903
2904   " insure that netrw_ftp_cmd starts off every method determination
2905   " with the current g:netrw_ftp_cmd
2906   let s:netrw_ftp_cmd= g:netrw_ftp_cmd
2907
2908  " initialization
2909  let b:netrw_method  = 0
2910  let g:netrw_machine = ""
2911  let b:netrw_fname   = ""
2912  let g:netrw_port    = ""
2913  let g:netrw_choice  = a:choice
2914
2915  " Patterns:
2916  " mipf     : a:machine a:id password filename	     Use ftp
2917  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
2918  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
2919  " rcpurm   : rcp://[user@]host/filename	     Use rcp
2920  " rcphf    : [user@]host:filename		     Use rcp
2921  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
2922  " httpurm  : http[s]://[user@]host/filename	     Use wget
2923  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
2924  " rsyncurm : rsync://host[:port]/path              Use rsync
2925  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
2926  " sftpurm  : sftp://[user@]host/filename  Use scp
2927  " fileurm  : file://[user@]host/filename	     Use elinks or links
2928  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
2929  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
2930  let ftpurm   = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
2931  let rcpurm   = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
2932  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
2933  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
2934  let httpurm  = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
2935  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
2936  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
2937  let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
2938  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
2939  let fileurm  = '^file\=://\(.*\)$'
2940
2941"  call Decho("determine method:",'~'.expand("<slnum>"))
2942  " Determine Method
2943  " Method#1: rcp://user@hostname/...path-to-file {{{3
2944  if match(a:choice,rcpurm) == 0
2945"   call Decho("rcp://...",'~'.expand("<slnum>"))
2946   let b:netrw_method  = 1
2947   let userid          = substitute(a:choice,rcpurm,'\1',"")
2948   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
2949   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
2950   if userid != ""
2951    let g:netrw_uid= userid
2952   endif
2953
2954  " Method#4: scp://user@hostname/...path-to-file {{{3
2955  elseif match(a:choice,scpurm) == 0
2956"   call Decho("scp://...",'~'.expand("<slnum>"))
2957   let b:netrw_method  = 4
2958   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
2959   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
2960   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
2961
2962  " Method#5: http[s]://user@hostname/...path-to-file {{{3
2963  elseif match(a:choice,httpurm) == 0
2964"   call Decho("http[s]://...",'~'.expand("<slnum>"))
2965   let b:netrw_method = 5
2966   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
2967   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
2968   let b:netrw_http   = (a:choice =~ '^https:')? "https" : "http"
2969
2970  " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
2971  elseif match(a:choice,davurm) == 0
2972"   call Decho("dav://...",'~'.expand("<slnum>"))
2973   let b:netrw_method= 6
2974   if a:choice =~ 'davs:'
2975    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
2976   else
2977    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
2978   endif
2979   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
2980
2981   " Method#7: rsync://user@hostname/...path-to-file {{{3
2982  elseif match(a:choice,rsyncurm) == 0
2983"   call Decho("rsync://...",'~'.expand("<slnum>"))
2984   let b:netrw_method = 7
2985   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
2986   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
2987
2988   " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
2989  elseif match(a:choice,ftpurm) == 0
2990"   call Decho("ftp://...",'~'.expand("<slnum>"))
2991   let userid	      = substitute(a:choice,ftpurm,'\2',"")
2992   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
2993   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
2994   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
2995"   call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
2996   if userid != ""
2997    let g:netrw_uid= userid
2998   endif
2999
3000   if curmachine != g:netrw_machine
3001    if exists("s:netwr_hup[".g:netrw_machine."]")
3002     call NetUserPass("ftp:".g:netrw_machine)
3003    elseif exists("s:netrw_passwd")
3004     " if there's a change in hostname, require password re-entry
3005     unlet s:netrw_passwd
3006    endif
3007    if exists("netrw_port")
3008     unlet netrw_port
3009    endif
3010   endif
3011
3012   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3013    let b:netrw_method = 3
3014   else
3015    let host= substitute(g:netrw_machine,'\..*$','','')
3016    if exists("s:netrw_hup[host]")
3017     call NetUserPass("ftp:".host)
3018
3019    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~ '-[sS]:'
3020"     call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3021"     call Decho("          g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3022     if g:netrw_ftp_cmd =~ '-[sS]:\S*MACHINE\>'
3023      let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3024"      call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3025     endif
3026     let b:netrw_method= 2
3027    elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3028"     call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3029     let b:netrw_method= 2
3030    else
3031     if !exists("g:netrw_uid") || g:netrw_uid == ""
3032      call NetUserPass()
3033     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3034      call NetUserPass(g:netrw_uid)
3035    " else just use current g:netrw_uid and s:netrw_passwd
3036     endif
3037     let b:netrw_method= 3
3038    endif
3039   endif
3040
3041  " Method#8: fetch {{{3
3042  elseif match(a:choice,fetchurm) == 0
3043"   call Decho("fetch://...",'~'.expand("<slnum>"))
3044   let b:netrw_method = 8
3045   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3046   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3047   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3048   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
3049
3050   " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
3051  elseif match(a:choice,mipf) == 0
3052"   call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
3053   let b:netrw_method  = 3
3054   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3055   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
3056   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
3057   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
3058   call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
3059
3060  " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3061  elseif match(a:choice,mf) == 0
3062"   call Decho("(ftp) host file",'~'.expand("<slnum>"))
3063   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3064    let b:netrw_method  = 3
3065    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3066    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3067
3068   elseif s:FileReadable(expand("$HOME/.netrc"))
3069    let b:netrw_method  = 2
3070    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3071    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3072   endif
3073
3074  " Method#9: sftp://user@hostname/...path-to-file {{{3
3075  elseif match(a:choice,sftpurm) == 0
3076"   call Decho("sftp://...",'~'.expand("<slnum>"))
3077   let b:netrw_method = 9
3078   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3079   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
3080
3081  " Method#1: Issue an rcp: hostname:filename"  (this one should be last) {{{3
3082  elseif match(a:choice,rcphf) == 0
3083"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3084   let b:netrw_method  = 1
3085   let userid          = substitute(a:choice,rcphf,'\2',"")
3086   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3087   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
3088"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3089"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3090"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3091"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3092   if userid != ""
3093    let g:netrw_uid= userid
3094   endif
3095
3096   " Method#10: file://user@hostname/...path-to-file {{{3
3097  elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
3098"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3099   let b:netrw_method = 10
3100   let b:netrw_fname  = substitute(a:choice,fileurm,'\1',"")
3101"   call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
3102
3103  " Cannot Determine Method {{{3
3104  else
3105   if !exists("g:netrw_quiet")
3106    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3107   endif
3108   let b:netrw_method  = -1
3109  endif
3110  "}}}3
3111
3112  if g:netrw_port != ""
3113   " remove any leading [:#] from port number
3114   let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
3115  elseif exists("netrw_port")
3116   " retain port number as implicit for subsequent ftp operations
3117   let g:netrw_port= netrw_port
3118  endif
3119
3120"  call Decho("a:choice       <".a:choice.">",'~'.expand("<slnum>"))
3121"  call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3122"  call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3123"  call Decho("g:netrw_port   <".g:netrw_port.">",'~'.expand("<slnum>"))
3124"  if exists("g:netrw_uid")		"Decho
3125"   call Decho("g:netrw_uid    <".g:netrw_uid.">",'~'.expand("<slnum>"))
3126"  endif					"Decho
3127"  if exists("s:netrw_passwd")		"Decho
3128"   call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3129"  endif					"Decho
3130"  call Decho("b:netrw_fname  <".b:netrw_fname.">",'~'.expand("<slnum>"))
3131"  call Dret("NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
3132endfun
3133
3134" ------------------------------------------------------------------------
3135" NetReadFixup: this sort of function is typically written by the user {{{2
3136"               to handle extra junk that their system's ftp dumps
3137"               into the transfer.  This function is provided as an
3138"               example and as a fix for a Windows 95 problem: in my
3139"               experience, win95's ftp always dumped four blank lines
3140"               at the end of the transfer.
3141if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
3142 fun! NetReadFixup(method, line1, line2)
3143"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
3144
3145   " sanity checks -- attempt to convert inputs to integers
3146   let method = a:method + 0
3147   let line1  = a:line1 + 0
3148   let line2  = a:line2 + 0
3149   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
3150"    call Dret("NetReadFixup")
3151    return
3152   endif
3153
3154   if method == 3   " ftp (no <.netrc>)
3155    let fourblanklines= line2 - 3
3156    if fourblanklines >= line1
3157     exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
3158     call histdel("/",-1)
3159    endif
3160   endif
3161
3162"   call Dret("NetReadFixup")
3163 endfun
3164endif
3165
3166" ---------------------------------------------------------------------
3167" NetUserPass: set username and password for subsequent ftp transfer {{{2
3168"   Usage:  :call NetUserPass()		               -- will prompt for userid and password
3169"	    :call NetUserPass("uid")	               -- will prompt for password
3170"	    :call NetUserPass("uid","password")        -- sets global userid and password
3171"	    :call NetUserPass("ftp:host")              -- looks up userid and password using hup dictionary
3172"	    :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
3173fun! NetUserPass(...)
3174
3175" call Dfunc("NetUserPass() a:0=".a:0)
3176
3177 if !exists('s:netrw_hup')
3178  let s:netrw_hup= {}
3179 endif
3180
3181 if a:0 == 0
3182  " case: no input arguments
3183
3184  " change host and username if not previously entered; get new password
3185  if !exists("g:netrw_machine")
3186   let g:netrw_machine= input('Enter hostname: ')
3187  endif
3188  if !exists("g:netrw_uid") || g:netrw_uid == ""
3189   " get username (user-id) via prompt
3190   let g:netrw_uid= input('Enter username: ')
3191  endif
3192  " get password via prompting
3193  let s:netrw_passwd= inputsecret("Enter Password: ")
3194
3195  " set up hup database
3196  let host = substitute(g:netrw_machine,'\..*$','','')
3197  if !exists('s:netrw_hup[host]')
3198   let s:netrw_hup[host]= {}
3199  endif
3200  let s:netrw_hup[host].uid    = g:netrw_uid
3201  let s:netrw_hup[host].passwd = s:netrw_passwd
3202
3203 elseif a:0 == 1
3204  " case: one input argument
3205
3206  if a:1 =~ '^ftp:'
3207   " get host from ftp:... url
3208   " access userid and password from hup (host-user-passwd) dictionary
3209"   call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3210   let host = substitute(a:1,'^ftp:','','')
3211   let host = substitute(host,'\..*','','')
3212   if exists("s:netrw_hup[host]")
3213    let g:netrw_uid    = s:netrw_hup[host].uid
3214    let s:netrw_passwd = s:netrw_hup[host].passwd
3215"    call Decho("get s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3216"    call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3217   else
3218    let g:netrw_uid    = input("Enter UserId: ")
3219    let s:netrw_passwd = inputsecret("Enter Password: ")
3220   endif
3221
3222  else
3223   " case: one input argument, not an url.  Using it as a new user-id.
3224"   call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3225   if exists("g:netrw_machine")
3226    if g:netrw_machine =~ '[0-9.]\+'
3227     let host= g:netrw_machine
3228    else
3229     let host= substitute(g:netrw_machine,'\..*$','','')
3230    endif
3231   else
3232    let g:netrw_machine= input('Enter hostname: ')
3233   endif
3234   let g:netrw_uid = a:1
3235"   call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3236   if exists("g:netrw_passwd")
3237    " ask for password if one not previously entered
3238    let s:netrw_passwd= g:netrw_passwd
3239   else
3240    let s:netrw_passwd = inputsecret("Enter Password: ")
3241   endif
3242  endif
3243
3244"  call Decho("host<".host.">",'~'.expand("<slnum>"))
3245  if exists("host")
3246   if !exists('s:netrw_hup[host]')
3247    let s:netrw_hup[host]= {}
3248   endif
3249   let s:netrw_hup[host].uid    = g:netrw_uid
3250   let s:netrw_hup[host].passwd = s:netrw_passwd
3251  endif
3252
3253 elseif a:0 == 2
3254  let g:netrw_uid    = a:1
3255  let s:netrw_passwd = a:2
3256
3257 elseif a:0 == 3
3258  " enter hostname, user-id, and password into the hup dictionary
3259  let host = substitute(a:1,'^\a\+:','','')
3260  let host = substitute(host,'\..*$','','')
3261  if !exists('s:netrw_hup[host]')
3262   let s:netrw_hup[host]= {}
3263  endif
3264  let s:netrw_hup[host].uid    = a:2
3265  let s:netrw_hup[host].passwd = a:3
3266  let g:netrw_uid              = s:netrw_hup[host].uid
3267  let s:netrw_passwd           = s:netrw_hup[host].passwd
3268"  call Decho("set s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3269"  call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3270 endif
3271
3272" call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
3273endfun
3274
3275" ===========================================
3276"  Shared Browsing Support:    {{{1
3277" ===========================================
3278
3279" ---------------------------------------------------------------------
3280" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3281fun! s:ExplorePatHls(pattern)
3282"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
3283  let repat= substitute(a:pattern,'^**/\{1,2}','','')
3284"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3285  let repat= escape(repat,'][.\')
3286"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3287  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
3288"  call Dret("s:ExplorePatHls repat<".repat.">")
3289  return repat
3290endfun
3291
3292" ---------------------------------------------------------------------
3293"  s:NetrwBookHistHandler: {{{2
3294"    0: (user: <mb>)   bookmark current directory
3295"    1: (user: <gb>)   change to the bookmarked directory
3296"    2: (user: <qb>)   list bookmarks
3297"    3: (browsing)     records current directory history
3298"    4: (user: <u>)    go up   (previous) directory, using history
3299"    5: (user: <U>)    go down (next)     directory, using history
3300"    6: (user: <mB>)   delete bookmark
3301fun! s:NetrwBookHistHandler(chg,curdir)
3302"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhist_cnt." histmax=".g:netrw_dirhistmax)
3303  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3304"   "  call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3305   return
3306  endif
3307
3308  let ykeep    = @@
3309  let curbufnr = bufnr("%")
3310
3311  if a:chg == 0
3312   " bookmark the current directory
3313"   call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3314   if exists("s:netrwmarkfilelist_{curbufnr}")
3315    call s:NetrwBookmark(0)
3316    echo "bookmarked marked files"
3317   else
3318    call s:MakeBookmark(a:curdir)
3319    echo "bookmarked the current directory"
3320   endif
3321
3322  elseif a:chg == 1
3323   " change to the bookmarked directory
3324"   call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3325   if exists("g:netrw_bookmarklist[v:count-1]")
3326"    call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3327    exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3328   else
3329    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3330   endif
3331
3332  elseif a:chg == 2
3333"   redraw!
3334   let didwork= 0
3335   " list user's bookmarks
3336"   call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3337   if exists("g:netrw_bookmarklist")
3338"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3339    let cnt= 1
3340    for bmd in g:netrw_bookmarklist
3341"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3342     echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3343     let didwork = 1
3344     let cnt     = cnt + 1
3345    endfor
3346   endif
3347
3348   " list directory history
3349   let cnt     = g:netrw_dirhist_cnt
3350   let first   = 1
3351   let histcnt = 0
3352   if g:netrw_dirhistmax > 0
3353    while ( first || cnt != g:netrw_dirhist_cnt )
3354"    call Decho("first=".first." cnt=".cnt." dirhist_cnt=".g:netrw_dirhist_cnt,'~'.expand("<slnum>"))
3355     if exists("g:netrw_dirhist_{cnt}")
3356"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3357      echo printf("Netrw  History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3358      let didwork= 1
3359     endif
3360     let histcnt = histcnt + 1
3361     let first   = 0
3362     let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3363     if cnt < 0
3364      let cnt= cnt + g:netrw_dirhistmax
3365     endif
3366    endwhile
3367   else
3368    let g:netrw_dirhist_cnt= 0
3369   endif
3370   if didwork
3371    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3372   endif
3373
3374  elseif a:chg == 3
3375   " saves most recently visited directories (when they differ)
3376"   call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3377   if !exists("g:netrw_dirhist_cnt") || !exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") || g:netrw_dirhist_{g:netrw_dirhist_cnt} != a:curdir
3378    if g:netrw_dirhistmax > 0
3379     let g:netrw_dirhist_cnt                   = ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
3380     let g:netrw_dirhist_{g:netrw_dirhist_cnt} = a:curdir
3381    endif
3382"    call Decho("save dirhist#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3383   endif
3384
3385  elseif a:chg == 4
3386   " u: change to the previous directory stored on the history list
3387"   call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
3388   if g:netrw_dirhistmax > 0
3389    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - v:count1 ) % g:netrw_dirhistmax
3390    if g:netrw_dirhist_cnt < 0
3391     let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
3392    endif
3393   else
3394    let g:netrw_dirhist_cnt= 0
3395   endif
3396   if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
3397"    call Decho("changedir u#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3398    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3399     setl ma noro
3400"     call Decho("setl ma noro",'~'.expand("<slnum>"))
3401     sil! NetrwKeepj %d _
3402     setl nomod
3403"     call Decho("setl nomod",'~'.expand("<slnum>"))
3404"     call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3405    endif
3406"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("<slnum>"))
3407    exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
3408   else
3409    if g:netrw_dirhistmax > 0
3410     let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + v:count1 ) % g:netrw_dirhistmax
3411    else
3412     let g:netrw_dirhist_cnt= 0
3413    endif
3414    echo "Sorry, no predecessor directory exists yet"
3415   endif
3416
3417  elseif a:chg == 5
3418   " U: change to the subsequent directory stored on the history list
3419"   call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3420   if g:netrw_dirhistmax > 0
3421    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
3422    if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
3423"    call Decho("changedir U#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3424     if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3425"      call Decho("setl ma noro",'~'.expand("<slnum>"))
3426      setl ma noro
3427      sil! NetrwKeepj %d _
3428"      call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3429"      call Decho("setl nomod",'~'.expand("<slnum>"))
3430      setl nomod
3431"      call Decho("(set nomod)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3432     endif
3433"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("<slnum>"))
3434     exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
3435    else
3436     let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax
3437     if g:netrw_dirhist_cnt < 0
3438      let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
3439     endif
3440     echo "Sorry, no successor directory exists yet"
3441    endif
3442   else
3443    let g:netrw_dirhist_cnt= 0
3444    echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
3445   endif
3446
3447  elseif a:chg == 6
3448"   call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3449   if exists("s:netrwmarkfilelist_{curbufnr}")
3450    call s:NetrwBookmark(1)
3451    echo "removed marked files from bookmarks"
3452   else
3453    " delete the v:count'th bookmark
3454    let iremove = v:count
3455    let dremove = g:netrw_bookmarklist[iremove - 1]
3456"    call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3457    call s:MergeBookmarks()
3458"    call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3459    NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3460    echo "removed ".dremove." from g:netrw_bookmarklist"
3461"    call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3462   endif
3463"   call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3464  endif
3465  call s:NetrwBookmarkMenu()
3466  call s:NetrwTgtMenu()
3467  let @@= ykeep
3468"  call Dret("s:NetrwBookHistHandler")
3469endfun
3470
3471" ---------------------------------------------------------------------
3472" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
3473"  Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
3474"                      Sister function: s:NetrwBookHistSave()
3475fun! s:NetrwBookHistRead()
3476"  call Dfunc("s:NetrwBookHistRead()")
3477  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3478"   "  call Dret("s:NetrwBookHistRead - suppressed due to g:netrw_dirhistmax")
3479   return
3480  endif
3481  let ykeep= @@
3482  if !exists("s:netrw_initbookhist")
3483   let home    = s:NetrwHome()
3484   let savefile= home."/.netrwbook"
3485   if filereadable(s:NetrwFile(savefile))
3486"    call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3487    exe "keepalt NetrwKeepj so ".savefile
3488   endif
3489   if g:netrw_dirhistmax > 0
3490    let savefile= home."/.netrwhist"
3491    if filereadable(s:NetrwFile(savefile))
3492"    call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3493     exe "keepalt NetrwKeepj so ".savefile
3494    endif
3495    let s:netrw_initbookhist= 1
3496    au VimLeave * call s:NetrwBookHistSave()
3497   endif
3498  endif
3499  let @@= ykeep
3500"  call Dret("s:NetrwBookHistRead")
3501endfun
3502
3503" ---------------------------------------------------------------------
3504" s:NetrwBookHistSave: this function saves bookmarks and history {{{2
3505"                      Sister function: s:NetrwBookHistRead()
3506"                      I used to do this via viminfo but that appears to
3507"                      be unreliable for long-term storage
3508"                      If g:netrw_dirhistmax is <= 0, no history or bookmarks
3509"                      will be saved.
3510fun! s:NetrwBookHistSave()
3511"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax)
3512  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3513"   call Dret("s:NetrwBookHistSave : dirhistmax=".g:netrw_dirhistmax)
3514   return
3515  endif
3516
3517  let savefile= s:NetrwHome()."/.netrwhist"
3518  1split
3519  call s:NetrwEnew()
3520  if g:netrw_use_noswf
3521   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
3522  else
3523   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
3524  endif
3525  setl nocin noai noci magic nospell nohid wig= noaw
3526  setl ma noro write
3527  if exists("+acd") | setl noacd | endif
3528  sil! NetrwKeepj keepalt %d _
3529
3530  " save .netrwhist -- no attempt to merge
3531  sil! keepalt file .netrwhist
3532  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
3533  call setline(2,"let g:netrw_dirhist_cnt =".g:netrw_dirhist_cnt)
3534  let lastline = line("$")
3535  let cnt      = 1
3536  while cnt <= g:netrw_dirhist_cnt
3537   call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3538   let cnt= cnt + 1
3539  endwhile
3540  exe "sil! w! ".savefile
3541
3542  sil NetrwKeepj %d _
3543  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
3544   " merge and write .netrwbook
3545   let savefile= s:NetrwHome()."/.netrwbook"
3546
3547   if filereadable(s:NetrwFile(savefile))
3548    let booklist= deepcopy(g:netrw_bookmarklist)
3549    exe "sil NetrwKeepj keepalt so ".savefile
3550    for bdm in booklist
3551     if index(g:netrw_bookmarklist,bdm) == -1
3552      call add(g:netrw_bookmarklist,bdm)
3553     endif
3554    endfor
3555    call sort(g:netrw_bookmarklist)
3556   endif
3557
3558   " construct and save .netrwbook
3559   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3560   exe "sil! w! ".savefile
3561  endif
3562  let bgone= bufnr("%")
3563  q!
3564  exe "keepalt ".bgone."bwipe!"
3565
3566"  call Dret("s:NetrwBookHistSave")
3567endfun
3568
3569" ---------------------------------------------------------------------
3570" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3571"  list of the contents of a local or remote directory.  It is assumed that the
3572"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3573"  with the requested remote hostname first.
3574"    Often called via:  Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
3575fun! s:NetrwBrowse(islocal,dirname)
3576  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
3577"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
3578"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
3579"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3580"  call Dredir("ls!")
3581
3582  " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3583  " This is useful when one edits a local file, then :e ., then :Rex
3584  if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
3585   let w:netrw_rexfile= bufname("#")
3586"   call Decho("setting w:netrw_rexfile<".w:netrw_rexfile."> win#".winnr())
3587  endif
3588
3589  " s:NetrwBrowse : initialize history {{{3
3590  if !exists("s:netrw_initbookhist")
3591   NetrwKeepj call s:NetrwBookHistRead()
3592  endif
3593
3594  " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
3595  if a:dirname !~ '^\a\{3,}://'
3596   let dirname= simplify(a:dirname)
3597  else
3598   let dirname= a:dirname
3599  endif
3600
3601  if exists("s:netrw_skipbrowse")
3602   unlet s:netrw_skipbrowse
3603"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("<slnum>"))
3604"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed")
3605   return
3606  endif
3607
3608  " s:NetrwBrowse : sanity checks: {{{3
3609  if !exists("*shellescape")
3610   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3611"   call Dret("s:NetrwBrowse : missing shellescape()")
3612   return
3613  endif
3614  if !exists("*fnameescape")
3615   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3616"   call Dret("s:NetrwBrowse : missing fnameescape()")
3617   return
3618  endif
3619
3620  " s:NetrwBrowse : save options: {{{3
3621  call s:NetrwOptionSave("w:")
3622
3623  " s:NetrwBrowse : re-instate any marked files {{{3
3624  if exists("s:netrwmarkfilelist_{bufnr('%')}")
3625"   call Decho("clearing marked files",'~'.expand("<slnum>"))
3626   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3627  endif
3628
3629  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
3630   " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3631"   call Decho("handle w:netrw_acdkeep:",'~'.expand("<slnum>"))
3632"   call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("<slnum>"))
3633   call s:NetrwLcd(dirname)
3634   call s:NetrwSafeOptions()
3635"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
3636
3637  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
3638   " s:NetrwBrowse :  remote regular file handler {{{3
3639"   call Decho("handle remote regular file: dirname<".dirname.">",'~'.expand("<slnum>"))
3640   if bufname(dirname) != ""
3641"    call Decho("edit buf#".bufname(dirname)." in win#".winnr(),'~'.expand("<slnum>"))
3642    exe "NetrwKeepj b ".bufname(dirname)
3643   else
3644    " attempt transfer of remote regular file
3645"    call Decho("attempt transfer as regular file<".dirname.">",'~'.expand("<slnum>"))
3646
3647    " remove any filetype indicator from end of dirname, except for the
3648    " "this is a directory" indicator (/).
3649    " There shouldn't be one of those here, anyway.
3650    let path= substitute(dirname,'[*=@|]\r\=$','','e')
3651"    call Decho("new path<".path.">",'~'.expand("<slnum>"))
3652    call s:RemotePathAnalysis(dirname)
3653
3654    " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3655    call s:NetrwEnew(dirname)
3656    call s:NetrwSafeOptions()
3657    setl ma noro
3658"    call Decho("setl ma noro",'~'.expand("<slnum>"))
3659    let b:netrw_curdir = dirname
3660    let url            = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3661"    call Decho("exe sil! keepalt file ".fnameescape(url)." (bt=".&bt.")",'~'.expand("<slnum>"))
3662    exe "sil! NetrwKeepj keepalt file ".fnameescape(url)
3663    exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3664    sil call netrw#NetRead(2,url)
3665    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3666"    call Decho("url<".url.">",'~'.expand("<slnum>"))
3667"    call Decho("s:path<".s:path.">",'~'.expand("<slnum>"))
3668"    call Decho("s:fname<".s:fname.">",'~'.expand("<slnum>"))
3669    if s:path =~ '.bz2'
3670     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3671    elseif s:path =~ '.gz'
3672     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3673    elseif s:path =~ '.gz'
3674     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3675    else
3676     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3677    endif
3678   endif
3679
3680   " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3681   call s:SetBufWinVars()
3682   call s:NetrwOptionRestore("w:")
3683"   call Decho("setl ma nomod",'~'.expand("<slnum>"))
3684   setl ma nomod noro
3685"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3686
3687"   call Dret("s:NetrwBrowse : file<".s:fname.">")
3688   return
3689  endif
3690
3691  " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
3692  call s:UseBufWinVars()
3693
3694  " set up some variables {{{3
3695  let b:netrw_browser_active = 1
3696  let dirname                = dirname
3697  let s:last_sort_by         = g:netrw_sort_by
3698
3699  " set up menu {{{3
3700  NetrwKeepj call s:NetrwMenu(1)
3701
3702  " get/set-up buffer {{{3
3703"  call Decho("saving position across a buffer refresh",'~'.expand("<slnum>"))
3704  let svpos  = winsaveview()
3705"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3706  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
3707
3708  " maintain markfile highlighting
3709  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3710"   call Decho("bufnr(%)=".bufnr('%'),'~'.expand("<slnum>"))
3711"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
3712   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3713  else
3714"   call Decho("2match none",'~'.expand("<slnum>"))
3715   2match none
3716  endif
3717  if reusing && line("$") > 1
3718   call s:NetrwOptionRestore("w:")
3719"   call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3720   setl noma nomod nowrap
3721"   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>"))
3722"   call Dret("s:NetrwBrowse : re-using not-cleared buffer")
3723   return
3724  endif
3725
3726  " set b:netrw_curdir to the new directory name {{{3
3727"  call Decho("set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")",'~'.expand("<slnum>"))
3728  let b:netrw_curdir= dirname
3729  if b:netrw_curdir =~ '[/\\]$'
3730   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
3731  endif
3732  if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
3733   let b:netrw_curdir= b:netrw_curdir."/"
3734  endif
3735  if b:netrw_curdir == ''
3736   if has("amiga")
3737    " On the Amiga, the empty string connotes the current directory
3738    let b:netrw_curdir= getcwd()
3739   else
3740    " under unix, when the root directory is encountered, the result
3741    " from the preceding substitute is an empty string.
3742    let b:netrw_curdir= '/'
3743   endif
3744  endif
3745  if !a:islocal && b:netrw_curdir !~ '/$'
3746   let b:netrw_curdir= b:netrw_curdir.'/'
3747  endif
3748"  call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
3749
3750  " ------------
3751  " (local only) {{{3
3752  " ------------
3753  if a:islocal
3754"   call Decho("local only:",'~'.expand("<slnum>"))
3755
3756   " Set up ShellCmdPost handling.  Append current buffer to browselist
3757   call s:LocalFastBrowser()
3758
3759  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3760   if !g:netrw_keepdir
3761"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
3762"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("<slnum>"))
3763    if !exists("&l:acd") || !&l:acd
3764     call s:NetrwLcd(b:netrw_curdir)
3765    endif
3766   endif
3767
3768  " --------------------------------
3769  " remote handling: {{{3
3770  " --------------------------------
3771  else
3772"   call Decho("remote only:",'~'.expand("<slnum>"))
3773
3774   " analyze dirname and g:netrw_list_cmd {{{3
3775"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>"))
3776   if dirname =~ "^NetrwTreeListing\>"
3777    let dirname= b:netrw_curdir
3778"    call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>"))
3779   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3780    let dirname= substitute(b:netrw_curdir,'\\','/','g')
3781    if dirname !~ '/$'
3782     let dirname= dirname.'/'
3783    endif
3784    let b:netrw_curdir = dirname
3785"    call Decho("(liststyle is TREELIST) dirname<".dirname.">",'~'.expand("<slnum>"))
3786   else
3787    let dirname = substitute(dirname,'\\','/','g')
3788"    call Decho("(normal) dirname<".dirname.">",'~'.expand("<slnum>"))
3789   endif
3790
3791   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3792   if dirname !~ dirpat
3793    if !exists("g:netrw_quiet")
3794     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3795    endif
3796    NetrwKeepj call s:NetrwOptionRestore("w:")
3797"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3798    setl noma nomod nowrap
3799"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3800"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
3801    return
3802   endif
3803   let b:netrw_curdir= dirname
3804"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("<slnum>"))
3805  endif  " (additional remote handling)
3806
3807  " -----------------------
3808  " Directory Listing: {{{3
3809  " -----------------------
3810  NetrwKeepj call s:NetrwMaps(a:islocal)
3811  NetrwKeepj call s:NetrwCommands(a:islocal)
3812  NetrwKeepj call s:PerformListing(a:islocal)
3813
3814  " restore option(s)
3815  call s:NetrwOptionRestore("w:")
3816"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3817
3818  " If there is a rexposn: restore position with rexposn
3819  " Otherwise            : set rexposn
3820  if exists("s:rexposn_".bufnr("%"))
3821"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
3822   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
3823   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
3824    NetrwKeepj exe w:netrw_bannercnt
3825   endif
3826  else
3827   NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
3828  endif
3829  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
3830   let &l:bexpr= "netrw#BalloonHelp()"
3831"   call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>"))
3832   setl beval
3833  endif
3834
3835  " restore position
3836  if reusing
3837"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3838   call winrestview(svpos)
3839  endif
3840
3841  " The s:LocalBrowseRefresh() function is called by an autocmd
3842  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow, medium speed).
3843  " However, s:NetrwBrowse() causes the FocusGained event to fire the firstt time.
3844"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3845"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3846"  call Dret("s:NetrwBrowse : did PerformListing  ft<".&ft.">")
3847  return
3848endfun
3849
3850" ---------------------------------------------------------------------
3851" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
3852" may not apply correctly; ie. netrw's idea of the current directory may
3853" differ from vim's.  This function insures that netrw's idea of the current
3854" directory is used.
3855fun! s:NetrwFile(fname)
3856"  call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
3857"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'))
3858"  call Decho("g:netrw_cygwin   =".(exists("g:netrw_cygwin")?    g:netrw_cygwin    : 'n/a'))
3859"  call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'))
3860"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'))
3861
3862  " clean up any leading treedepthstring
3863  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
3864   let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
3865"   call Decho("clean up any leading treedepthstring: fname<".fname.">")
3866  else
3867   let fname= a:fname
3868  endif
3869
3870  if g:netrw_keepdir
3871   " vim's idea of the current directory possibly may differ from netrw's
3872   if !exists("b:netrw_curdir")
3873    let b:netrw_curdir= getcwd()
3874   endif
3875
3876   if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
3877    if fname =~ '^\' || fname =~ '^\a:\'
3878     " windows, but full path given
3879     let ret= fname
3880"     call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3881    else
3882     " windows, relative path given
3883     let ret= s:ComposePath(b:netrw_curdir,fname)
3884"     call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3885    endif
3886
3887   elseif fname =~ '^/'
3888    " not windows, full path given
3889    let ret= fname
3890"    call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3891   else
3892    " not windows, relative path given
3893    let ret= s:ComposePath(b:netrw_curdir,fname)
3894"    call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3895   endif
3896  else
3897   " vim and netrw agree on the current directory
3898   let ret= fname
3899"   call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
3900  endif
3901
3902"  call Dret("s:NetrwFile ".ret)
3903  return ret
3904endfun
3905
3906" ---------------------------------------------------------------------
3907" s:NetrwFileInfo: supports qf (query for file information) {{{2
3908fun! s:NetrwFileInfo(islocal,fname)
3909"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
3910  let ykeep= @@
3911  if a:islocal
3912   let lsopt= "-lsad"
3913   if g:netrw_sizestyle =~ 'H'
3914    let lsopt= "-lsadh"
3915   elseif g:netrw_sizestyle =~ 'h'
3916    let lsopt= "-lsadh --si"
3917   endif
3918   if (has("unix") || has("macunix")) && executable("/bin/ls")
3919
3920    if getline(".") == "../"
3921     echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
3922"     call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
3923
3924    elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
3925     echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
3926"     call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
3927
3928    elseif exists("b:netrw_curdir")
3929      echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
3930"      call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
3931
3932    else
3933"     call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
3934     echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
3935"     call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
3936    endif
3937   else
3938    " use vim functions to return information about file below cursor
3939"    call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
3940    if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
3941     let fname= substitute(a:fname,".$","","")
3942    else
3943     let fname= a:fname
3944    endif
3945    let t  = getftime(s:NetrwFile(fname))
3946    let sz = getfsize(s:NetrwFile(fname))
3947    if g:netrw_sizestyle =~ "[hH]"
3948     let sz= s:NetrwHumanReadable(sz)
3949    endif
3950    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
3951"    call Decho("fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
3952   endif
3953  else
3954   echo "sorry, \"qf\" not supported yet for remote files"
3955  endif
3956  let @@= ykeep
3957"  call Dret("s:NetrwFileInfo")
3958endfun
3959
3960" ---------------------------------------------------------------------
3961" s:NetrwGetBuffer: {{{2
3962"   returns 0=cleared buffer
3963"           1=re-used buffer (buffer not cleared)
3964fun! s:NetrwGetBuffer(islocal,dirname)
3965"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
3966"  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>"))
3967  let dirname= a:dirname
3968
3969  " re-use buffer if possible {{{3
3970"  call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
3971  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
3972   " find NetrwTreeList buffer if there is one
3973"   call Decho("case liststyle=treelist: find NetrwTreeList buffer if there is one",'~'.expand("<slnum>"))
3974   if exists("w:netrw_treebufnr") && w:netrw_treebufnr > 0
3975"    call Decho("  re-using w:netrw_treebufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
3976    let eikeep= &ei
3977    setl ei=all
3978    exe "sil! keepj noswapfile keepalt b ".w:netrw_treebufnr
3979    let &ei= eikeep
3980    setl ma
3981    sil! NetrwKeepj %d _
3982"    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>"))
3983"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3984"    call Dret("s:NetrwGetBuffer 0<buffer cleared> : bufnum#".w:netrw_treebufnr."<NetrwTreeListing>")
3985    return 0
3986   endif
3987   let bufnum= -1
3988"   call Decho("  liststyle=TREE but w:netrw_treebufnr doesn't exist",'~'.expand("<slnum>"))
3989
3990  else
3991   " find buffer number of buffer named precisely the same as dirname {{{3
3992"   call Decho("case listtyle not treelist: find buffer numnber of buffer named precisely the same as dirname--",'~'.expand("<slnum>"))
3993"   call Dredir("(NetrwGetBuffer) ls!","ls!")
3994
3995   " get dirname and associated buffer number
3996   let bufnum  = bufnr(escape(dirname,'\'))
3997"   call Decho("  find buffer<".dirname.">'s number ",'~'.expand("<slnum>"))
3998"   call Decho("  bufnr(dirname<".escape(dirname,'\').">)=".bufnum,'~'.expand("<slnum>"))
3999
4000   if bufnum < 0 && dirname !~ '/$'
4001    " try appending a trailing /
4002"    call Decho("  try appending a trailing / to dirname<".dirname.">",'~'.expand("<slnum>"))
4003    let bufnum= bufnr(escape(dirname.'/','\'))
4004    if bufnum > 0
4005     let dirname= dirname.'/'
4006    endif
4007   endif
4008
4009   if bufnum < 0 && dirname =~ '/$'
4010    " try removing a trailing /
4011"    call Decho("  try removing a trailing / from dirname<".dirname.">",'~'.expand("<slnum>"))
4012    let bufnum= bufnr(escape(substitute(dirname,'/$','',''),'\'))
4013    if bufnum > 0
4014     let dirname= substitute(dirname,'/$','','')
4015    endif
4016   endif
4017
4018"   call Decho("  findbuf1: bufnum=bufnr('".dirname."')=".bufnum." bufname(".bufnum.")<".bufname(bufnum)."> (initial)",'~'.expand("<slnum>"))
4019   " note: !~ was used just below, but that means using ../ to go back would match (ie. abc/def/  and abc/ matches)
4020   if bufnum > 0 && bufname(bufnum) != dirname && bufname(bufnum) != '.'
4021    " handle approximate matches
4022"    call Decho("  handling approx match: bufnum#".bufnum.">0 AND bufname<".bufname(bufnum).">!=dirname<".dirname."> AND bufname(".bufnum.")!='.'",'~'.expand("<slnum>"))
4023    let ibuf    = 1
4024    let buflast = bufnr("$")
4025"    call Decho("  findbuf2: buflast=bufnr($)=".buflast,'~'.expand("<slnum>"))
4026    while ibuf <= buflast
4027     let bname= substitute(bufname(ibuf),'\\','/','g')
4028     let bname= substitute(bname,'.\zs/$','','')
4029"     call Decho("  findbuf3: while [ibuf=",ibuf."]<=[buflast=".buflast."]: dirname<".dirname."> bname=bufname(".ibuf.")<".bname.">",'~'.expand("<slnum>"))
4030     if bname != '' && dirname =~ '/'.bname.'/\=$' && dirname !~ '^/'
4031      " bname is not empty
4032      " dirname ends with bname,
4033      " dirname doesn't start with /, so its not a absolute path
4034"      call Decho("  findbuf3a: passes test 1 : dirname<".dirname.'> =~ /'.bname.'/\=$ && dirname !~ ^/','~'.expand("<slnum>"))
4035      break
4036     endif
4037     if bname =~ '^'.dirname.'/\=$'
4038      " bname begins with dirname
4039"      call Decho('  findbuf3b: passes test 2 : bname<'.bname.'>=~^'.dirname.'/\=$','~'.expand("<slnum>"))
4040      break
4041     endif
4042     if dirname =~ '^'.bname.'/$'
4043"      call Decho('  findbuf3c: passes test 3 : dirname<'.dirname.'>=~^'.bname.'/$','~'.expand("<slnum>"))
4044      break
4045     endif
4046     if bname != '' && dirname =~ '/'.bname.'$' && bname == bufname("%") && line("$") == 1
4047"      call Decho('  findbuf3d: passes test 4 : dirname<'.dirname.'>=~ /'.bname.'$','~'.expand("<slnum>"))
4048      break
4049     endif
4050     let ibuf= ibuf + 1
4051    endwhile
4052    if ibuf > buflast
4053     let bufnum= -1
4054    else
4055     let bufnum= ibuf
4056    endif
4057"    call Decho("  findbuf4: bufnum=".bufnum." (ibuf=".ibuf." buflast=".buflast.")",'~'.expand("<slnum>"))
4058   endif
4059  endif
4060
4061  " get enew buffer and name it -or- re-use buffer {{{3
4062  if bufnum < 0 || !bufexists(bufnum)   " get enew buffer and name it
4063"   call Decho("--get enew buffer and name it  (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4064   call s:NetrwEnew(dirname)
4065"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4066   " name the buffer
4067   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4068    " Got enew buffer; transform into a NetrwTreeListing
4069"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4070    if !exists("s:netrw_treelistnum")
4071     let s:netrw_treelistnum= 1
4072    else
4073     let s:netrw_treelistnum= s:netrw_treelistnum + 1
4074    endif
4075    let w:netrw_treebufnr= bufnr("%")
4076"    call Decho("  exe sil! keepalt file NetrwTreeListing ".fnameescape(s:netrw_treelistnum),'~'.expand("<slnum>"))
4077    exe 'sil! keepalt file NetrwTreeListing\ '.fnameescape(s:netrw_treelistnum)
4078    if g:netrw_use_noswf
4079     setl nobl bt=nofile noswf
4080    else
4081     setl nobl bt=nofile
4082    endif
4083    nnoremap <silent> <buffer> [[       :sil call <SID>TreeListMove('[[')<cr>
4084    nnoremap <silent> <buffer> ]]       :sil call <SID>TreeListMove(']]')<cr>
4085    nnoremap <silent> <buffer> []       :sil call <SID>TreeListMove('[]')<cr>
4086    nnoremap <silent> <buffer> ][       :sil call <SID>TreeListMove('][')<cr>
4087"    call Decho("  tree listing#".s:netrw_treelistnum." bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
4088   else
4089"    let v:errmsg   = "" " Decho
4090    let escdirname = fnameescape(dirname)
4091"    call Decho("  errmsg<".v:errmsg."> bufnr(escdirname<".escdirname.">)=".bufnr(escdirname)." bufname()<".bufname(bufnr(escdirname)).">",'~'.expand("<slnum>"))
4092"    call Decho('  exe sil! keepalt file '.escdirname,'~'.expand("<slnum>"))
4093"    let v:errmsg= "" " Decho
4094    exe 'sil! keepj keepalt file '.escdirname
4095"    call Decho("  errmsg<".v:errmsg."> bufnr(".escdirname.")=".bufnr(escdirname)."<".bufname(bufnr(escdirname)).">",'~'.expand("<slnum>"))
4096   endif
4097"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4098
4099  else " Re-use the buffer
4100"   call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4101   let eikeep= &ei
4102   setl ei=all
4103   if getline(2) =~ '^" Netrw Directory Listing'
4104"    call Decho("  getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>"))
4105    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4106   else
4107"    call Decho("  getline(2)<".getline(2).'> does not match "Netrw Directory Listing" : using b '.bufnum,'~'.expand("<slnum>"))
4108    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4109   endif
4110"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
4111   if bufname("%") == '.'
4112"    call Decho("exe sil! keepalt file ".fnameescape(getcwd()),'~'.expand("<slnum>"))
4113    exe "sil! NetrwKeepj keepalt file ".fnameescape(getcwd())
4114   endif
4115   let &ei= eikeep
4116
4117   if line("$") <= 1 && getline(1) == ""
4118    " empty buffer
4119    NetrwKeepj call s:NetrwListSettings(a:islocal)
4120"    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>"))
4121"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4122"    call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4123    return 0
4124
4125   elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4126"    call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4127    NetrwKeepj call s:NetrwListSettings(a:islocal)
4128    sil NetrwKeepj %d _
4129"    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>"))
4130"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4131"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4132    return 0
4133
4134   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4135"    call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4136"    call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4137    sil NetrwKeepj %d _
4138    NetrwKeepj call s:NetrwListSettings(a:islocal)
4139"    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>"))
4140"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4141"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4142    return 0
4143
4144   else
4145"    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>"))
4146"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4147"    call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4148    return 1
4149   endif
4150  endif
4151
4152  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4153  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
4154  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
4155  "  med    1         D      H
4156  "  fast   2         H      H
4157"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
4158  let fname= expand("%")
4159  NetrwKeepj call s:NetrwListSettings(a:islocal)
4160"  call Decho("exe sil! keepalt file ".fnameescape(fname),'~'.expand("<slnum>"))
4161  exe "sil! NetrwKeepj keepalt file ".fnameescape(fname)
4162
4163  " delete all lines from buffer {{{3
4164"  call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4165"  call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4166  sil! keepalt NetrwKeepj %d _
4167
4168"  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>"))
4169"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4170"  call Dret("s:NetrwGetBuffer 0<cleared buffer>")
4171  return 0
4172endfun
4173
4174" ---------------------------------------------------------------------
4175" s:NetrwGetcwd: get the current directory. {{{2
4176"   Change backslashes to forward slashes, if any.
4177"   If doesc is true, escape certain troublesome characters
4178fun! s:NetrwGetcwd(doesc)
4179"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
4180  let curdir= substitute(getcwd(),'\\','/','ge')
4181  if curdir !~ '[\/]$'
4182   let curdir= curdir.'/'
4183  endif
4184  if a:doesc
4185   let curdir= fnameescape(curdir)
4186  endif
4187"  call Dret("NetrwGetcwd <".curdir.">")
4188  return curdir
4189endfun
4190
4191" ---------------------------------------------------------------------
4192"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4193fun! s:NetrwGetWord()
4194"  call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4195"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4196  let keepsol= &l:sol
4197  setl nosol
4198
4199  call s:UseBufWinVars()
4200
4201  " insure that w:netrw_liststyle is set up
4202  if !exists("w:netrw_liststyle")
4203   if exists("g:netrw_liststyle")
4204    let w:netrw_liststyle= g:netrw_liststyle
4205   else
4206    let w:netrw_liststyle= s:THINLIST
4207   endif
4208"   call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
4209  endif
4210
4211  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4212   " Active Banner support
4213"   call Decho("active banner handling",'~'.expand("<slnum>"))
4214   NetrwKeepj norm! 0
4215   let dirname= "./"
4216   let curline= getline('.')
4217
4218   if curline =~ '"\s*Sorted by\s'
4219    NetrwKeepj norm s
4220    let s:netrw_skipbrowse= 1
4221    echo 'Pressing "s" also works'
4222
4223   elseif curline =~ '"\s*Sort sequence:'
4224    let s:netrw_skipbrowse= 1
4225    echo 'Press "S" to edit sorting sequence'
4226
4227   elseif curline =~ '"\s*Quick Help:'
4228    NetrwKeepj norm ?
4229    let s:netrw_skipbrowse= 1
4230
4231   elseif curline =~ '"\s*\%(Hiding\|Showing\):'
4232    NetrwKeepj norm a
4233    let s:netrw_skipbrowse= 1
4234    echo 'Pressing "a" also works'
4235
4236   elseif line("$") > w:netrw_bannercnt
4237    exe 'sil NetrwKeepj '.w:netrw_bannercnt
4238   endif
4239
4240  elseif w:netrw_liststyle == s:THINLIST
4241"   call Decho("thin column handling",'~'.expand("<slnum>"))
4242   NetrwKeepj norm! 0
4243   let dirname= substitute(getline('.'),'\t -->.*$','','')
4244
4245  elseif w:netrw_liststyle == s:LONGLIST
4246"   call Decho("long column handling",'~'.expand("<slnum>"))
4247   NetrwKeepj norm! 0
4248   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
4249
4250  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4251"   call Decho("treelist handling",'~'.expand("<slnum>"))
4252   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4253   let dirname= substitute(dirname,'\t -->.*$','','')
4254
4255  else
4256"   call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4257   let dirname= getline('.')
4258
4259   if !exists("b:netrw_cpf")
4260    let b:netrw_cpf= 0
4261    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
4262    call histdel("/",-1)
4263"   "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4264   endif
4265
4266"   call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4267   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4268"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4269"   call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4270   if filestart == 0
4271    NetrwKeepj norm! 0ma
4272   else
4273    call cursor(line("."),filestart+1)
4274    NetrwKeepj norm! ma
4275   endif
4276   let rega= @a
4277   let eofname= filestart + b:netrw_cpf + 1
4278   if eofname <= col("$")
4279    call cursor(line("."),filestart+b:netrw_cpf+1)
4280    NetrwKeepj norm! "ay`a
4281   else
4282    NetrwKeepj norm! "ay$
4283   endif
4284   let dirname = @a
4285   let @a      = rega
4286"   call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4287   let dirname= substitute(dirname,'\s\+$','','e')
4288"   call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4289  endif
4290
4291  " symlinks are indicated by a trailing "@".  Remove it before further processing.
4292  let dirname= substitute(dirname,"@$","","")
4293
4294  " executables are indicated by a trailing "*".  Remove it before further processing.
4295  let dirname= substitute(dirname,"\*$","","")
4296
4297  let &l:sol= keepsol
4298
4299"  call Dret("s:NetrwGetWord <".dirname.">")
4300  return dirname
4301endfun
4302
4303" ---------------------------------------------------------------------
4304" s:NetrwListSettings: make standard settings for a netrw listing {{{2
4305fun! s:NetrwListSettings(islocal)
4306"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4307"  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>"))
4308  let fname= bufname("%")
4309"  "  call Decho("(NetrwListSettings) setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
4310  setl bt=nofile nobl ma nonu nowrap noro nornu
4311"  call Decho("(NetrwListSettings) exe sil! keepalt file ".fnameescape(fname),'~'.expand("<slnum>"))
4312  exe "sil! keepalt file ".fnameescape(fname)
4313  if g:netrw_use_noswf
4314   setl noswf
4315  endif
4316"  call Dredir("ls!")
4317"  call Decho("(NetrwListSettings) exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
4318  exe "setl ts=".(g:netrw_maxfilenamelen+1)
4319  setl isk+=.,~,-
4320  if g:netrw_fastbrowse > a:islocal
4321   setl bh=hide
4322  else
4323   setl bh=delete
4324  endif
4325"  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>"))
4326"  call Dret("s:NetrwListSettings")
4327endfun
4328
4329" ---------------------------------------------------------------------
4330"  s:NetrwListStyle: {{{2
4331"  islocal=0: remote browsing
4332"         =1: local browsing
4333fun! s:NetrwListStyle(islocal)
4334"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
4335
4336  let ykeep             = @@
4337  let fname             = s:NetrwGetWord()
4338  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
4339  let svpos            = winsaveview()
4340"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4341  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
4342"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
4343"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>"))
4344"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
4345
4346  if w:netrw_liststyle == s:THINLIST
4347   " use one column listing
4348"   call Decho("use one column list",'~'.expand("<slnum>"))
4349   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4350
4351  elseif w:netrw_liststyle == s:LONGLIST
4352   " use long list
4353"   call Decho("use long list",'~'.expand("<slnum>"))
4354   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
4355
4356  elseif w:netrw_liststyle == s:WIDELIST
4357   " give wide list
4358"   call Decho("use wide list",'~'.expand("<slnum>"))
4359   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4360
4361  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4362"   call Decho("use tree list",'~'.expand("<slnum>"))
4363   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4364
4365  else
4366   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4367   let g:netrw_liststyle = s:THINLIST
4368   let w:netrw_liststyle = g:netrw_liststyle
4369   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
4370  endif
4371  setl ma noro
4372"  call Decho("setl ma noro",'~'.expand("<slnum>"))
4373
4374  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
4375"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4376  sil! NetrwKeepj %d _
4377  " following prevents tree listing buffer from being marked "modified"
4378"  call Decho("setl nomod",'~'.expand("<slnum>"))
4379  setl nomod
4380"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4381
4382  " refresh the listing
4383"  call Decho("refresh the listing",'~'.expand("<slnum>"))
4384  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4385  NetrwKeepj call s:NetrwCursor()
4386
4387  " restore position; keep cursor on the filename
4388"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4389  NetrwKeepj call winrestview(svpos)
4390  let @@= ykeep
4391
4392"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
4393endfun
4394
4395" ---------------------------------------------------------------------
4396" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4397fun! s:NetrwBannerCtrl(islocal)
4398"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
4399
4400  let ykeep= @@
4401  " toggle the banner (enable/suppress)
4402  let g:netrw_banner= !g:netrw_banner
4403
4404  " refresh the listing
4405  let svpos= winsaveview()
4406"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4407  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4408
4409  " keep cursor on the filename
4410  let fname= s:NetrwGetWord()
4411  sil NetrwKeepj $
4412  let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4413"  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4414  if result <= 0 && exists("w:netrw_bannercnt")
4415   exe "NetrwKeepj ".w:netrw_bannercnt
4416  endif
4417  let @@= ykeep
4418"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
4419endfun
4420
4421" ---------------------------------------------------------------------
4422" s:NetrwBookmark: supports :NetrwMB[!] [file]s                 {{{2
4423"
4424"  No bang: enters files/directories into Netrw's bookmark system
4425"   No argument and in netrw buffer:
4426"     if there are marked files: bookmark marked files
4427"     otherwise                : bookmark file/directory under cursor
4428"   No argument and not in netrw buffer: bookmarks current open file
4429"   Has arguments: globs them individually and bookmarks them
4430"
4431"  With bang: deletes files/directories from Netrw's bookmark system
4432fun! s:NetrwBookmark(del,...)
4433"  call Dfunc("s:NetrwBookmark(del=".a:del.",...) a:0=".a:0)
4434  if a:0 == 0
4435   if &ft == "netrw"
4436    let curbufnr = bufnr("%")
4437
4438    if exists("s:netrwmarkfilelist_{curbufnr}")
4439     " for every filename in the marked list
4440"     call Decho("bookmark every filename in marked list",'~'.expand("<slnum>"))
4441     let svpos  = winsaveview()
4442"     call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4443     let islocal= expand("%") !~ '^\a\{3,}://'
4444     for fname in s:netrwmarkfilelist_{curbufnr}
4445      if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4446     endfor
4447     let curdir  = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4448     call s:NetrwUnmarkList(curbufnr,curdir)
4449     NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./'))
4450"     call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4451     NetrwKeepj call winrestview(svpos)
4452    else
4453     let fname= s:NetrwGetWord()
4454     if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4455    endif
4456
4457   else
4458    " bookmark currently open file
4459"    call Decho("bookmark currently open file",'~'.expand("<slnum>"))
4460    let fname= expand("%")
4461    if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4462   endif
4463
4464  else
4465   " bookmark specified files
4466   "  attempts to infer if working remote or local
4467   "  by deciding if the current file begins with an url
4468   "  Globbing cannot be done remotely.
4469   let islocal= expand("%") !~ '^\a\{3,}://'
4470"   call Decho("bookmark specified file".((a:0>1)? "s" : ""),'~'.expand("<slnum>"))
4471   let i = 1
4472   while i <= a:0
4473    if islocal
4474     if v:version == 704 && has("patch656")
4475      let mbfiles= glob(a:{i},0,1,1)
4476     else
4477      let mbfiles= glob(a:{i},0,1)
4478     endif
4479    else
4480     let mbfiles= [a:{i}]
4481    endif
4482"    call Decho("mbfiles".string(mbfiles),'~'.expand("<slnum>"))
4483    for mbfile in mbfiles
4484"     call Decho("mbfile<".mbfile.">",'~'.expand("<slnum>"))
4485     if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4486    endfor
4487    let i= i + 1
4488   endwhile
4489  endif
4490
4491  " update the menu
4492  call s:NetrwBookmarkMenu()
4493
4494"  call Dret("s:NetrwBookmark")
4495endfun
4496
4497" ---------------------------------------------------------------------
4498" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4499"                      .2.[cnt] for bookmarks, and
4500"                      .3.[cnt] for history
4501"                      (see s:NetrwMenu())
4502fun! s:NetrwBookmarkMenu()
4503  if !exists("s:netrw_menucnt")
4504   return
4505  endif
4506"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhist_cnt." menucnt=".s:netrw_menucnt)
4507
4508  " the following test assures that gvim is running, has menus available, and has menus enabled.
4509  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
4510   if exists("g:NetrwTopLvlMenu")
4511"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4512    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4513    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4514   endif
4515   if !exists("s:netrw_initbookhist")
4516    call s:NetrwBookHistRead()
4517   endif
4518
4519   " show bookmarked places
4520   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4521    let cnt= 1
4522    for bmd in g:netrw_bookmarklist
4523"     call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd,'~'.expand("<slnum>"))
4524     let bmd= escape(bmd,g:netrw_menu_escape)
4525
4526     " show bookmarks for goto menu
4527     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
4528
4529     " show bookmarks for deletion menu
4530     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
4531     let cnt= cnt + 1
4532    endfor
4533
4534   endif
4535
4536   " show directory browsing history
4537   if g:netrw_dirhistmax > 0
4538    let cnt     = g:netrw_dirhist_cnt
4539    let first   = 1
4540    let histcnt = 0
4541    while ( first || cnt != g:netrw_dirhist_cnt )
4542     let histcnt  = histcnt + 1
4543     let priority = g:netrw_dirhist_cnt + histcnt
4544     if exists("g:netrw_dirhist_{cnt}")
4545      let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4546"     call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir,'~'.expand("<slnum>"))
4547      exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
4548     endif
4549     let first = 0
4550     let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
4551     if cnt < 0
4552      let cnt= cnt + g:netrw_dirhistmax
4553     endif
4554    endwhile
4555   endif
4556
4557  endif
4558"  call Dret("NetrwBookmarkMenu")
4559endfun
4560
4561" ---------------------------------------------------------------------
4562"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4563"                       directory and a new directory name.  Also, if the
4564"                       "new directory name" is actually a file,
4565"                       NetrwBrowseChgDir() edits the file.
4566fun! s:NetrwBrowseChgDir(islocal,newdir,...)
4567"  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 : "").">")
4568"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4569
4570  let ykeep= @@
4571  if !exists("b:netrw_curdir")
4572   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4573   " and the current window is the NetrwMessage window.
4574   let @@= ykeep
4575"   call Decho("b:netrw_curdir doesn't exist!",'~'.expand("<slnum>"))
4576"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
4577"   call Dredir("ls!")
4578"   call Dret("s:NetrwBrowseChgDir")
4579   return
4580  endif
4581
4582  " NetrwBrowseChgDir: save options and initialize {{{3
4583"  call Decho("saving options",'~'.expand("<slnum>"))
4584  NetrwKeepj call s:NetrwOptionSave("s:")
4585  NetrwKeepj call s:NetrwSafeOptions()
4586  let nbcd_curpos                = winsaveview()
4587"  call Decho("saving posn to nbcd_curpos<".string(nbcd_curpos).">",'~'.expand("<slnum>"))
4588  let s:nbcd_curpos_{bufnr('%')} = nbcd_curpos
4589  if (has("win32") || has("win95") || has("win64") || has("win16"))
4590   let dirname = substitute(b:netrw_curdir,'\\','/','ge')
4591  else
4592   let dirname = b:netrw_curdir
4593  endif
4594  let newdir    = a:newdir
4595  let dolockout = 0
4596  let dorestore = 1
4597"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
4598
4599  " ignore <cr>s when done in the banner
4600"  call Decho('ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("<slnum>"))
4601  if g:netrw_banner
4602"   call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>"))
4603   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4604    if getline(".") =~ 'Quick Help'
4605"     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>"))
4606     let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4607"     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>"))
4608     setl ma noro nowrap
4609     NetrwKeepj call setline(line('.'),'"   Quick Help: <F1>:help  '.s:QuickHelp[g:netrw_quickhelp])
4610     setl noma nomod nowrap
4611"     call Decho("restoring posn to nbcd_curpos<".string(nbcd_curpos).">",'~'.expand("<slnum>"))
4612     NetrwKeepj call winrestview(nbcd_curpos)
4613     NetrwKeepj call s:NetrwOptionRestore("s:")
4614"     call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4615    endif
4616   endif
4617"  else " Decho
4618"   call Decho("(s:NetrwBrowseChgdir) g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("<slnum>"))
4619  endif
4620
4621  " set up o/s-dependent directory recognition pattern
4622  if has("amiga")
4623   let dirpat= '[\/:]$'
4624  else
4625   let dirpat= '[\/]$'
4626  endif
4627"  call Decho("set up o/s-dependent directory recognition pattern: dirname<".dirname.">  dirpat<".dirpat.">",'~'.expand("<slnum>"))
4628
4629  if dirname !~ dirpat
4630   " apparently vim is "recognizing" that it is in a directory and
4631   " is removing the trailing "/".  Bad idea, so let's put it back.
4632   let dirname= dirname.'/'
4633"   call Decho("adjusting dirname<".dirname.'>  (put trailing "/" back)','~'.expand("<slnum>"))
4634  endif
4635
4636"  "  call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>"))
4637  if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
4638   " ------------------------------
4639   " NetrwBrowseChgDir: edit a file {{{3
4640   " ------------------------------
4641"   call Decho('edit-a-file: case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>"))
4642
4643   " save position for benefit of Rexplore
4644   let s:rexposn_{bufnr("%")}= winsaveview()
4645"   call Decho("edit-a-file: saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
4646"   call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
4647"   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>"))
4648
4649   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4650"    call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("<slnum>"))
4651"    call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("<slnum>"))
4652    let dirname= s:NetrwTreeDir(a:islocal)
4653    if dirname =~ '/$'
4654     let dirname= dirname.newdir
4655    else
4656     let dirname= dirname."/".newdir
4657    endif
4658"    call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>"))
4659"    call Decho("edit-a-file: tree listing",'~'.expand("<slnum>"))
4660   elseif newdir =~ '^\(/\|\a:\)'
4661"    call Decho("edit-a-file: handle an url or path starting with /: <".newdir.">")
4662    let dirname= newdir
4663   else
4664    let dirname= s:ComposePath(dirname,newdir)
4665   endif
4666"   call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>"))
4667   " this lets netrw#BrowseX avoid the edit
4668   if a:0 < 1
4669"    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>"))
4670    NetrwKeepj call s:NetrwOptionRestore("s:")
4671    let curdir= b:netrw_curdir
4672    if !exists("s:didsplit")
4673"     call Decho("edit-a-file: s:didsplit does not exist; g:netrw_browse_split=".string(g:netrw_browse_split)." win#".winnr(),'~'.expand("<slnum>"))
4674     if type(g:netrw_browse_split) == 3
4675      " open file in server
4676      " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4677"      call Decho("edit-a-file: open file in server",'~'.expand("<slnum>"))
4678      call s:NetrwServerEdit(a:islocal,dirname)
4679"      call Dret("s:NetrwBrowseChgDir")
4680      return
4681     elseif g:netrw_browse_split == 1
4682      " horizontally splitting the window first
4683"      call Decho("edit-a-file: horizontally splitting window prior to edit",'~'.expand("<slnum>"))
4684      keepalt new
4685      if !&ea
4686       keepalt wincmd _
4687      endif
4688      call s:SetRexDir(a:islocal,b:netrw_curdir)
4689     elseif g:netrw_browse_split == 2
4690      " vertically splitting the window first
4691"      call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>"))
4692      keepalt rightb vert new
4693      if !&ea
4694       keepalt wincmd |
4695      endif
4696      call s:SetRexDir(a:islocal,b:netrw_curdir)
4697     elseif g:netrw_browse_split == 3
4698      " open file in new tab
4699"      call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>"))
4700      keepalt tabnew
4701      call s:SetRexDir(a:islocal,b:netrw_curdir)
4702     elseif g:netrw_browse_split == 4
4703      " act like "P" (ie. open previous window)
4704"      call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>"))
4705      if s:NetrwPrevWinOpen(2) == 3
4706       let @@= ykeep
4707"       call Dret("s:NetrwBrowseChgDir")
4708       return
4709      endif
4710      call s:SetRexDir(a:islocal,b:netrw_curdir)
4711     else
4712      " handling a file, didn't split, so remove menu
4713"      call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>"))
4714      call s:NetrwMenu(0)
4715      " optional change to window
4716      if g:netrw_chgwin >= 1
4717"       call Decho("edit-a-file: changing window to #".g:netrw_chgwin,'~'.expand("<slnum>"))
4718       if winnr("$")+1 == g:netrw_chgwin
4719	" if g:netrw_chgwin is set to one more than the last window, then
4720	" vertically split the last window to make that window available.
4721	let curwin= winnr()
4722	exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4723	vs
4724	exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4725       endif
4726       exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4727      endif
4728      call s:SetRexDir(a:islocal,curdir)
4729     endif
4730    endif
4731
4732    " the point where netrw actually edits the (local) file
4733    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4734    " no keepalt to support  :e #  to return to a directory listing
4735    if a:islocal
4736"     call Decho("edit-a-file: edit local file: exe e! ".fnameescape(dirname),'~'.expand("<slnum>"))
4737     " some like c-^ to return to the last edited file
4738     " others like c-^ to return to the netrw buffer
4739     if exists("g:netrw_altfile") && g:netrw_altfile
4740      exe "NetrwKeepj keepalt e! ".fnameescape(dirname)
4741     else
4742      exe "NetrwKeepj e! ".fnameescape(dirname)
4743     endif
4744"     call Decho("edit-a-file: after e! ".dirname.": hidden=".&hidden." bufhidden<".&bufhidden."> mod=".&mod,'~'.expand("<slnum>"))
4745     call s:NetrwCursor()
4746     if &hidden || &bufhidden == "hide"
4747      " file came from vim's hidden storage.  Don't "restore" options with it.
4748      let dorestore= 0
4749     endif
4750    else
4751"     call Decho("edit-a-file: remote file: NetrwBrowse will edit it",'~'.expand("<slnum>"))
4752    endif
4753    let dolockout= 1
4754
4755    " handle g:Netrw_funcref -- call external-to-netrw functions
4756    "   This code will handle g:Netrw_funcref as an individual function reference
4757    "   or as a list of function references.  It will ignore anything that's not
4758    "   a function reference.  See  :help Funcref  for information about function references.
4759    if exists("g:Netrw_funcref")
4760"     call Decho("edit-a-file: handle optional Funcrefs",'~'.expand("<slnum>"))
4761     if type(g:Netrw_funcref) == 2
4762"      call Decho("edit-a-file: handling a g:Netrw_funcref",'~'.expand("<slnum>"))
4763      NetrwKeepj call g:Netrw_funcref()
4764     elseif type(g:Netrw_funcref) == 3
4765"      call Decho("edit-a-file: handling a list of g:Netrw_funcrefs",'~'.expand("<slnum>"))
4766      for Fncref in g:Netrw_funcref
4767       if type(FncRef) == 2
4768        NetrwKeepj call FncRef()
4769       endif
4770      endfor
4771     endif
4772    endif
4773   endif
4774
4775  elseif newdir =~ '^/'
4776   " ----------------------------------------------------
4777   " NetrwBrowseChgDir: just go to the new directory spec {{{3
4778   " ----------------------------------------------------
4779"   call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("<slnum>"))
4780   let dirname = newdir
4781   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4782   NetrwKeepj call s:NetrwOptionRestore("s:")
4783   norm! m`
4784
4785  elseif newdir == './'
4786   " ---------------------------------------------
4787   " NetrwBrowseChgDir: refresh the directory list {{{3
4788   " ---------------------------------------------
4789"   call Decho('refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("<slnum>"))
4790   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4791   norm! m`
4792
4793  elseif newdir == '../'
4794   " --------------------------------------
4795   " NetrwBrowseChgDir: go up one directory {{{3
4796   " --------------------------------------
4797"   call Decho('go-up: case "go up one directory": newdir == "../"','~'.expand("<slnum>"))
4798
4799   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4800    " force a refresh
4801"    call Decho("go-up: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4802"    call Decho("go-up: setl noro ma",'~'.expand("<slnum>"))
4803    setl noro ma
4804    NetrwKeepj %d _
4805   endif
4806
4807   if has("amiga")
4808    " amiga
4809"    call Decho('go-up: case "go up one directory": newdir == "../" and amiga','~'.expand("<slnum>"))
4810    if a:islocal
4811     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
4812     let dirname= substitute(dirname,'/$','','')
4813    else
4814     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
4815    endif
4816"    call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4817
4818   elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
4819    " windows
4820    if a:islocal
4821     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4822     if dirname == ""
4823      let dirname= '/'
4824     endif
4825    else
4826     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4827    endif
4828    if dirname =~ '^\a:$'
4829     let dirname= dirname.'/'
4830    endif
4831"    call Decho("go-up: windows: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4832
4833   else
4834    " unix or cygwin
4835"    call Decho('go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("<slnum>"))
4836    if a:islocal
4837     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4838     if dirname == ""
4839      let dirname= '/'
4840     endif
4841    else
4842     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4843    endif
4844"    call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4845   endif
4846   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4847   norm m`
4848
4849  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4850   " --------------------------------------
4851   " NetrwBrowseChgDir: Handle Tree Listing {{{3
4852   " --------------------------------------
4853"   call Decho('tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("<slnum>"))
4854   " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
4855"   call Decho("tree-list: setl noro ma",'~'.expand("<slnum>"))
4856   setl noro ma
4857   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
4858"    call Decho("tree-list: clear buffer<".expand("%")."> with :%d  (force refresh)",'~'.expand("<slnum>"))
4859    NetrwKeepj %d _
4860   endif
4861   let treedir      = s:NetrwTreeDir(a:islocal)
4862"   call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>"))
4863   let s:treecurpos = nbcd_curpos
4864   let haskey       = 0
4865"   call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
4866
4867   " search treedict for tree dir as-is
4868"   call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("<slnum>"))
4869   if has_key(w:netrw_treedict,treedir)
4870"    call Decho('tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>"))
4871    let haskey= 1
4872   else
4873"    call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
4874   endif
4875
4876   " search treedict for treedir with a [/@] appended
4877"   call Decho("tree-list: search treedict for treedir with a [/@] appended",'~'.expand("<slnum>"))
4878   if !haskey && treedir !~ '[/@]$'
4879    if has_key(w:netrw_treedict,treedir."/")
4880     let treedir= treedir."/"
4881"     call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
4882     let haskey = 1
4883    else
4884"     call Decho('tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("<slnum>"))
4885    endif
4886   endif
4887
4888   " search treedict for treedir with any trailing / elided
4889"   call Decho("tree-list: search treedict for treedir with any trailing / elided",'~'.expand("<slnum>"))
4890   if !haskey && treedir =~ '/$'
4891    let treedir= substitute(treedir,'/$','','')
4892    if has_key(w:netrw_treedict,treedir)
4893"     call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
4894     let haskey = 1
4895    else
4896"     call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
4897    endif
4898   endif
4899
4900"   call Decho("haskey=".haskey,'~'.expand("<slnum>"))
4901   if haskey
4902    " close tree listing for selected subdirectory
4903"    call Decho("tree-list: closing selected subdirectory<".dirname.">",'~'.expand("<slnum>"))
4904    call remove(w:netrw_treedict,treedir)
4905"    call Decho("tree-list: removed     entry<".treedir."> from treedict",'~'.expand("<slnum>"))
4906"    call Decho("tree-list: yielding treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
4907    let dirname= w:netrw_treetop
4908   else
4909    " go down one directory
4910    let dirname= substitute(treedir,'/*$','/','')
4911"    call Decho("tree-list: go down one dir: treedir<".treedir.">",'~'.expand("<slnum>"))
4912"    call Decho("tree-list: ...            : dirname<".dirname.">",'~'.expand("<slnum>"))
4913   endif
4914   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4915"   call Decho("setting s:treeforceredraw to true",'~'.expand("<slnum>"))
4916   let s:treeforceredraw = 1
4917
4918  else
4919   " ----------------------------------------
4920   " NetrwBrowseChgDir: Go down one directory {{{3
4921   " ----------------------------------------
4922   let dirname    = s:ComposePath(dirname,newdir)
4923"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("<slnum>"))
4924   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4925   norm m`
4926  endif
4927
4928 " --------------------------------------
4929 " NetrwBrowseChgDir: Restore and Cleanup {{{3
4930 " --------------------------------------
4931  if dorestore
4932   " dorestore is zero'd when a local file was hidden or bufhidden;
4933   " in such a case, we want to keep whatever settings it may have.
4934"   call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("<slnum>"))
4935   NetrwKeepj call s:NetrwOptionRestore("s:")
4936"  else " Decho
4937"   call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>"))
4938  endif
4939  if dolockout && dorestore
4940"   call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>"))
4941   if filewritable(dirname)
4942"    call Decho("restore: doing modification lockout settings: ma nomod noro",'~'.expand("<slnum>"))
4943"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
4944    setl ma noro nomod
4945"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4946   else
4947"    call Decho("restore: doing modification lockout settings: ma nomod ro",'~'.expand("<slnum>"))
4948"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
4949    setl ma ro nomod
4950"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4951   endif
4952  endif
4953  let @@= ykeep
4954
4955"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
4956  return dirname
4957endfun
4958
4959" ---------------------------------------------------------------------
4960" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
4961"    for thin, long, and wide: cursor placed just after banner
4962"    for tree, keeps cursor on current filename
4963fun! s:NetrwBrowseUpDir(islocal)
4964"  call Dfunc("s:NetrwBrowseUpDir(islocal=".a:islocal.")")
4965  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
4966   " this test needed because occasionally this function seems to be incorrectly called
4967   " when multiple leftmouse clicks are taken when atop the one line help in the banner.
4968   " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
4969   " directories.
4970"   call Dret("s:NetrwBrowseUpDir : cursor not in file area")
4971   return
4972  endif
4973
4974  norm! 0
4975  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4976"   call Decho("case: treestyle",'~'.expand("<slnum>"))
4977   let curline= getline(".")
4978   let swwline= winline() - 1
4979   if exists("w:netrw_treetop")
4980    let b:netrw_curdir= w:netrw_treetop
4981   endif
4982   let curdir= b:netrw_curdir
4983   if a:islocal
4984    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
4985   else
4986    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
4987   endif
4988   if !search('\c^'.s:treedepthstring.curline,'cw')
4989    if !search('\c^'.curline,'cw')
4990     sil! NetrwKeepj 1
4991    endif
4992   endif
4993   exe "sil! NetrwKeepj norm! z\<cr>"
4994   while winline() < swwline
4995    let curwinline= winline()
4996    exe "sil! NetrwKeepj norm! \<c-y>"
4997    if curwinline == winline()
4998     break
4999    endif
5000   endwhile
5001  else
5002"   call Decho("case: not treestyle",'~'.expand("<slnum>"))
5003   if exists("b:netrw_curdir")
5004    let curdir= b:netrw_curdir
5005   else
5006    let curdir= expand(getcwd())
5007   endif
5008   if a:islocal
5009    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5010   else
5011    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5012   endif
5013   if exists("w:netrw_bannercnt")
5014"    call Decho("moving to line#".w:netrw_bannercnt,'~'.expand("<slnum>"))
5015    exe w:netrw_bannercnt
5016   else
5017    1
5018   endif
5019  endif
5020  let curdir= substitute(curdir,'^.*[\/]','','')
5021  call search('\<'.curdir.'\>','wc')
5022"  call Dret("s:NetrwBrowseUpDir")
5023endfun
5024
5025" ---------------------------------------------------------------------
5026" netrw#BrowseX:  (implements "x") executes a special "viewer" script or program for the {{{2
5027"              given filename; typically this means given their extension.
5028"              0=local, 1=remote
5029fun! netrw#BrowseX(fname,remote)
5030"  call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")")
5031
5032  " if its really just a directory, then do a "gf" instead
5033  if (a:remote == 0 && isdirectory(a:fname)) || (a:remote == 1 && fname =~ '/$' && fname !~ '^https\=:')
5034   norm! gf
5035"   call Dret("netrw#BrowseX : did gf instead")
5036  endif
5037
5038
5039  let ykeep      = @@
5040  let screenposn = winsaveview()
5041"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5042
5043  " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
5044  let awkeep     = &aw
5045  set noaw
5046
5047  " special core dump handler
5048  if a:fname =~ '/core\(\.\d\+\)\=$'
5049   if exists("g:Netrw_corehandler")
5050    if type(g:Netrw_corehandler) == 2
5051     " g:Netrw_corehandler is a function reference (see :help Funcref)
5052"     call Decho("g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
5053     call g:Netrw_corehandler(s:NetrwFile(a:fname))
5054    elseif type(g:Netrw_corehandler) == 3
5055     " g:Netrw_corehandler is a List of function references (see :help Funcref)
5056"     call Decho("g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
5057     for Fncref in g:Netrw_corehandler
5058      if type(FncRef) == 2
5059       call FncRef(a:fname)
5060      endif
5061     endfor
5062    endif
5063"    call Decho("restoring posn to screenposn<".string(screenposn).">,'~'.expand("<slnum>"))"
5064    call winrestview(screenposn)
5065    let @@= ykeep
5066    let &aw= awkeep
5067"    call Dret("netrw#BrowseX : coredump handler invoked")
5068    return
5069   endif
5070  endif
5071
5072  " set up the filename
5073  " (lower case the extension, make a local copy of a remote file)
5074  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5075  if has("win32") || has("win95") || has("win64") || has("win16")
5076   let exten= substitute(exten,'^.*$','\L&\E','')
5077  endif
5078"  call Decho("exten<".exten.">",'~'.expand("<slnum>"))
5079
5080  if a:remote == 1
5081   " create a local copy
5082"   call Decho("remote: a:remote=".a:remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
5083   setl bh=delete
5084   call netrw#NetRead(3,a:fname)
5085   " attempt to rename tempfile
5086   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5087   let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5088"   call Decho("basename<".basename.">",'~'.expand("<slnum>"))
5089"   call Decho("newname <".newname.">",'~'.expand("<slnum>"))
5090   if rename(s:netrw_tmpfile,newname) == 0
5091    " renaming succeeded
5092    let fname= newname
5093   else
5094    " renaming failed
5095    let fname= s:netrw_tmpfile
5096   endif
5097  else
5098"   call Decho("local: a:remote=".a:remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
5099   let fname= a:fname
5100   " special ~ handler for local
5101   if fname =~ '^\~' && expand("$HOME") != ""
5102"    call Decho('invoking special ~ handler','~'.expand("<slnum>"))
5103    let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5104   endif
5105  endif
5106"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
5107"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
5108
5109  " set up redirection
5110  if &srr =~ "%s"
5111   if (has("win32") || has("win95") || has("win64") || has("win16"))
5112    let redir= substitute(&srr,"%s","nul","")
5113   else
5114    let redir= substitute(&srr,"%s","/dev/null","")
5115   endif
5116  elseif (has("win32") || has("win95") || has("win64") || has("win16"))
5117   let redir= &srr . "nul"
5118  else
5119   let redir= &srr . "/dev/null"
5120  endif
5121"  call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
5122
5123  " extract any viewing options.  Assumes that they're set apart by quotes.
5124"  call Decho("extract any viewing options",'~'.expand("<slnum>"))
5125  if exists("g:netrw_browsex_viewer")
5126"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5127   if g:netrw_browsex_viewer =~ '\s'
5128    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5129    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5130    let oviewer = ''
5131    let cnt     = 1
5132    while !executable(viewer) && viewer != oviewer
5133     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5134     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5135     let cnt     = cnt + 1
5136     let oviewer = viewer
5137"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5138    endwhile
5139   else
5140    let viewer  = g:netrw_browsex_viewer
5141    let viewopt = ""
5142   endif
5143"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5144  endif
5145
5146  " execute the file handler
5147"  call Decho("execute the file handler (if any)",'~'.expand("<slnum>"))
5148  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
5149"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5150   let ret= netrwFileHandlers#Invoke(exten,fname)
5151
5152  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
5153"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5154   call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
5155   let ret= v:shell_error
5156
5157  elseif has("win32") || has("win64")
5158"   call Decho("windows",'~'.expand("<slnum>"))
5159   if executable("start")
5160    call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5161   elseif executable("rundll32")
5162    call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5163   else
5164    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5165   endif
5166   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
5167   let ret= v:shell_error
5168
5169  elseif has("win32unix")
5170   let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
5171"   call Decho("cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
5172   if executable("start")
5173    call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5174   elseif executable("rundll32")
5175    call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5176   elseif executable("cygstart")
5177    call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
5178   else
5179    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5180   endif
5181   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
5182   let ret= v:shell_error
5183
5184  elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
5185"   call Decho("unix and kfmclient",'~'.expand("<slnum>"))
5186   call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
5187   let ret= v:shell_error
5188
5189  elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
5190"   call Decho("unix, exo-open, xdg-open",'~'.expand("<slnum>"))
5191   call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir)
5192   let ret= v:shell_error
5193
5194  elseif has("unix") && executable("xdg-open")
5195"   call Decho("unix and xdg-open",'~'.expand("<slnum>"))
5196   call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir)
5197   let ret= v:shell_error
5198
5199  elseif has("macunix") && executable("open")
5200"   call Decho("macunix and open",'~'.expand("<slnum>"))
5201   call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
5202   let ret= v:shell_error
5203
5204  else
5205   " netrwFileHandlers#Invoke() always returns 0
5206   let ret= netrwFileHandlers#Invoke(exten,fname)
5207  endif
5208
5209  " if unsuccessful, attempt netrwFileHandlers#Invoke()
5210  if ret
5211   let ret= netrwFileHandlers#Invoke(exten,fname)
5212  endif
5213
5214  " restoring redraw! after external file handlers
5215  redraw!
5216
5217  " cleanup: remove temporary file,
5218  "          delete current buffer if success with handler,
5219  "          return to prior buffer (directory listing)
5220  "          Feb 12, 2008: had to de-activiate removal of
5221  "          temporary file because it wasn't getting seen.
5222"  if a:remote == 1 && fname != a:fname
5223""   call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
5224"   call s:NetrwDelete(fname)
5225"  endif
5226
5227  if a:remote == 1
5228   setl bh=delete bt=nofile
5229   if g:netrw_use_noswf
5230    setl noswf
5231   endif
5232   exe "sil! NetrwKeepj norm! \<c-o>"
5233"   redraw!
5234  endif
5235"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5236  call winrestview(screenposn)
5237  let @@ = ykeep
5238  let &aw= awkeep
5239
5240"  call Dret("netrw#BrowseX")
5241endfun
5242
5243" ---------------------------------------------------------------------
5244" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5245fun! netrw#BrowseXVis()
5246"  call Dfunc("netrw#BrowseXVis()")
5247  let atkeep = @@
5248  norm! gvy
5249"  call Decho("@@<".@@.">",'~'.expand("<slnum>"))
5250  call netrw#BrowseX(@@,netrw#CheckIfRemote())
5251  let @@     = atkeep
5252"  call Dret("netrw#BrowseXVis")
5253endfun
5254
5255" ---------------------------------------------------------------------
5256" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5257fun! netrw#CheckIfRemote()
5258"  call Dfunc("netrw#CheckIfRemote()")
5259  if expand("%") =~ '^\a\{3,}://'
5260"   call Dret("netrw#CheckIfRemote 1")
5261   return 1
5262  else
5263"   call Dret("netrw#CheckIfRemote 0")
5264   return 0
5265  endif
5266endfun
5267
5268" ---------------------------------------------------------------------
5269" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5270fun! s:NetrwChgPerm(islocal,curdir)
5271"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
5272  let ykeep  = @@
5273  call inputsave()
5274  let newperm= input("Enter new permission: ")
5275  call inputrestore()
5276  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5277  let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5278"  call Decho("chgperm<".chgperm.">",'~'.expand("<slnum>"))
5279  call system(chgperm)
5280  if v:shell_error != 0
5281   NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5282  endif
5283  if a:islocal
5284   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5285  endif
5286  let @@= ykeep
5287"  call Dret("s:NetrwChgPerm")
5288endfun
5289
5290" ---------------------------------------------------------------------
5291" s:CheckIfKde: checks if kdeinit is running {{{2
5292"    Returns 0: kdeinit not running
5293"            1: kdeinit is  running
5294fun! s:CheckIfKde()
5295"  call Dfunc("s:CheckIfKde()")
5296  " seems kde systems often have gnome-open due to dependencies, even though
5297  " gnome-open's subsidiary display tools are largely absent.  Kde systems
5298  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
5299  if !exists("s:haskdeinit")
5300   if has("unix") && executable("ps") && !has("win32unix")
5301    let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5302    if v:shell_error
5303     let s:haskdeinit = 0
5304    endif
5305   else
5306    let s:haskdeinit= 0
5307   endif
5308"   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5309  endif
5310
5311"  call Dret("s:CheckIfKde ".s:haskdeinit)
5312  return s:haskdeinit
5313endfun
5314
5315" ---------------------------------------------------------------------
5316" s:NetrwClearExplore: clear explore variables (if any) {{{2
5317fun! s:NetrwClearExplore()
5318"  call Dfunc("s:NetrwClearExplore()")
5319  2match none
5320  if exists("s:explore_match")        |unlet s:explore_match        |endif
5321  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
5322  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5323  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
5324  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
5325  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
5326  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5327  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
5328  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
5329"   redraw!
5330  echo " "
5331  echo " "
5332"  call Dret("s:NetrwClearExplore")
5333endfun
5334
5335" ---------------------------------------------------------------------
5336" s:NetrwExploreListUniq: {{{2
5337fun! s:NetrwExploreListUniq(explist)
5338"  call Dfunc("s:NetrwExploreListUniq(explist<".string(a:explist).">)")
5339
5340  " this assumes that the list is already sorted
5341  let newexplist= []
5342  for member in a:explist
5343   if !exists("uniqmember") || member != uniqmember
5344    let uniqmember = member
5345    let newexplist = newexplist + [ member ]
5346   endif
5347  endfor
5348
5349"  call Dret("s:NetrwExploreListUniq newexplist<".string(newexplist).">")
5350  return newexplist
5351endfun
5352
5353" ---------------------------------------------------------------------
5354" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5355fun! s:NetrwForceChgDir(islocal,newdir)
5356"  call Dfunc("s:NetrwForceChgDir(islocal=".a:islocal." newdir<".a:newdir.">)")
5357  let ykeep= @@
5358  if a:newdir !~ '/$'
5359   " ok, looks like force is needed to get directory-style treatment
5360   if a:newdir =~ '@$'
5361    let newdir= substitute(a:newdir,'@$','/','')
5362   elseif a:newdir =~ '[*=|\\]$'
5363    let newdir= substitute(a:newdir,'.$','/','')
5364   else
5365    let newdir= a:newdir.'/'
5366   endif
5367"   call Decho("adjusting newdir<".newdir."> due to gd",'~'.expand("<slnum>"))
5368  else
5369   " should already be getting treatment as a directory
5370   let newdir= a:newdir
5371  endif
5372  let newdir= s:NetrwBrowseChgDir(a:islocal,newdir)
5373  call s:NetrwBrowse(a:islocal,newdir)
5374  let @@= ykeep
5375"  call Dret("s:NetrwForceChgDir")
5376endfun
5377
5378" ---------------------------------------------------------------------
5379" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5380fun! s:NetrwGlob(direntry,expr)
5381"  call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr.">)")
5382  if netrw#CheckIfRemote()
5383   keepalt 1sp
5384   keepalt enew
5385   let keep_liststyle    = w:netrw_liststyle
5386   let w:netrw_liststyle = s:THINLIST
5387   if s:NetrwRemoteListing() == 0
5388    keepj keepalt %s@/@@
5389    let filelist= getline(1,$)
5390    q!
5391   else
5392    " remote listing error -- leave treedict unchanged
5393    let filelist= w:netrw_treedict[a:direntry]
5394   endif
5395   let w:netrw_liststyle= keep_liststyle
5396  else
5397   let filelist= glob(s:ComposePath(a:direntry,a:expr),0,1,1)
5398   let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5399  endif
5400"  call Dret("s:NetrwGlob ".string(filelist))
5401  return filelist
5402endfun
5403
5404" ---------------------------------------------------------------------
5405" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5406fun! s:NetrwForceFile(islocal,newfile)
5407"  call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)")
5408  if a:newfile =~ '[/@*=|\\]$'
5409   let newfile= substitute(a:newfile,'.$','','')
5410  else
5411   let newfile= a:newfile
5412  endif
5413  if a:islocal
5414   call s:NetrwBrowseChgDir(a:islocal,newfile)
5415  else
5416   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile))
5417  endif
5418"  call Dret("s:NetrwForceFile")
5419endfun
5420
5421" ---------------------------------------------------------------------
5422" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5423"          and switches the hiding mode.  The actual hiding is done by
5424"          s:NetrwListHide().
5425"             g:netrw_hide= 0: show all
5426"                           1: show not-hidden files
5427"                           2: show hidden files only
5428fun! s:NetrwHide(islocal)
5429"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
5430  let ykeep= @@
5431  let svpos= winsaveview()
5432"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5433
5434  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5435"   call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>"))
5436"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5437
5438   " hide the files in the markfile list
5439   for fname in s:netrwmarkfilelist_{bufnr("%")}
5440"    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>"))
5441    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5442     " remove fname from hiding list
5443     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5444     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5445     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5446"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5447    else
5448     " append fname to hiding list
5449     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5450      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5451     else
5452      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5453     endif
5454"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5455    endif
5456   endfor
5457   NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5458   let g:netrw_hide= 1
5459
5460  else
5461
5462   " switch between show-all/show-not-hidden/show-hidden
5463   let g:netrw_hide=(g:netrw_hide+1)%3
5464   exe "NetrwKeepj norm! 0"
5465   if g:netrw_hide && g:netrw_list_hide == ""
5466    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5467    let @@= ykeep
5468"    call Dret("NetrwHide")
5469    return
5470   endif
5471  endif
5472
5473  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5474"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5475  NetrwKeepj call winrestview(svpos)
5476  let @@= ykeep
5477"  call Dret("NetrwHide")
5478endfun
5479
5480" ---------------------------------------------------------------------
5481" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5482fun! s:NetrwHideEdit(islocal)
5483"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
5484
5485  let ykeep= @@
5486  " save current cursor position
5487  let svpos= winsaveview()
5488"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5489
5490  " get new hiding list from user
5491  call inputsave()
5492  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5493  call inputrestore()
5494  let g:netrw_list_hide= newhide
5495"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5496
5497  " refresh the listing
5498  sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
5499
5500  " restore cursor position
5501"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5502  call winrestview(svpos)
5503  let @@= ykeep
5504
5505"  call Dret("NetrwHideEdit")
5506endfun
5507
5508" ---------------------------------------------------------------------
5509" s:NetrwHidden: invoked by "gh" {{{2
5510fun! s:NetrwHidden(islocal)
5511"  call Dfunc("s:NetrwHidden()")
5512  let ykeep= @@
5513  "  save current position
5514  let svpos= winsaveview()
5515"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5516
5517  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5518   " remove pattern from hiding list
5519   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5520  elseif s:Strlen(g:netrw_list_hide) >= 1
5521   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5522  else
5523   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5524  endif
5525
5526  " refresh screen and return to saved position
5527  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5528"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5529  NetrwKeepj call winrestview(svpos)
5530  let @@= ykeep
5531"  call Dret("s:NetrwHidden")
5532endfun
5533
5534" ---------------------------------------------------------------------
5535"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5536fun! s:NetrwHome()
5537  if exists("g:netrw_home")
5538   let home= g:netrw_home
5539  else
5540   " go to vim plugin home
5541   for home in split(&rtp,',') + ['']
5542    if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5543     let basehome= substitute(home,'[/\\]\.vim$','','')
5544     if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5545     let home= basehome."/.vim"
5546     break
5547    endif
5548   endfor
5549   if home == ""
5550    " just pick the first directory
5551    let home= substitute(&rtp,',.*$','','')
5552   endif
5553   if (has("win32") || has("win95") || has("win64") || has("win16"))
5554    let home= substitute(home,'/','\\','g')
5555   endif
5556  endif
5557  " insure that the home directory exists
5558  if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5559   if exists("g:netrw_mkdir")
5560    call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5561   else
5562    call mkdir(home)
5563   endif
5564  endif
5565  let g:netrw_home= home
5566  return home
5567endfun
5568
5569" ---------------------------------------------------------------------
5570" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5571fun! s:NetrwLeftmouse(islocal)
5572  if exists("s:netrwdrag")
5573   return
5574  endif
5575"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
5576
5577  let ykeep= @@
5578  " check if the status bar was clicked on instead of a file/directory name
5579  while getchar(0) != 0
5580   "clear the input stream
5581  endwhile
5582  call feedkeys("\<LeftMouse>")
5583  let c          = getchar()
5584  let mouse_lnum = v:mouse_lnum
5585  let wlastline  = line('w$')
5586  let lastline   = line('$')
5587"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr(),'~'.expand("<slnum>"))
5588"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0),'~'.expand("<slnum>"))
5589  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5590   " appears to be a status bar leftmouse click
5591   let @@= ykeep
5592"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
5593   return
5594  endif
5595   " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5596   " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5597   " without this test when its disabled.
5598   " May 26, 2014: edit file, :Lex, resize window -- causes refresh.  Reinstated a modified test.  See if problems develop.
5599"   call Decho("v:mouse_col=".v:mouse_col." col#".col('.')." virtcol#".virtcol('.')." col($)#".col("$")." virtcol($)#".virtcol("$"),'~'.expand("<slnum>"))
5600   if v:mouse_col > virtcol('.')
5601    let @@= ykeep
5602"    call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
5603    return
5604   endif
5605
5606  if a:islocal
5607   if exists("b:netrw_curdir")
5608    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
5609   endif
5610  else
5611   if exists("b:netrw_curdir")
5612    NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5613   endif
5614  endif
5615  let @@= ykeep
5616"  call Dret("s:NetrwLeftmouse")
5617endfun
5618
5619" ---------------------------------------------------------------------
5620" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5621fun! s:NetrwCLeftmouse(islocal)
5622"  call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")")
5623  call s:NetrwMarkFileTgt(a:islocal)
5624"  call Dret("s:NetrwCLeftmouse")
5625endfun
5626
5627" ---------------------------------------------------------------------
5628" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER  (implements <c-r>){{{2
5629"   a:islocal=0 : <c-r> not used, remote
5630"   a:islocal=1 : <c-r> no  used, local
5631"   a:islocal=2 : <c-r>     used, remote
5632"   a:islocal=3 : <c-r>     used, local
5633fun! s:NetrwServerEdit(islocal,fname)
5634"  call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5635  let islocal = a:islocal%2      " =0: remote           =1: local
5636  let ctrlr   = a:islocal >= 2   " =0: <c-r> not used   =1: <c-r> used
5637"  call Decho("islocal=".islocal." ctrlr=".ctrlr,'~'.expand("<slnum>"))
5638
5639  if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5640   " handle directories in the local window -- not in the remote vim server
5641   " user must have closed the NETRWSERVER window.  Treat as normal editing from netrw.
5642"   call Decho("handling directory in client window",'~'.expand("<slnum>"))
5643   let g:netrw_browse_split= 0
5644   if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
5645    let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5646    unlet s:netrw_browse_split_{winnr()}
5647   endif
5648   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5649"   call Dret("s:NetrwServerEdit")
5650   return
5651  endif
5652
5653"  call Decho("handling file in server window",'~'.expand("<slnum>"))
5654  if has("clientserver") && executable("gvim")
5655"   call Decho("has clientserver and gvim",'~'.expand("<slnum>"))
5656
5657    if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
5658"     call Decho("g:netrw_browse_split=".string(g:netrw_browse_split),'~'.expand("<slnum>"))
5659     let srvrname = g:netrw_browse_split[0]
5660     let tabnum   = g:netrw_browse_split[1]
5661     let winnum   = g:netrw_browse_split[2]
5662
5663     if serverlist() !~ '\<'.srvrname.'\>'
5664"      call Decho("server not available; ctrlr=".ctrlr,'~'.expand("<slnum>"))
5665
5666      if !ctrlr
5667       " user must have closed the server window and the user did not use <c-r>, but
5668       " used something like <cr>.
5669"       call Decho("user must have closed server AND did not use ctrl-r",'~'.expand("<slnum>"))
5670       if exists("g:netrw_browse_split")
5671	unlet g:netrw_browse_split
5672       endif
5673       let g:netrw_browse_split= 0
5674       if exists("s:netrw_browse_split_".winnr())
5675        let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5676       endif
5677       call s:NetrwBrowseChgDir(islocal,a:fname)
5678"       call Dret("s:NetrwServerEdit")
5679       return
5680
5681      elseif has("win32") && executable("start")
5682       " start up remote netrw server under windows
5683"       call Decho("starting up gvim server<".srvrname."> for windows",'~'.expand("<slnum>"))
5684       call system("start gvim --servername ".srvrname)
5685
5686      else
5687       " start up remote netrw server under linux
5688"       call Decho("starting up gvim server<".srvrname.">",'~'.expand("<slnum>"))
5689       call system("gvim --servername ".srvrname)
5690      endif
5691     endif
5692
5693"     call Decho("srvrname<".srvrname."> tabnum=".tabnum." winnum=".winnum." server-editing<".a:fname.">",'~'.expand("<slnum>"))
5694     call remote_send(srvrname,":tabn ".tabnum."\<cr>")
5695     call remote_send(srvrname,":".winnum."wincmd w\<cr>")
5696     call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5697
5698    else
5699
5700     if serverlist() !~ '\<'.g:netrw_servername.'\>'
5701
5702      if !ctrlr
5703"       call Decho("server<".g:netrw_servername."> not available and ctrl-r not used",'~'.expand("<slnum>"))
5704       if exists("g:netrw_browse_split")
5705	unlet g:netrw_browse_split
5706       endif
5707       let g:netrw_browse_split= 0
5708       call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5709"       call Dret("s:NetrwServerEdit")
5710       return
5711
5712      else
5713"       call Decho("server<".g:netrw_servername."> not available but ctrl-r used",'~'.expand("<slnum>"))
5714       if has("win32") && executable("start")
5715        " start up remote netrw server under windows
5716"        call Decho("starting up gvim server<".g:netrw_servername."> for windows",'~'.expand("<slnum>"))
5717        call system("start gvim --servername ".g:netrw_servername)
5718       else
5719        " start up remote netrw server under linux
5720"        call Decho("starting up gvim server<".g:netrw_servername.">",'~'.expand("<slnum>"))
5721        call system("gvim --servername ".g:netrw_servername)
5722       endif
5723      endif
5724     endif
5725
5726     while 1
5727      try
5728"       call Decho("remote-send: e ".a:fname,'~'.expand("<slnum>"))
5729       call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5730       break
5731      catch /^Vim\%((\a\+)\)\=:E241/
5732       sleep 200m
5733      endtry
5734     endwhile
5735
5736     if exists("g:netrw_browse_split")
5737      if type(g:netrw_browse_split) != 3
5738        let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
5739       endif
5740      unlet g:netrw_browse_split
5741     endif
5742     let g:netrw_browse_split= [g:netrw_servername,1,1]
5743    endif
5744
5745   else
5746    call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
5747   endif
5748
5749"  call Dret("s:NetrwServerEdit")
5750endfun
5751
5752" ---------------------------------------------------------------------
5753" s:NetrwSLeftmouse: marks the file under the cursor.  May be dragged to select additional files {{{2
5754fun! s:NetrwSLeftmouse(islocal)
5755"  call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
5756
5757  let s:ngw= s:NetrwGetWord()
5758  call s:NetrwMarkFile(a:islocal,s:ngw)
5759
5760"  call Dret("s:NetrwSLeftmouse")
5761endfun
5762
5763" ---------------------------------------------------------------------
5764" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
5765"                   Used to mark multiple files.
5766fun! s:NetrwSLeftdrag(islocal)
5767"  call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
5768  if !exists("s:netrwdrag")
5769   let s:netrwdrag = winnr()
5770   if a:islocal
5771    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
5772   else
5773    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
5774   endif
5775  endif
5776  let ngw = s:NetrwGetWord()
5777  if !exists("s:ngw") || s:ngw != ngw
5778   call s:NetrwMarkFile(a:islocal,ngw)
5779  endif
5780  let s:ngw= ngw
5781"  call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5782endfun
5783
5784" ---------------------------------------------------------------------
5785" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
5786fun! s:NetrwSLeftrelease(islocal)
5787"  call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5788  if exists("s:netrwdrag")
5789   nunmap <s-leftrelease>
5790   let ngw = s:NetrwGetWord()
5791   if !exists("s:ngw") || s:ngw != ngw
5792    call s:NetrwMarkFile(a:islocal,ngw)
5793   endif
5794   if exists("s:ngw")
5795    unlet s:ngw
5796   endif
5797   unlet s:netrwdrag
5798  endif
5799"  call Dret("s:NetrwSLeftrelease")
5800endfun
5801
5802" ---------------------------------------------------------------------
5803" s:NetrwListHide: uses [range]g~...~d to delete files that match comma {{{2
5804" separated patterns given in g:netrw_list_hide
5805fun! s:NetrwListHide()
5806"  call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
5807  let ykeep= @@
5808
5809  " find a character not in the "hide" string to use as a separator for :g and :v commands
5810  " How-it-works: take the hiding command, convert it into a range.  Duplicate
5811  " characters don't matter.  Remove all such characters from the '/~...90'
5812  " string.  Use the first character left as a separator character.
5813  let listhide= g:netrw_list_hide
5814  let sep     = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
5815"  call Decho("sep=".sep,'~'.expand("<slnum>"))
5816
5817  while listhide != ""
5818   if listhide =~ ','
5819    let hide     = substitute(listhide,',.*$','','e')
5820    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
5821   else
5822    let hide     = listhide
5823    let listhide = ""
5824   endif
5825
5826   " Prune the list by hiding any files which match
5827   if g:netrw_hide == 1
5828"    call Decho("hiding<".hide."> listhide<".listhide.">",'~'.expand("<slnum>"))
5829    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
5830   elseif g:netrw_hide == 2
5831"    call Decho("showing<".hide."> listhide<".listhide.">",'~'.expand("<slnum>"))
5832    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
5833   endif
5834  endwhile
5835  if g:netrw_hide == 2
5836   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
5837   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
5838  endif
5839
5840  " remove any blank lines that have somehow remained.
5841  " This seems to happen under Windows.
5842  exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
5843
5844  let @@= ykeep
5845"  call Dret("s:NetrwListHide")
5846endfun
5847
5848" ---------------------------------------------------------------------
5849" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
5850"                 implements the "d" mapping.
5851fun! s:NetrwMakeDir(usrhost)
5852"  call Dfunc("s:NetrwMakeDir(usrhost<".a:usrhost.">)")
5853
5854  let ykeep= @@
5855  " get name of new directory from user.  A bare <CR> will skip.
5856  " if its currently a directory, also request will be skipped, but with
5857  " a message.
5858  call inputsave()
5859  let newdirname= input("Please give directory name: ")
5860  call inputrestore()
5861"  call Decho("newdirname<".newdirname.">",'~'.expand("<slnum>"))
5862
5863  if newdirname == ""
5864   let @@= ykeep
5865"   call Dret("s:NetrwMakeDir : user aborted with bare <cr>")
5866   return
5867  endif
5868
5869  if a:usrhost == ""
5870"   call Decho("local mkdir",'~'.expand("<slnum>"))
5871
5872   " Local mkdir:
5873   " sanity checks
5874   let fullnewdir= b:netrw_curdir.'/'.newdirname
5875"   call Decho("fullnewdir<".fullnewdir.">",'~'.expand("<slnum>"))
5876   if isdirectory(s:NetrwFile(fullnewdir))
5877    if !exists("g:netrw_quiet")
5878     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
5879    endif
5880    let @@= ykeep
5881"    call Dret("s:NetrwMakeDir : directory<".newdirname."> exists previously")
5882    return
5883   endif
5884   if s:FileReadable(fullnewdir)
5885    if !exists("g:netrw_quiet")
5886     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
5887    endif
5888    let @@= ykeep
5889"    call Dret("s:NetrwMakeDir : file<".newdirname."> exists previously")
5890    return
5891   endif
5892
5893   " requested new local directory is neither a pre-existing file or
5894   " directory, so make it!
5895   if exists("*mkdir")
5896    if has("unix")
5897     call mkdir(fullnewdir,"p",xor(0777, system("umask")))
5898    else
5899     call mkdir(fullnewdir,"p")
5900    endif
5901   else
5902    let netrw_origdir= s:NetrwGetcwd(1)
5903    call s:NetrwLcd(b:netrw_curdir)
5904"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("<slnum>"))
5905    call s:NetrwExe("sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
5906    if v:shell_error != 0
5907     let @@= ykeep
5908     call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
5909"     call Dret("s:NetrwMakeDir : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
5910     return
5911    endif
5912    if !g:netrw_keepdir
5913"     call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
5914     call s:NetrwLcd(netrw_origdir)
5915    endif
5916   endif
5917
5918   if v:shell_error == 0
5919    " refresh listing
5920"    call Decho("refresh listing",'~'.expand("<slnum>"))
5921    let svpos= winsaveview()
5922"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5923    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
5924"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5925    call winrestview(svpos)
5926   elseif !exists("g:netrw_quiet")
5927    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
5928   endif
5929"   redraw!
5930
5931  elseif !exists("b:netrw_method") || b:netrw_method == 4
5932   " Remote mkdir:  using ssh
5933"   call Decho("remote mkdir",'~'.expand("<slnum>"))
5934   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
5935   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
5936   call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
5937   if v:shell_error == 0
5938    " refresh listing
5939    let svpos= winsaveview()
5940"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5941    NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5942"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5943    NetrwKeepj call winrestview(svpos)
5944   elseif !exists("g:netrw_quiet")
5945    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
5946   endif
5947"   redraw!
5948
5949  elseif b:netrw_method == 2
5950   " Remote mkdir:  using ftp+.netrc
5951   let svpos= winsaveview()
5952"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5953"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
5954   if exists("b:netrw_fname")
5955"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
5956    let remotepath= b:netrw_fname
5957   else
5958    let remotepath= ""
5959   endif
5960   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
5961   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5962"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5963   NetrwKeepj call winrestview(svpos)
5964
5965  elseif b:netrw_method == 3
5966   " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
5967   let svpos= winsaveview()
5968"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5969"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
5970   if exists("b:netrw_fname")
5971"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
5972    let remotepath= b:netrw_fname
5973   else
5974    let remotepath= ""
5975   endif
5976   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
5977   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5978"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5979   NetrwKeepj call winrestview(svpos)
5980  endif
5981
5982  let @@= ykeep
5983"  call Dret("s:NetrwMakeDir")
5984endfun
5985
5986" ---------------------------------------------------------------------
5987" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
5988fun! s:TreeSqueezeDir(islocal)
5989"  call Dfunc("s:TreeSqueezeDir(islocal=".a:islocal.")")
5990  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5991   " its a tree-listing style
5992   let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
5993   let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
5994   let depth    = strchars(substitute(curdepth,' ','','g'))
5995   let srch     = -1
5996"   call Decho("curdepth<".curdepth.'>','~'.expand("<slnum>"))
5997"   call Decho("depth   =".depth,'~'.expand("<slnum>"))
5998"   call Decho("stopline#".stopline,'~'.expand("<slnum>"))
5999"   call Decho("curline#".line(".")."<".getline('.').'>','~'.expand("<slnum>"))
6000   if depth >= 2
6001    NetrwKeepj norm! 0
6002    let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
6003    let srch      = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
6004"    call Decho("curdepthm1<".curdepthm1.'>','~'.expand("<slnum>"))
6005"    call Decho("case depth>=2: srch<".srch.'>','~'.expand("<slnum>"))
6006   elseif depth == 1
6007    NetrwKeepj norm! 0
6008    let treedepthchr= substitute(s:treedepthstring,' ','','')
6009    let srch        = search('^[^'.treedepthchr.']','bW',stopline)
6010"    call Decho("case depth==1: srch<".srch.'>','~'.expand("<slnum>"))
6011   endif
6012   if srch > 0
6013"    call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
6014    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord()))
6015    exe srch
6016   endif
6017  endif
6018"  call Dret("s:TreeSqueezeDir")
6019endfun
6020
6021" ---------------------------------------------------------------------
6022" s:NetrwMaps: {{{2
6023fun! s:NetrwMaps(islocal)
6024"  call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6025
6026  if g:netrw_mousemaps && g:netrw_retmap
6027"   call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
6028   if !hasmapto("<Plug>NetrwReturn")
6029    if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
6030"     call Decho("making map for 2-leftmouse",'~'.expand("<slnum>"))
6031     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
6032    elseif maparg("<c-leftmouse>","n") == ""
6033"     call Decho("making map for c-leftmouse",'~'.expand("<slnum>"))
6034     nmap <unique> <silent> <c-leftmouse>	<Plug>NetrwReturn
6035    endif
6036   endif
6037   nno <silent> <Plug>NetrwReturn	:Rexplore<cr>
6038"   call Decho("made <Plug>NetrwReturn map",'~'.expand("<slnum>"))
6039  endif
6040
6041  if a:islocal
6042"   call Decho("make local maps",'~'.expand("<slnum>"))
6043   " local normal-mode maps
6044   nnoremap <buffer> <silent> <nowait> a	:<c-u>call <SID>NetrwHide(1)<cr>
6045   nnoremap <buffer> <silent> <nowait> -	:<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6046   nnoremap <buffer> <silent> <nowait> %	:<c-u>call <SID>NetrwOpenFile(1)<cr>
6047   nnoremap <buffer> <silent> <nowait> c	:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6048   nnoremap <buffer> <silent> <nowait> C	:<c-u>call <SID>NetrwSetChgwin()<cr>
6049   nnoremap <buffer> <silent> <nowait> <cr>	:<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6050   nnoremap <buffer> <silent> <nowait> <c-r>	:<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6051   nnoremap <buffer> <silent> <nowait> d	:<c-u>call <SID>NetrwMakeDir("")<cr>
6052   nnoremap <buffer> <silent> <nowait> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6053   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6054   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6055   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
6056   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr>
6057   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6058   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6059   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(1)<cr>
6060   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6061   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6062   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6063   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6064   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6065   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6066   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6067   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6068   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6069   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6070   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6071   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6072   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6073   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6074   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6075   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6076   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6077   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6078   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6079   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6080   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6081   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6082   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(1)<cr>
6083   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(3)<cr>
6084   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6085   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6086   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6087   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6088   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6089   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6090   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>
6091   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(1)<cr>
6092   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(1)<cr>
6093   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6094   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(4)<cr>
6095   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6096   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6097   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6098   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(5)<cr>
6099   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6100   nnoremap <buffer> <silent> <nowait> X	:<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6101"   " local insert-mode maps
6102"   inoremap <buffer> <silent> <nowait> a	<c-o>:call <SID>NetrwHide(1)<cr>
6103"   inoremap <buffer> <silent> <nowait> c	<c-o>:exe "NetrwKeepj lcd ".fnameescape(b:netrw_curdir)<cr>
6104"   inoremap <buffer> <silent> <nowait> c	<c-o>:call <SID>NetrwLcd(b:netrw_curdir)<cr>
6105"   inoremap <buffer> <silent> <nowait> C	<c-o>:call <SID>NetrwSetChgwin()<cr>
6106"   inoremap <buffer> <silent> <nowait> %	<c-o>:call <SID>NetrwOpenFile(1)<cr>
6107"   inoremap <buffer> <silent> <nowait> -	<c-o>:call <SID>NetrwBrowseUpDir(1)<cr>
6108"   inoremap <buffer> <silent> <nowait> <cr>	<c-o>:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6109"   inoremap <buffer> <silent> <nowait> d	<c-o>:call <SID>NetrwMakeDir("")<cr>
6110"   inoremap <buffer> <silent> <nowait> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6111"   inoremap <buffer> <silent> <nowait> gh	<c-o>:<c-u>call <SID>NetrwHidden(1)<cr>
6112"   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr>
6113"   inoremap <buffer> <silent> <nowait> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6114"   inoremap <buffer> <silent> <nowait> I	<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
6115"   inoremap <buffer> <silent> <nowait> i	<c-o>:call <SID>NetrwListStyle(1)<cr>
6116"   inoremap <buffer> <silent> <nowait> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6117"   inoremap <buffer> <silent> <nowait> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6118"   inoremap <buffer> <silent> <nowait> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6119"   inoremap <buffer> <silent> <nowait> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6120"   inoremap <buffer> <silent> <nowait> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6121"   inoremap <buffer> <silent> <nowait> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6122"   inoremap <buffer> <silent> <nowait> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6123"   inoremap <buffer> <silent> <nowait> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6124"   inoremap <buffer> <silent> <nowait> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6125"   inoremap <buffer> <silent> <nowait> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6126"   inoremap <buffer> <silent> <nowait> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6127"   inoremap <buffer> <silent> <nowait> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6128"   inoremap <buffer> <silent> <nowait> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6129"   inoremap <buffer> <silent> <nowait> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6130"   inoremap <buffer> <silent> <nowait> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6131"   inoremap <buffer> <silent> <nowait> mv	<c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6132"   inoremap <buffer> <silent> <nowait> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6133"   inoremap <buffer> <silent> <nowait> mX	<c-o>:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6134"   inoremap <buffer> <silent> <nowait> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6135"   inoremap <buffer> <silent> <nowait> O	<c-o>:call <SID>NetrwObtain(1)<cr>
6136"   inoremap <buffer> <silent> <nowait> o	<c-o>:call <SID>NetrwSplit(3)<cr>
6137"   inoremap <buffer> <silent> <nowait> p	<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6138"   inoremap <buffer> <silent> <nowait> P	<c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
6139"   inoremap <buffer> <silent> <nowait> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6140"   inoremap <buffer> <silent> <nowait> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6141"   inoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6142"   inoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6143"   inoremap <buffer> <silent> <nowait> r	<c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr>
6144"   inoremap <buffer> <silent> <nowait> s	<c-o>:call <SID>NetrwSortStyle(1)<cr>
6145"   inoremap <buffer> <silent> <nowait> S	<c-o>:call <SID>NetSortSequence(1)<cr>
6146"   inoremap <buffer> <silent> <nowait> t	<c-o>:call <SID>NetrwSplit(4)<cr>
6147"   inoremap <buffer> <silent> <nowait> Tb	<c-o>:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6148"   inoremap <buffer> <silent> <nowait> Th	<c-o>:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6149"   inoremap <buffer> <silent> <nowait> u	<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6150"   inoremap <buffer> <silent> <nowait> U	<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6151"   inoremap <buffer> <silent> <nowait> v	<c-o>:call <SID>NetrwSplit(5)<cr>
6152"   inoremap <buffer> <silent> <nowait> x	<c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6153   if !hasmapto('<Plug>NetrwHideEdit')
6154    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6155"    imap <buffer> <unique> <c-h> <c-o><Plug>NetrwHideEdit
6156   endif
6157   nnoremap <buffer> <silent> <Plug>NetrwHideEdit		:call <SID>NetrwHideEdit(1)<cr>
6158   if !hasmapto('<Plug>NetrwRefresh')
6159    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6160"    imap <buffer> <unique> <c-l> <c-o><Plug>NetrwRefresh
6161   endif
6162   nnoremap <buffer> <silent> <Plug>NetrwRefresh		<c-l>:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr>
6163   if s:didstarstar || !mapcheck("<s-down>","n")
6164    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6165"    inoremap <buffer> <silent> <s-down>	<c-o>:Nexplore<cr>
6166   endif
6167   if s:didstarstar || !mapcheck("<s-up>","n")
6168    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6169"    inoremap <buffer> <silent> <s-up>	<c-o>:Pexplore<cr>
6170   endif
6171   if !hasmapto('<Plug>NetrwTreeSqueeze')
6172    nmap <buffer> <silent> <nowait> <s-cr>			<Plug>NetrwTreeSqueeze
6173"    imap <buffer> <silent> <nowait> <s-cr>			<c-o><Plug>NetrwTreeSqueeze
6174   endif
6175   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze		:call <SID>TreeSqueezeDir(1)<cr>
6176   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6177   if g:netrw_mousemaps == 1
6178    nmap <buffer> <leftmouse>   				<Plug>NetrwLeftmouse
6179    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
6180    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6181    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(1)<cr>
6182    nmap <buffer> <middlemouse>		<Plug>NetrwMiddlemouse
6183    nno  <buffer> <silent>		<Plug>NetrwMiddlemouse	<leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
6184    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6185    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(1)<cr>
6186    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6187    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(1)<cr>
6188    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6189    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6190    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6191"    ino  <buffer> <silent>		<Plug>ILeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(1)<cr>
6192    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6193"    ino  <buffer> <silent>		<Plug>IMiddlemouse	<c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
6194"    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6195"    ino  <buffer> <silent>		<Plug>ISLeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6196    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6197    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6198"    exe 'inoremap <buffer> <silent> <rightmouse>  <c-o><leftmouse><c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6199   endif
6200   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6201   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6202   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6203   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("")<cr>'
6204   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6205   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6206   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6207"   exe 'inoremap <buffer> <silent> <nowait> <del>	<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6208"   exe 'inoremap <buffer> <silent> <nowait> D		<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6209"   exe 'inoremap <buffer> <silent> <nowait> R		<c-o>:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6210"   exe 'inoremap <buffer> <silent> <nowait> d		<c-o>:call <SID>NetrwMakeDir("")<cr>'
6211   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6212
6213   " support user-specified maps
6214   call netrw#UserMaps(1)
6215
6216  else " remote
6217"   call Decho("make remote maps",'~'.expand("<slnum>"))
6218   call s:RemotePathAnalysis(b:netrw_curdir)
6219   " remote normal-mode maps
6220   nnoremap <buffer> <silent> <nowait> a	:<c-u>call <SID>NetrwHide(0)<cr>
6221   nnoremap <buffer> <silent> <nowait> -	:<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6222   nnoremap <buffer> <silent> <nowait> %	:<c-u>call <SID>NetrwOpenFile(0)<cr>
6223   nnoremap <buffer> <silent> <nowait> C	:<c-u>call <SID>NetrwSetChgwin()<cr>
6224   nnoremap <buffer> <silent> <nowait> <c-l>	:<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6225   nnoremap <buffer> <silent> <nowait> <cr>	:<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6226   nnoremap <buffer> <silent> <nowait> <c-r>	:<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6227   nnoremap <buffer> <silent> <nowait> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6228   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6229   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6230   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
6231   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6232   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6233   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(0)<cr>
6234   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6235   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6236   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6237   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6238   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6239   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6240   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6241   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6242   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6243   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6244   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6245   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6246   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6247   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6248   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6249   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6250   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6251   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6252   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6253   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6254   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6255   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6256   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(0)<cr>
6257   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(0)<cr>
6258   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6259   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6260   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6261   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6262   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6263   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6264   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>
6265   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(0)<cr>
6266   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(0)<cr>
6267   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6268   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(1)<cr>
6269   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6270   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6271   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6272   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(2)<cr>
6273   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6274"   " remote insert-mode maps
6275"   inoremap <buffer> <silent> <nowait> <cr>	<c-o>:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6276"   inoremap <buffer> <silent> <nowait> <c-l>	<c-o>:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6277"   inoremap <buffer> <silent> <nowait> <s-cr>	<c-o>:call <SID>TreeSqueezeDir(0)<cr>
6278"   inoremap <buffer> <silent> <nowait> -		<c-o>:call <SID>NetrwBrowseUpDir(0)<cr>
6279"   inoremap <buffer> <silent> <nowait> a		<c-o>:call <SID>NetrwHide(0)<cr>
6280"   inoremap <buffer> <silent> <nowait> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6281"   inoremap <buffer> <silent> <nowait> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6282"   inoremap <buffer> <silent> <nowait> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6283"   inoremap <buffer> <silent> <nowait> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6284"   inoremap <buffer> <silent> <nowait> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6285"   inoremap <buffer> <silent> <nowait> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6286"   inoremap <buffer> <silent> <nowait> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6287"   inoremap <buffer> <silent> <nowait> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6288"   inoremap <buffer> <silent> <nowait> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6289"   inoremap <buffer> <silent> <nowait> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6290"   inoremap <buffer> <silent> <nowait> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6291"   inoremap <buffer> <silent> <nowait> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6292"   inoremap <buffer> <silent> <nowait> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6293"   inoremap <buffer> <silent> <nowait> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6294"   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6295"   inoremap <buffer> <silent> <nowait> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6296"   inoremap <buffer> <silent> <nowait> mX	<c-o>:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6297"   inoremap <buffer> <silent> <nowait> mv	<c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6298"   inoremap <buffer> <silent> <nowait> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6299"   inoremap <buffer> <silent> <nowait> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6300"   inoremap <buffer> <silent> <nowait> gh	<c-o>:<c-u>call <SID>NetrwHidden(0)<cr>
6301"   inoremap <buffer> <silent> <nowait> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6302"   inoremap <buffer> <silent> <nowait> C		<c-o>:call <SID>NetrwSetChgwin()<cr>
6303"   inoremap <buffer> <silent> <nowait> i		<c-o>:call <SID>NetrwListStyle(0)<cr>
6304"   inoremap <buffer> <silent> <nowait> I		<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
6305"   inoremap <buffer> <silent> <nowait> o		<c-o>:call <SID>NetrwSplit(0)<cr>
6306"   inoremap <buffer> <silent> <nowait> O		<c-o>:call <SID>NetrwObtain(0)<cr>
6307"   inoremap <buffer> <silent> <nowait> p		<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6308"   inoremap <buffer> <silent> <nowait> P		<c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
6309"   inoremap <buffer> <silent> <nowait> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6310"   inoremap <buffer> <silent> <nowait> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6311"   inoremap <buffer> <silent> <nowait> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6312"   inoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6313"   inoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6314"   inoremap <buffer> <silent> <nowait> r		<c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~ 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6315"   inoremap <buffer> <silent> <nowait> s		<c-o>:call <SID>NetrwSortStyle(0)<cr>
6316"   inoremap <buffer> <silent> <nowait> S		<c-o>:call <SID>NetSortSequence(0)<cr>
6317"   inoremap <buffer> <silent> <nowait> t		<c-o>:call <SID>NetrwSplit(1)<cr>
6318"   inoremap <buffer> <silent> <nowait> Tb	<c-o>:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr>
6319"   inoremap <buffer> <silent> <nowait> Th	<c-o>:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr>
6320"   inoremap <buffer> <silent> <nowait> u		<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6321"   inoremap <buffer> <silent> <nowait> U		<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6322"   inoremap <buffer> <silent> <nowait> v		<c-o>:call <SID>NetrwSplit(2)<cr>
6323"   inoremap <buffer> <silent> <nowait> x		<c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6324"   inoremap <buffer> <silent> <nowait> %		<c-o>:call <SID>NetrwOpenFile(0)<cr>
6325   if !hasmapto('<Plug>NetrwHideEdit')
6326    nmap <buffer> <c-h> <Plug>NetrwHideEdit
6327"    imap <buffer> <c-h> <Plug>NetrwHideEdit
6328   endif
6329   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
6330   if !hasmapto('<Plug>NetrwRefresh')
6331    nmap <buffer> <c-l> <Plug>NetrwRefresh
6332"    imap <buffer> <c-l> <Plug>NetrwRefresh
6333   endif
6334   if !hasmapto('<Plug>NetrwTreeSqueeze')
6335    nmap <buffer> <silent> <nowait> <s-cr>	<Plug>NetrwTreeSqueeze
6336"    imap <buffer> <silent> <nowait> <s-cr>	<c-o><Plug>NetrwTreeSqueeze
6337   endif
6338   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze	:call <SID>TreeSqueezeDir(0)<cr>
6339
6340   let mapsafepath     = escape(s:path, s:netrw_map_escape)
6341   let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6342
6343   nnoremap <buffer> <silent> <Plug>NetrwRefresh	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6344   if g:netrw_mousemaps == 1
6345    nmap <buffer> <leftmouse>		<Plug>NetrwLeftmouse
6346    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
6347    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6348    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(0)<cr>
6349    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6350    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(0)<cr>
6351    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6352    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(0)<cr>
6353    nmap <middlemouse>			<Plug>NetrwMiddlemouse
6354    nno  <buffer> <silent>		<middlemouse>		<Plug>NetrwMiddlemouse <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
6355    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6356    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6357    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6358"    ino  <buffer> <silent>		<Plug>ILeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(0)<cr>
6359    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6360"    ino  <buffer> <silent>		<Plug>IMiddlemouse	<c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
6361    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6362"    ino  <buffer> <silent>		<Plug>ISLeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6363    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6364    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6365"    exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6366   endif
6367   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6368   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6369   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6370   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6371   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6372   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6373   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6374"   exe 'inoremap <buffer> <silent> <nowait> <del>	<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6375"   exe 'inoremap <buffer> <silent> <nowait> d		<c-o>:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6376"   exe 'inoremap <buffer> <silent> <nowait> D		<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6377"   exe 'inoremap <buffer> <silent> <nowait> R		<c-o>:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6378   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6379"   inoremap <buffer> <F1>			<c-o>:he netrw-quickhelp<cr>
6380
6381   " support user-specified maps
6382   call netrw#UserMaps(0)
6383  endif
6384
6385"  call Dret("s:NetrwMaps")
6386endfun
6387
6388" ---------------------------------------------------------------------
6389" s:NetrwCommands: set up commands 				{{{2
6390"  If -buffer, the command is only available from within netrw buffers
6391"  Otherwise, the command is available from any window, so long as netrw
6392"  has been used at least once in the session.
6393fun! s:NetrwCommands(islocal)
6394"  call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6395
6396  com! -nargs=* -complete=file -bang	NetrwMB	call s:NetrwBookmark(<bang>0,<f-args>)
6397  com! -nargs=*			    	NetrwC	call s:NetrwSetChgwin(<q-args>)
6398  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
6399  if a:islocal
6400   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(1,<f-args>)
6401  else
6402   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(0,<f-args>)
6403  endif
6404  com! -buffer -nargs=? -complete=file	MT	call s:NetrwMarkTarget(<q-args>)
6405
6406"  call Dret("s:NetrwCommands")
6407endfun
6408
6409" ---------------------------------------------------------------------
6410" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6411"                   glob()ing only works with local files
6412fun! s:NetrwMarkFiles(islocal,...)
6413"  call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6414  let curdir = s:NetrwGetCurdir(a:islocal)
6415  let i      = 1
6416  while i <= a:0
6417   if a:islocal
6418    if v:version == 704 && has("patch656")
6419     let mffiles= glob(a:{i},0,1,1)
6420    else
6421     let mffiles= glob(a:{i},0,1)
6422    endif
6423   else
6424    let mffiles= [a:{i}]
6425   endif
6426"   call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6427   for mffile in mffiles
6428"    call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6429    call s:NetrwMarkFile(a:islocal,mffile)
6430   endfor
6431   let i= i + 1
6432  endwhile
6433"  call Dret("s:NetrwMarkFiles")
6434endfun
6435
6436" ---------------------------------------------------------------------
6437" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6438fun! s:NetrwMarkTarget(...)
6439"  call Dfunc("s:NetrwMarkTarget() a:0=".a:0)
6440  if a:0 == 0 || (a:0 == 1 && a:1 == "")
6441   let curdir = s:NetrwGetCurdir(1)
6442   let tgt    = b:netrw_curdir
6443  else
6444   let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6445   let tgt    = a:1
6446  endif
6447"  call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
6448  let s:netrwmftgt         = tgt
6449  let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6450  let curislocal           = b:netrw_curdir !~ '^\a\{3,}://'
6451  let svpos                = winsaveview()
6452"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6453  call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./'))
6454"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6455  call winrestview(svpos)
6456"  call Dret("s:NetrwMarkTarget")
6457endfun
6458
6459" ---------------------------------------------------------------------
6460" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6461"                  mark and unmark files.  If a markfile list exists,
6462"                  then the rename and delete functions will use it instead
6463"                  of whatever may happen to be under the cursor at that
6464"                  moment.  When the mouse and gui are available,
6465"                  shift-leftmouse may also be used to mark files.
6466"
6467"  Creates two lists
6468"    s:netrwmarkfilelist    -- holds complete paths to all marked files
6469"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
6470"
6471"  Creates a marked file match string
6472"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
6473"
6474"  Creates a buffer version of islocal
6475"    b:netrw_islocal
6476fun! s:NetrwMarkFile(islocal,fname)
6477"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6478"  call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6479
6480  " sanity check
6481  if empty(a:fname)
6482"   call Dret("s:NetrwMarkFile : emtpy fname")
6483   return
6484  endif
6485  let curdir = s:NetrwGetCurdir(a:islocal)
6486
6487  let ykeep   = @@
6488  let curbufnr= bufnr("%")
6489  if a:fname =~ '^\a'
6490   let leader= '\<'
6491  else
6492   let leader= ''
6493  endif
6494  if a:fname =~ '\a$'
6495   let trailer = '\>[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6496  else
6497   let trailer = '[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6498  endif
6499
6500  if exists("s:netrwmarkfilelist_".curbufnr)
6501   " markfile list pre-exists
6502"   call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6503"   call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6504"   call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6505   let b:netrw_islocal= a:islocal
6506
6507   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6508    " append filename to buffer's markfilelist
6509"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6510    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6511    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6512
6513   else
6514    " remove filename from buffer's markfilelist
6515"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6516    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6517    if s:netrwmarkfilelist_{curbufnr} == []
6518     " local markfilelist is empty; remove it entirely
6519"     call Decho("markfile list now empty",'~'.expand("<slnum>"))
6520     call s:NetrwUnmarkList(curbufnr,curdir)
6521    else
6522     " rebuild match list to display markings correctly
6523"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6524     let s:netrwmarkfilemtch_{curbufnr}= ""
6525     let first                         = 1
6526     for fname in s:netrwmarkfilelist_{curbufnr}
6527      if first
6528       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6529      else
6530       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6531      endif
6532      let first= 0
6533     endfor
6534"     call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6535    endif
6536   endif
6537
6538  else
6539   " initialize new markfilelist
6540"   call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6541
6542"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6543   let s:netrwmarkfilelist_{curbufnr}= []
6544   call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6545"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6546
6547   " build initial markfile matching pattern
6548   if a:fname =~ '/$'
6549    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6550   else
6551    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6552   endif
6553"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6554  endif
6555
6556  " handle global markfilelist
6557  if exists("s:netrwmarkfilelist")
6558   let dname= s:ComposePath(b:netrw_curdir,a:fname)
6559   if index(s:netrwmarkfilelist,dname) == -1
6560    " append new filename to global markfilelist
6561    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6562"    call Decho("append filename<".a:fname."> to global markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6563   else
6564    " remove new filename from global markfilelist
6565"    call Decho("filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6566    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6567"    call Decho("ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6568    if s:netrwmarkfilelist == []
6569     unlet s:netrwmarkfilelist
6570    endif
6571   endif
6572  else
6573   " initialize new global-directory markfilelist
6574   let s:netrwmarkfilelist= []
6575   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6576"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6577  endif
6578
6579  " set up 2match'ing to netrwmarkfilemtch_# list
6580  if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6581"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6582   if exists("g:did_drchip_netrwlist_syntax")
6583    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6584   endif
6585  else
6586"   call Decho("2match none",'~'.expand("<slnum>"))
6587   2match none
6588  endif
6589  let @@= ykeep
6590"  call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">")
6591endfun
6592
6593" ---------------------------------------------------------------------
6594" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6595"                         mA: move the argument list to marked file list     (tomflist=1)
6596"                            Uses the global marked file list
6597fun! s:NetrwMarkFileArgList(islocal,tomflist)
6598"  call Dfunc("s:NetrwMarkFileArgList(islocal=".a:islocal.",tomflist=".a:tomflist.")")
6599
6600  let svpos    = winsaveview()
6601"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6602  let curdir   = s:NetrwGetCurdir(a:islocal)
6603  let curbufnr = bufnr("%")
6604
6605  if a:tomflist
6606   " mA: move argument list to marked file list
6607   while argc()
6608    let fname= argv(0)
6609"    call Decho("exe argdel ".fname,'~'.expand("<slnum>"))
6610    exe "argdel ".fnameescape(fname)
6611    call s:NetrwMarkFile(a:islocal,fname)
6612   endwhile
6613
6614  else
6615   " ma: move marked file list to argument list
6616   if exists("s:netrwmarkfilelist")
6617
6618    " for every filename in the marked list
6619    for fname in s:netrwmarkfilelist
6620"     call Decho("exe argadd ".fname,'~'.expand("<slnum>"))
6621     exe "argadd ".fnameescape(fname)
6622    endfor	" for every file in the marked list
6623
6624    " unmark list and refresh
6625    call s:NetrwUnmarkList(curbufnr,curdir)
6626    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6627"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6628    NetrwKeepj call winrestview(svpos)
6629   endif
6630  endif
6631
6632"  call Dret("s:NetrwMarkFileArgList")
6633endfun
6634
6635" ---------------------------------------------------------------------
6636" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6637"                          compress/decompress files using the programs
6638"                          in g:netrw_compress and g:netrw_uncompress,
6639"                          using g:netrw_compress_suffix to know which to
6640"                          do.  By default:
6641"                            g:netrw_compress        = "gzip"
6642"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6643fun! s:NetrwMarkFileCompress(islocal)
6644"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
6645  let svpos    = winsaveview()
6646"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6647  let curdir   = s:NetrwGetCurdir(a:islocal)
6648  let curbufnr = bufnr("%")
6649
6650  " sanity check
6651  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6652   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6653"   call Dret("s:NetrwMarkFileCompress")
6654   return
6655  endif
6656"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6657
6658  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6659
6660   " for every filename in the marked list
6661   for fname in s:netrwmarkfilelist_{curbufnr}
6662    let sfx= substitute(fname,'^.\{-}\(\.\a\+\)$','\1','')
6663"    call Decho("extracted sfx<".sfx.">",'~'.expand("<slnum>"))
6664    if exists("g:netrw_decompress['".sfx."']")
6665     " fname has a suffix indicating that its compressed; apply associated decompression routine
6666     let exe= g:netrw_decompress[sfx]
6667"     call Decho("fname<".fname."> is compressed so decompress with <".exe.">",'~'.expand("<slnum>"))
6668     let exe= netrw#WinPath(exe)
6669     if a:islocal
6670      if g:netrw_keepdir
6671       let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6672      endif
6673     else
6674      let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6675     endif
6676     if executable(exe)
6677      if a:islocal
6678       call system(exe." ".fname)
6679      else
6680       NetrwKeepj call s:RemoteSystem(exe." ".fname)
6681      endif
6682     else
6683      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6684     endif
6685    endif
6686    unlet sfx
6687
6688    if exists("exe")
6689     unlet exe
6690    elseif a:islocal
6691     " fname not a compressed file, so compress it
6692     call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
6693    else
6694     " fname not a compressed file, so compress it
6695     NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
6696    endif
6697   endfor	" for every file in the marked list
6698
6699   call s:NetrwUnmarkList(curbufnr,curdir)
6700   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6701"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6702   NetrwKeepj call winrestview(svpos)
6703  endif
6704"  call Dret("s:NetrwMarkFileCompress")
6705endfun
6706
6707" ---------------------------------------------------------------------
6708" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
6709"                      If no marked files, then set up directory as the
6710"                      target.  Currently does not support copying entire
6711"                      directories.  Uses the local-buffer marked file list.
6712"                      Returns 1=success  (used by NetrwMarkFileMove())
6713"                              0=failure
6714fun! s:NetrwMarkFileCopy(islocal,...)
6715"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
6716
6717  let curdir   = s:NetrwGetCurdir(a:islocal)
6718  let curbufnr = bufnr("%")
6719  if b:netrw_curdir !~ '/$'
6720   if !exists("b:netrw_curdir")
6721    let b:netrw_curdir= curdir
6722   endif
6723   let b:netrw_curdir= b:netrw_curdir."/"
6724  endif
6725
6726  " sanity check
6727  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6728   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6729"   call Dret("s:NetrwMarkFileCopy")
6730   return
6731  endif
6732"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6733
6734  if !exists("s:netrwmftgt")
6735   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
6736"   call Dret("s:NetrwMarkFileCopy 0")
6737   return 0
6738  endif
6739"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
6740
6741  if a:islocal &&  s:netrwmftgt_islocal
6742   " Copy marked files, local directory to local directory
6743"   call Decho("copy from local to local",'~'.expand("<slnum>"))
6744   if !executable(g:netrw_localcopycmd) && g:netrw_localcopycmd !~ '^'.expand("$COMSPEC").'\s'
6745    call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
6746"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
6747    return
6748   endif
6749
6750   " copy marked files while within the same directory (ie. allow renaming)
6751   if simplify(s:netrwmftgt) == simplify(b:netrw_curdir)
6752    if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
6753     " only one marked file
6754"     call Decho("case: only one marked file",'~'.expand("<slnum>"))
6755     let args    = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
6756     let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
6757    elseif a:0 == 1
6758"     call Decho("case: handling one input argument",'~'.expand("<slnum>"))
6759     " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
6760     let args    = s:ShellEscape(b:netrw_curdir.a:1)
6761     let oldname = a:1
6762    else
6763     " copy multiple marked files inside the same directory
6764"     call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
6765     let s:recursive= 1
6766     for oldname in s:netrwmarkfilelist_{bufnr("%")}
6767      let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
6768      if ret == 0
6769       break
6770      endif
6771     endfor
6772     unlet s:recursive
6773     call s:NetrwUnmarkList(curbufnr,curdir)
6774"     call Dret("s:NetrwMarkFileCopy ".ret)
6775     return ret
6776    endif
6777
6778    call inputsave()
6779    let newname= input("Copy ".oldname." to : ",oldname,"file")
6780    call inputrestore()
6781    if newname == ""
6782"     call Dret("s:NetrwMarkFileCopy 0")
6783     return 0
6784    endif
6785    let args= s:ShellEscape(oldname)
6786    let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
6787   else
6788    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
6789    let tgt = s:ShellEscape(s:netrwmftgt)
6790   endif
6791   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
6792    let args= substitute(args,'/','\\','g')
6793    let tgt = substitute(tgt, '/','\\','g')
6794   endif
6795   if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
6796   if tgt  =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
6797   if args =~ '//'|let args= substitute(args,'//','/','g')|endif
6798   if tgt  =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
6799"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
6800"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
6801   if isdirectory(s:NetrwFile(args))
6802"    call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
6803    let copycmd= g:netrw_localcopydircmd
6804"    call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
6805    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
6806     " window's xcopy doesn't copy a directory to a target properly.  Instead, it copies a directory's
6807     " contents to a target.  One must append the source directory name to the target to get xcopy to
6808     " do the right thing.
6809     let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
6810"     call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
6811    endif
6812   else
6813    let copycmd= g:netrw_localcopycmd
6814   endif
6815   if g:netrw_localcopycmd =~ '\s'
6816    let copycmd     = substitute(copycmd,'\s.*$','','')
6817    let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
6818    let copycmd     = netrw#WinPath(copycmd).copycmdargs
6819   else
6820    let copycmd = netrw#WinPath(copycmd)
6821   endif
6822"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
6823"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
6824"   call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
6825"   call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
6826   call system(copycmd." '".args."' '".tgt."'")
6827   if v:shell_error != 0
6828    if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
6829     call netrw#ErrorMsg(s:ERROR,"copy failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",101)
6830    else
6831     call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
6832    endif
6833"    call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
6834    return 0
6835   endif
6836
6837  elseif  a:islocal && !s:netrwmftgt_islocal
6838   " Copy marked files, local directory to remote directory
6839"   call Decho("copy from local to remote",'~'.expand("<slnum>"))
6840   NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6841
6842  elseif !a:islocal &&  s:netrwmftgt_islocal
6843   " Copy marked files, remote directory to local directory
6844"   call Decho("copy from remote to local",'~'.expand("<slnum>"))
6845   NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6846
6847  elseif !a:islocal && !s:netrwmftgt_islocal
6848   " Copy marked files, remote directory to remote directory
6849"   call Decho("copy from remote to remote",'~'.expand("<slnum>"))
6850   let curdir = getcwd()
6851   let tmpdir = s:GetTempfile("")
6852   if tmpdir !~ '/'
6853    let tmpdir= curdir."/".tmpdir
6854   endif
6855   if exists("*mkdir")
6856    call mkdir(tmpdir)
6857   else
6858    call s:NetrwExe("sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1))
6859    if v:shell_error != 0
6860     call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6861"     call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
6862     return
6863    endif
6864   endif
6865   if isdirectory(s:NetrwFile(tmpdir))
6866    call s:NetrwLcd(tmpdir)
6867    NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
6868    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
6869    NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
6870    if getcwd() == tmpdir
6871     for fname in s:netrwmarkfilelist_{bufnr('%')}
6872      NetrwKeepj call s:NetrwDelete(fname)
6873     endfor
6874     call s:NetrwLcd(curdir)
6875     if v:version < 704 || !has("patch1109")
6876      call s:NetrwExe("sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1))
6877      if v:shell_error != 0
6878       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localrmdir<".g:netrw_localrmdir."> to something that works",80)
6879" "      call Dret("s:NetrwMarkFileCopy : failed: sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1) )
6880       return
6881      endif
6882     else
6883      if delete(tmpdir,"d")
6884       call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
6885      endif
6886     endif
6887    else
6888     call s:NetrwLcd(curdir)
6889    endif
6890   endif
6891  endif
6892
6893  " -------
6894  " cleanup
6895  " -------
6896"  call Decho("cleanup",'~'.expand("<slnum>"))
6897"  call Decho(" g:netrw_fastbrowse  =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
6898"  call Decho(" s:netrwmftgt        =".s:netrwmftgt,'~'.expand("<slnum>"))
6899"  call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
6900"  call Decho(" curdir              =".curdir,'~'.expand("<slnum>"))
6901"  call Decho(" a:islocal           =".a:islocal,'~'.expand("<slnum>"))
6902"  call Decho(" curbufnr            =".curbufnr,'~'.expand("<slnum>"))
6903  if exists("s:recursive")
6904"   call Decho(" s:recursive         =".s:recursive,'~'.expand("<slnum>"))
6905  else
6906"   call Decho(" s:recursive         =n/a",'~'.expand("<slnum>"))
6907  endif
6908  " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
6909  if g:netrw_fastbrowse <= 1
6910   NetrwKeepj call s:LocalBrowseRefresh()
6911  else
6912   " refresh local and targets for fast browsing
6913   if !exists("s:recursive")
6914    " remove markings from local buffer
6915"    call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
6916    NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
6917   endif
6918
6919   " refresh buffers
6920   if s:netrwmftgt_islocal
6921"    call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
6922    NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
6923   endif
6924   if a:islocal && s:netrwmftgt != curdir
6925"    call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
6926    NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
6927   endif
6928  endif
6929
6930"  call Dret("s:NetrwMarkFileCopy 1")
6931  return 1
6932endfun
6933
6934" ---------------------------------------------------------------------
6935" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
6936"                      invoke vim's diff mode on the marked files.
6937"                      Either two or three files can be so handled.
6938"                      Uses the global marked file list.
6939fun! s:NetrwMarkFileDiff(islocal)
6940"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6941  let curbufnr= bufnr("%")
6942
6943  " sanity check
6944  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6945   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6946"   call Dret("s:NetrwMarkFileDiff")
6947   return
6948  endif
6949  let curdir= s:NetrwGetCurdir(a:islocal)
6950"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6951
6952  if exists("s:netrwmarkfilelist_{".curbufnr."}")
6953   let cnt    = 0
6954   for fname in s:netrwmarkfilelist
6955    let cnt= cnt + 1
6956    if cnt == 1
6957"     call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
6958     exe "NetrwKeepj e ".fnameescape(fname)
6959     diffthis
6960    elseif cnt == 2 || cnt == 3
6961     vsplit
6962     wincmd l
6963"     call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
6964     exe "NetrwKeepj e ".fnameescape(fname)
6965     diffthis
6966    else
6967     break
6968    endif
6969   endfor
6970   call s:NetrwUnmarkList(curbufnr,curdir)
6971  endif
6972
6973"  call Dret("s:NetrwMarkFileDiff")
6974endfun
6975
6976" ---------------------------------------------------------------------
6977" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
6978"                       Uses global markfilelist
6979fun! s:NetrwMarkFileEdit(islocal)
6980"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
6981
6982  let curdir   = s:NetrwGetCurdir(a:islocal)
6983  let curbufnr = bufnr("%")
6984
6985  " sanity check
6986  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6987   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6988"   call Dret("s:NetrwMarkFileEdit")
6989   return
6990  endif
6991"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6992
6993  if exists("s:netrwmarkfilelist_{curbufnr}")
6994   call s:SetRexDir(a:islocal,curdir)
6995   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
6996   " unmark markedfile list
6997"   call s:NetrwUnmarkList(curbufnr,curdir)
6998   call s:NetrwUnmarkAll()
6999"   call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
7000   exe "sil args ".flist
7001  endif
7002  echo "(use :bn, :bp to navigate files; :Rex to return)"
7003
7004"  call Dret("s:NetrwMarkFileEdit")
7005endfun
7006
7007" ---------------------------------------------------------------------
7008" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
7009fun! s:NetrwMarkFileQFEL(islocal,qfel)
7010"  call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
7011  call s:NetrwUnmarkAll()
7012  let curbufnr= bufnr("%")
7013
7014  if !empty(a:qfel)
7015   for entry in a:qfel
7016    let bufnmbr= entry["bufnr"]
7017"    call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
7018    if !exists("s:netrwmarkfilelist_{curbufnr}")
7019"     call Decho("case: no marked file list",'~'.expand("<slnum>"))
7020     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7021    elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
7022     " s:NetrwMarkFile will remove duplicate entries from the marked file list.
7023     " So, this test lets two or more hits on the same pattern to be ignored.
7024"     call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
7025     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7026    else
7027"     call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
7028    endif
7029   endfor
7030   echo "(use me to edit marked files)"
7031  else
7032   call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
7033  endif
7034
7035"  call Dret("s:NetrwMarkFileQFEL")
7036endfun
7037
7038" ---------------------------------------------------------------------
7039" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
7040"                     mx enbloc=0: Uses the local marked-file list, applies command to each file individually
7041"                     mX enbloc=1: Uses the global marked-file list, applies command to entire list
7042fun! s:NetrwMarkFileExe(islocal,enbloc)
7043"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")")
7044  let svpos    = winsaveview()
7045"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7046  let curdir   = s:NetrwGetCurdir(a:islocal)
7047  let curbufnr = bufnr("%")
7048
7049  if a:enbloc == 0
7050   " individually apply command to files, one at a time
7051    " sanity check
7052    if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7053     NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7054"     call Dret("s:NetrwMarkFileExe")
7055     return
7056    endif
7057"    call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7058
7059    if exists("s:netrwmarkfilelist_{curbufnr}")
7060     " get the command
7061     call inputsave()
7062     let cmd= input("Enter command: ","","file")
7063     call inputrestore()
7064"     call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7065     if cmd == ""
7066"      call Dret("s:NetrwMarkFileExe : early exit, empty command")
7067      return
7068     endif
7069
7070     " apply command to marked files, individually.  Substitute: filename -> %
7071     " If no %, then append a space and the filename to the command
7072     for fname in s:netrwmarkfilelist_{curbufnr}
7073      if a:islocal
7074       if g:netrw_keepdir
7075	let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
7076       endif
7077      else
7078       let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
7079      endif
7080      if cmd =~ '%'
7081       let xcmd= substitute(cmd,'%',fname,'g')
7082      else
7083       let xcmd= cmd.' '.fname
7084      endif
7085      if a:islocal
7086"       call Decho("local: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7087       let ret= system(xcmd)
7088      else
7089"       call Decho("remote: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7090       let ret= s:RemoteSystem(xcmd)
7091      endif
7092      if v:shell_error < 0
7093       NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7094       break
7095      else
7096       echo ret
7097      endif
7098     endfor
7099
7100   " unmark marked file list
7101   call s:NetrwUnmarkList(curbufnr,curdir)
7102
7103   " refresh the listing
7104   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7105"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7106   NetrwKeepj call winrestview(svpos)
7107  else
7108   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7109  endif
7110
7111 else " apply command to global list of files, en bloc
7112
7113  call inputsave()
7114  let cmd= input("Enter command: ","","file")
7115  call inputrestore()
7116"  call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7117  if cmd == ""
7118"   call Dret("s:NetrwMarkFileExe : early exit, empty command")
7119   return
7120  endif
7121  if cmd =~ '%'
7122   let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7123  else
7124   let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7125  endif
7126  if a:islocal
7127   call system(cmd)
7128   if v:shell_error < 0
7129    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7130   endif
7131  else
7132   let ret= s:RemoteSystem(cmd)
7133  endif
7134  call s:NetrwUnmarkAll()
7135
7136  " refresh the listing
7137  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7138"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7139  NetrwKeepj call winrestview(svpos)
7140
7141 endif
7142
7143"  call Dret("s:NetrwMarkFileExe")
7144endfun
7145
7146" ---------------------------------------------------------------------
7147" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7148"                  as the marked file(s) (toggles suffix presence)
7149"                  Uses the local marked file list.
7150fun! s:NetrwMarkHideSfx(islocal)
7151"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7152  let svpos    = winsaveview()
7153"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7154  let curbufnr = bufnr("%")
7155
7156  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7157  if exists("s:netrwmarkfilelist_{curbufnr}")
7158
7159   for fname in s:netrwmarkfilelist_{curbufnr}
7160"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7161     " construct suffix pattern
7162     if fname =~ '\.'
7163      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7164     else
7165      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7166     endif
7167     " determine if its in the hiding list or not
7168     let inhidelist= 0
7169     if g:netrw_list_hide != ""
7170      let itemnum = 0
7171      let hidelist= split(g:netrw_list_hide,',')
7172      for hidepat in hidelist
7173       if sfxpat == hidepat
7174        let inhidelist= 1
7175        break
7176       endif
7177       let itemnum= itemnum + 1
7178      endfor
7179     endif
7180"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7181     if inhidelist
7182      " remove sfxpat from list
7183      call remove(hidelist,itemnum)
7184      let g:netrw_list_hide= join(hidelist,",")
7185     elseif g:netrw_list_hide != ""
7186      " append sfxpat to non-empty list
7187      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7188     else
7189      " set hiding list to sfxpat
7190      let g:netrw_list_hide= sfxpat
7191     endif
7192    endfor
7193
7194   " refresh the listing
7195   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7196"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7197   NetrwKeepj call winrestview(svpos)
7198  else
7199   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7200  endif
7201
7202"  call Dret("s:NetrwMarkHideSfx")
7203endfun
7204
7205" ---------------------------------------------------------------------
7206" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7207"                     Uses the local marked-file list.
7208fun! s:NetrwMarkFileVimCmd(islocal)
7209"  call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")")
7210  let svpos    = winsaveview()
7211"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7212  let curdir   = s:NetrwGetCurdir(a:islocal)
7213  let curbufnr = bufnr("%")
7214
7215  " sanity check
7216  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7217   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7218"   call Dret("s:NetrwMarkFileVimCmd")
7219   return
7220  endif
7221"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7222
7223  if exists("s:netrwmarkfilelist_{curbufnr}")
7224   " get the command
7225   call inputsave()
7226   let cmd= input("Enter vim command: ","","file")
7227   call inputrestore()
7228"   call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7229   if cmd == ""
7230"    "   call Dret("s:NetrwMarkFileVimCmd : early exit, empty command")
7231    return
7232   endif
7233
7234   " apply command to marked files.  Substitute: filename -> %
7235   " If no %, then append a space and the filename to the command
7236   for fname in s:netrwmarkfilelist_{curbufnr}
7237"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7238    if a:islocal
7239     1split
7240     exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7241"     call Decho("local<".fname.">: exe ".cmd,'~'.expand("<slnum>"))
7242     exe cmd
7243     exe "sil! keepalt wq!"
7244    else
7245"     call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET",'~'.expand("<slnum>"))
7246     echo "sorry, \"mv\" not supported yet for remote files"
7247    endif
7248   endfor
7249
7250   " unmark marked file list
7251   call s:NetrwUnmarkList(curbufnr,curdir)
7252
7253   " refresh the listing
7254   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7255"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7256   NetrwKeepj call winrestview(svpos)
7257  else
7258   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7259  endif
7260
7261"  call Dret("s:NetrwMarkFileVimCmd")
7262endfun
7263
7264" ---------------------------------------------------------------------
7265" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7266"                  as the marked file(s) (toggles suffix presence)
7267"                  Uses the local marked file list.
7268fun! s:NetrwMarkHideSfx(islocal)
7269"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7270  let svpos    = winsaveview()
7271"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7272  let curbufnr = bufnr("%")
7273
7274  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7275  if exists("s:netrwmarkfilelist_{curbufnr}")
7276
7277   for fname in s:netrwmarkfilelist_{curbufnr}
7278"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7279     " construct suffix pattern
7280     if fname =~ '\.'
7281      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7282     else
7283      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7284     endif
7285     " determine if its in the hiding list or not
7286     let inhidelist= 0
7287     if g:netrw_list_hide != ""
7288      let itemnum = 0
7289      let hidelist= split(g:netrw_list_hide,',')
7290      for hidepat in hidelist
7291       if sfxpat == hidepat
7292        let inhidelist= 1
7293        break
7294       endif
7295       let itemnum= itemnum + 1
7296      endfor
7297     endif
7298"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7299     if inhidelist
7300      " remove sfxpat from list
7301      call remove(hidelist,itemnum)
7302      let g:netrw_list_hide= join(hidelist,",")
7303     elseif g:netrw_list_hide != ""
7304      " append sfxpat to non-empty list
7305      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7306     else
7307      " set hiding list to sfxpat
7308      let g:netrw_list_hide= sfxpat
7309     endif
7310    endfor
7311
7312   " refresh the listing
7313   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7314"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7315   NetrwKeepj call winrestview(svpos)
7316  else
7317   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7318  endif
7319
7320"  call Dret("s:NetrwMarkHideSfx")
7321endfun
7322
7323" ---------------------------------------------------------------------
7324" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7325"                     Uses the global markfilelist
7326fun! s:NetrwMarkFileGrep(islocal)
7327"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7328  let svpos    = winsaveview()
7329"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7330  let curbufnr = bufnr("%")
7331  let curdir   = s:NetrwGetCurdir(a:islocal)
7332
7333  if exists("s:netrwmarkfilelist")
7334"  call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7335   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7336   call s:NetrwUnmarkAll()
7337  else
7338"   call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7339   let netrwmarkfilelist= "*"
7340  endif
7341
7342  " ask user for pattern
7343  call inputsave()
7344  let pat= input("Enter pattern: ","")
7345  call inputrestore()
7346  let patbang = ""
7347  if pat =~ '^!'
7348   let patbang = "!"
7349   let pat     = strpart(pat,2)
7350  endif
7351  if pat =~ '^\i'
7352   let pat    = escape(pat,'/')
7353   let pat    = '/'.pat.'/'
7354  else
7355   let nonisi = pat[0]
7356  endif
7357
7358  " use vimgrep for both local and remote
7359"  call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7360  try
7361   exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7362  catch /^Vim\%((\a\+)\)\=:E480/
7363   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7364"   call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7365   return
7366  endtry
7367  echo "(use :cn, :cp to navigate, :Rex to return)"
7368
7369  2match none
7370"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7371  NetrwKeepj call winrestview(svpos)
7372
7373  if exists("nonisi")
7374   " original, user-supplied pattern did not begin with a character from isident
7375"   call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7376   if pat =~ nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7377    call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7378   endif
7379  endif
7380
7381"  call Dret("s:NetrwMarkFileGrep")
7382endfun
7383
7384" ---------------------------------------------------------------------
7385" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7386"                      uses the global marked file list
7387"                      s:netrwmfloc= 0: target directory is remote
7388"                                  = 1: target directory is local
7389fun! s:NetrwMarkFileMove(islocal)
7390"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7391  let curdir   = s:NetrwGetCurdir(a:islocal)
7392  let curbufnr = bufnr("%")
7393
7394  " sanity check
7395  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7396   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7397"   call Dret("s:NetrwMarkFileMove")
7398   return
7399  endif
7400"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7401
7402  if !exists("s:netrwmftgt")
7403   NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7404"   call Dret("s:NetrwMarkFileCopy 0")
7405   return 0
7406  endif
7407"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7408
7409  if      a:islocal &&  s:netrwmftgt_islocal
7410   " move: local -> local
7411"   call Decho("move from local to local",'~'.expand("<slnum>"))
7412"   call Decho("local to local move",'~'.expand("<slnum>"))
7413   if !executable(g:netrw_localmovecmd) && g:netrw_localmovecmd !~ '^'.expand("$COMSPEC").'\s'
7414    call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7415"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7416    return
7417   endif
7418   let tgt         = s:ShellEscape(s:netrwmftgt)
7419"   call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7420   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7421    let tgt         = substitute(tgt, '/','\\','g')
7422"    call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7423    if g:netrw_localmovecmd =~ '\s'
7424     let movecmd     = substitute(g:netrw_localmovecmd,'\s.*$','','')
7425     let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7426     let movecmd     = netrw#WinPath(movecmd).movecmdargs
7427"     call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7428    else
7429     let movecmd = netrw#WinPath(movecmd)
7430"     call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7431    endif
7432   else
7433    let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7434"    call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7435   endif
7436   for fname in s:netrwmarkfilelist_{bufnr("%")}
7437    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7438     let fname= substitute(fname,'/','\\','g')
7439    endif
7440"    call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7441    let ret= system(movecmd." ".s:ShellEscape(fname)." ".tgt)
7442    if v:shell_error != 0
7443     if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7444      call netrw#ErrorMsg(s:ERROR,"move failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",100)
7445     else
7446      call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7447     endif
7448     break
7449    endif
7450   endfor
7451
7452  elseif  a:islocal && !s:netrwmftgt_islocal
7453   " move: local -> remote
7454"   call Decho("move from local to remote",'~'.expand("<slnum>"))
7455"   call Decho("copy",'~'.expand("<slnum>"))
7456   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7457   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7458"   call Decho("remove",'~'.expand("<slnum>"))
7459   for fname in mflist
7460    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7461    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7462   endfor
7463   unlet mflist
7464
7465  elseif !a:islocal &&  s:netrwmftgt_islocal
7466   " move: remote -> local
7467"   call Decho("move from remote to local",'~'.expand("<slnum>"))
7468"   call Decho("copy",'~'.expand("<slnum>"))
7469   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7470   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7471"   call Decho("remove",'~'.expand("<slnum>"))
7472   for fname in mflist
7473    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7474    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7475   endfor
7476   unlet mflist
7477
7478  elseif !a:islocal && !s:netrwmftgt_islocal
7479   " move: remote -> remote
7480"   call Decho("move from remote to remote",'~'.expand("<slnum>"))
7481"   call Decho("copy",'~'.expand("<slnum>"))
7482   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7483   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7484"   call Decho("remove",'~'.expand("<slnum>"))
7485   for fname in mflist
7486    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7487    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7488   endfor
7489   unlet mflist
7490  endif
7491
7492  " -------
7493  " cleanup
7494  " -------
7495"  call Decho("cleanup",'~'.expand("<slnum>"))
7496
7497  " remove markings from local buffer
7498  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7499
7500  " refresh buffers
7501  if !s:netrwmftgt_islocal
7502"   call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7503   NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7504  endif
7505  if a:islocal
7506"   call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7507   NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7508  endif
7509  if g:netrw_fastbrowse <= 1
7510"   call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7511   NetrwKeepj call s:LocalBrowseRefresh()
7512  endif
7513
7514"  call Dret("s:NetrwMarkFileMove")
7515endfun
7516
7517" ---------------------------------------------------------------------
7518" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7519"                       using the hardcopy command.  Local marked-file list only.
7520fun! s:NetrwMarkFilePrint(islocal)
7521"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7522  let curbufnr= bufnr("%")
7523
7524  " sanity check
7525  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7526   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7527"   call Dret("s:NetrwMarkFilePrint")
7528   return
7529  endif
7530"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7531  let curdir= s:NetrwGetCurdir(a:islocal)
7532
7533  if exists("s:netrwmarkfilelist_{curbufnr}")
7534   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7535   call s:NetrwUnmarkList(curbufnr,curdir)
7536   for fname in netrwmarkfilelist
7537    if a:islocal
7538     if g:netrw_keepdir
7539      let fname= s:ComposePath(curdir,fname)
7540     endif
7541    else
7542     let fname= curdir.fname
7543    endif
7544    1split
7545    " the autocmds will handle both local and remote files
7546"    call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7547    exe "sil NetrwKeepj e ".fnameescape(fname)
7548"    call Decho("hardcopy",'~'.expand("<slnum>"))
7549    hardcopy
7550    q
7551   endfor
7552   2match none
7553  endif
7554"  call Dret("s:NetrwMarkFilePrint")
7555endfun
7556
7557" ---------------------------------------------------------------------
7558" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7559"                        files when given a regexp (for which a prompt is
7560"                        issued) (matches to name of files).
7561fun! s:NetrwMarkFileRegexp(islocal)
7562"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7563
7564  " get the regular expression
7565  call inputsave()
7566  let regexp= input("Enter regexp: ","","file")
7567  call inputrestore()
7568
7569  if a:islocal
7570   let curdir= s:NetrwGetCurdir(a:islocal)
7571   " get the matching list of files using local glob()
7572"   call Decho("handle local regexp",'~'.expand("<slnum>"))
7573   let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7574   if v:version == 704 && has("patch656")
7575    let files   = glob(s:ComposePath(dirname,regexp),0,0,1)
7576   else
7577    let files   = glob(s:ComposePath(dirname,regexp),0,0)
7578   endif
7579"   call Decho("files<".files.">",'~'.expand("<slnum>"))
7580   let filelist= split(files,"\n")
7581
7582  " mark the list of files
7583  for fname in filelist
7584"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7585   NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7586  endfor
7587
7588  else
7589"   call Decho("handle remote regexp",'~'.expand("<slnum>"))
7590
7591   " convert displayed listing into a filelist
7592   let eikeep = &ei
7593   let areg   = @a
7594   sil NetrwKeepj %y a
7595   setl ei=all ma
7596"   call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7597   1split
7598   NetrwKeepj call s:NetrwEnew()
7599   NetrwKeepj call s:NetrwSafeOptions()
7600   sil NetrwKeepj norm! "ap
7601   NetrwKeepj 2
7602   let bannercnt= search('^" =====','W')
7603   exe "sil NetrwKeepj 1,".bannercnt."d"
7604   setl bt=nofile
7605   if     g:netrw_liststyle == s:LONGLIST
7606    sil NetrwKeepj %s/\s\{2,}\S.*$//e
7607    call histdel("/",-1)
7608   elseif g:netrw_liststyle == s:WIDELIST
7609    sil NetrwKeepj %s/\s\{2,}/\r/ge
7610    call histdel("/",-1)
7611   elseif g:netrw_liststyle == s:TREELIST
7612    exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7613    sil! NetrwKeepj g/^ .*$/d
7614    call histdel("/",-1)
7615    call histdel("/",-1)
7616   endif
7617   " convert regexp into the more usual glob-style format
7618   let regexp= substitute(regexp,'\*','.*','g')
7619"   call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7620   exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7621   call histdel("/",-1)
7622   let filelist= getline(1,line("$"))
7623   q!
7624   for filename in filelist
7625    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7626   endfor
7627   unlet filelist
7628   let @a  = areg
7629   let &ei = eikeep
7630  endif
7631  echo "  (use me to edit marked files)"
7632
7633"  call Dret("s:NetrwMarkFileRegexp")
7634endfun
7635
7636" ---------------------------------------------------------------------
7637" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7638"                        Uses the local marked file list.
7639fun! s:NetrwMarkFileSource(islocal)
7640"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7641  let curbufnr= bufnr("%")
7642
7643  " sanity check
7644  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7645   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7646"   call Dret("s:NetrwMarkFileSource")
7647   return
7648  endif
7649"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7650  let curdir= s:NetrwGetCurdir(a:islocal)
7651
7652  if exists("s:netrwmarkfilelist_{curbufnr}")
7653   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7654   call s:NetrwUnmarkList(curbufnr,curdir)
7655   for fname in netrwmarkfilelist
7656    if a:islocal
7657     if g:netrw_keepdir
7658      let fname= s:ComposePath(curdir,fname)
7659     endif
7660    else
7661     let fname= curdir.fname
7662    endif
7663    " the autocmds will handle sourcing both local and remote files
7664"    call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7665    exe "so ".fnameescape(fname)
7666   endfor
7667   2match none
7668  endif
7669"  call Dret("s:NetrwMarkFileSource")
7670endfun
7671
7672" ---------------------------------------------------------------------
7673" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
7674"                     Uses the global markfilelist
7675fun! s:NetrwMarkFileTag(islocal)
7676"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
7677  let svpos    = winsaveview()
7678"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7679  let curdir   = s:NetrwGetCurdir(a:islocal)
7680  let curbufnr = bufnr("%")
7681
7682  " sanity check
7683  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7684   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7685"   call Dret("s:NetrwMarkFileTag")
7686   return
7687  endif
7688"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7689
7690  if exists("s:netrwmarkfilelist")
7691"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7692   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
7693   call s:NetrwUnmarkAll()
7694
7695   if a:islocal
7696    if executable(g:netrw_ctags)
7697"     call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("<slnum>"))
7698     call system(g:netrw_ctags." ".netrwmarkfilelist)
7699    else
7700     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
7701    endif
7702   else
7703    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
7704    call netrw#Obtain(a:islocal,"tags")
7705    let curdir= b:netrw_curdir
7706    1split
7707    NetrwKeepj e tags
7708    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
7709"    call Decho("curdir<".curdir."> path<".path.">",'~'.expand("<slnum>"))
7710    exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
7711    call histdel("/",-1)
7712    wq!
7713   endif
7714   2match none
7715   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7716"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7717   call winrestview(svpos)
7718  endif
7719
7720"  call Dret("s:NetrwMarkFileTag")
7721endfun
7722
7723" ---------------------------------------------------------------------
7724" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
7725"   Sets up two variables,
7726"     s:netrwmftgt         : holds the target directory
7727"     s:netrwmftgt_islocal : 0=target directory is remote
7728"                            1=target directory is local
7729fun! s:NetrwMarkFileTgt(islocal)
7730" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
7731  let svpos  = winsaveview()
7732"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7733  let curdir = s:NetrwGetCurdir(a:islocal)
7734  let hadtgt = exists("s:netrwmftgt")
7735  if !exists("w:netrw_bannercnt")
7736   let w:netrw_bannercnt= b:netrw_bannercnt
7737  endif
7738
7739  " set up target
7740  if line(".") < w:netrw_bannercnt
7741"   call Decho("set up target: line(.) < w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
7742   " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
7743   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
7744"    call Decho("cursor in banner region, and target already is <".b:netrw_curdir.">: removing target",'~'.expand("<slnum>"))
7745    unlet s:netrwmftgt s:netrwmftgt_islocal
7746    if g:netrw_fastbrowse <= 1
7747     call s:LocalBrowseRefresh()
7748    endif
7749    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7750"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7751    call winrestview(svpos)
7752"    call Dret("s:NetrwMarkFileTgt : removed target")
7753    return
7754   else
7755    let s:netrwmftgt= b:netrw_curdir
7756"    call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7757   endif
7758
7759  else
7760   " get word under cursor.
7761   "  * If directory, use it for the target.
7762   "  * If file, use b:netrw_curdir for the target
7763"   call Decho("get word under cursor",'~'.expand("<slnum>"))
7764   let curword= s:NetrwGetWord()
7765   let tgtdir = s:ComposePath(curdir,curword)
7766   if a:islocal && isdirectory(s:NetrwFile(tgtdir))
7767    let s:netrwmftgt = tgtdir
7768"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7769   elseif !a:islocal && tgtdir =~ '/$'
7770    let s:netrwmftgt = tgtdir
7771"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7772   else
7773    let s:netrwmftgt = curdir
7774"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7775   endif
7776  endif
7777  if a:islocal
7778   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
7779   let s:netrwmftgt= simplify(s:netrwmftgt)
7780"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7781  endif
7782  if g:netrw_cygwin
7783   let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
7784   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
7785  endif
7786  let s:netrwmftgt_islocal= a:islocal
7787
7788  " need to do refresh so that the banner will be updated
7789  "  s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
7790  if g:netrw_fastbrowse <= 1
7791"   call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers")
7792   call s:LocalBrowseRefresh()
7793  endif
7794"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7795  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7796   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop))
7797  else
7798   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7799  endif
7800"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7801  call winrestview(svpos)
7802  if !hadtgt
7803   sil! NetrwKeepj norm! j
7804  endif
7805
7806"  call Decho("getmatches=".string(getmatches()),'~'.expand("<slnum>"))
7807"  call Decho("s:netrwmarkfilelist=".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : 'n/a'),'~'.expand("<slnum>"))
7808"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
7809endfun
7810
7811" ---------------------------------------------------------------------
7812" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
7813fun! s:NetrwGetCurdir(islocal)
7814"  call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
7815
7816  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7817   let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
7818"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
7819  elseif !exists("b:netrw_curdir")
7820   let b:netrw_curdir= getcwd()
7821"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
7822  endif
7823
7824"  call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern")
7825  if b:netrw_curdir !~ '\<\a\{3,}://'
7826   let curdir= b:netrw_curdir
7827"   call Decho("g:netrw_keepdir=".g:netrw_keepdir)
7828   if g:netrw_keepdir == 0
7829    call s:NetrwLcd(curdir)
7830   endif
7831  endif
7832
7833"  call Dret("s:NetrwGetCurdir <".curdir.">")
7834  return b:netrw_curdir
7835endfun
7836
7837" ---------------------------------------------------------------------
7838" s:NetrwOpenFile: query user for a filename and open it {{{2
7839fun! s:NetrwOpenFile(islocal)
7840"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
7841  let ykeep= @@
7842  call inputsave()
7843  let fname= input("Enter filename: ")
7844  call inputrestore()
7845  if fname !~ '[/\\]'
7846   if exists("b:netrw_curdir")
7847    if exists("g:netrw_quiet")
7848     let netrw_quiet_keep = g:netrw_quiet
7849    endif
7850    let g:netrw_quiet = 1
7851    " save position for benefit of Rexplore
7852    let s:rexposn_{bufnr("%")}= winsaveview()
7853"    call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
7854    if b:netrw_curdir =~ '/$'
7855     exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
7856    else
7857     exe "e ".fnameescape(b:netrw_curdir."/".fname)
7858    endif
7859    if exists("netrw_quiet_keep")
7860     let g:netrw_quiet= netrw_quiet_keep
7861    else
7862     unlet g:netrw_quiet
7863    endif
7864   endif
7865  else
7866   exe "NetrwKeepj e ".fnameescape(fname)
7867  endif
7868  let @@= ykeep
7869"  call Dret("s:NetrwOpenFile")
7870endfun
7871
7872" ---------------------------------------------------------------------
7873" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
7874"               For the mapping to this function be made via
7875"               netrwPlugin, you'll need to have had
7876"               g:netrw_usetab set to non-zero.
7877fun! netrw#Shrink()
7878"  call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
7879  let curwin  = winnr()
7880  let wiwkeep = &wiw
7881  set wiw=1
7882
7883  if &ft == "netrw"
7884   if winwidth(0) > g:netrw_wiw
7885    let t:netrw_winwidth= winwidth(0)
7886    exe "vert resize ".g:netrw_wiw
7887    wincmd l
7888    if winnr() == curwin
7889     wincmd h
7890    endif
7891"    call Decho("vert resize 0",'~'.expand("<slnum>"))
7892   else
7893    exe "vert resize ".t:netrw_winwidth
7894"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7895   endif
7896
7897  elseif exists("t:netrw_lexbufnr")
7898   exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
7899   if     winwidth(bufwinnr(t:netrw_lexbufnr)) >  g:netrw_wiw
7900    let t:netrw_winwidth= winwidth(0)
7901    exe "vert resize ".g:netrw_wiw
7902    wincmd l
7903    if winnr() == curwin
7904     wincmd h
7905    endif
7906"    call Decho("vert resize 0",'~'.expand("<slnum>"))
7907   elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
7908    exe "vert resize ".t:netrw_winwidth
7909"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7910   else
7911    call netrw#Lexplore(0,0)
7912   endif
7913
7914  else
7915   call netrw#Lexplore(0,0)
7916  endif
7917  let wiw= wiwkeep
7918
7919"  call Dret("netrw#Shrink")
7920endfun
7921
7922" ---------------------------------------------------------------------
7923" s:NetSortSequence: allows user to edit the sorting sequence {{{2
7924fun! s:NetSortSequence(islocal)
7925"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
7926
7927  let ykeep= @@
7928  let svpos= winsaveview()
7929"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7930  call inputsave()
7931  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
7932  call inputrestore()
7933
7934  " refresh the listing
7935  let g:netrw_sort_sequence= newsortseq
7936  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7937"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7938  NetrwKeepj call winrestview(svpos)
7939  let @@= ykeep
7940
7941"  call Dret("NetSortSequence")
7942endfun
7943
7944" ---------------------------------------------------------------------
7945" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
7946"   User access provided by the <mF> mapping. (see :help netrw-mF)
7947"   Used by many MarkFile functions.
7948fun! s:NetrwUnmarkList(curbufnr,curdir)
7949"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
7950
7951  "  remove all files in local marked-file list from global list
7952  if exists("s:netrwmarkfilelist")
7953   for mfile in s:netrwmarkfilelist_{a:curbufnr}
7954    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
7955    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
7956    call remove(s:netrwmarkfilelist,idx)            " remove from global list
7957   endfor
7958   if s:netrwmarkfilelist == []
7959    unlet s:netrwmarkfilelist
7960   endif
7961
7962   " getting rid of the local marked-file lists is easy
7963   unlet s:netrwmarkfilelist_{a:curbufnr}
7964  endif
7965  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
7966   unlet s:netrwmarkfilemtch_{a:curbufnr}
7967  endif
7968  2match none
7969"  call Dret("s:NetrwUnmarkList")
7970endfun
7971
7972" ---------------------------------------------------------------------
7973" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
7974fun! s:NetrwUnmarkAll()
7975"  call Dfunc("s:NetrwUnmarkAll()")
7976  if exists("s:netrwmarkfilelist")
7977   unlet s:netrwmarkfilelist
7978  endif
7979  sil call s:NetrwUnmarkAll2()
7980  2match none
7981"  call Dret("s:NetrwUnmarkAll")
7982endfun
7983
7984" ---------------------------------------------------------------------
7985" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
7986fun! s:NetrwUnmarkAll2()
7987"  call Dfunc("s:NetrwUnmarkAll2()")
7988  redir => netrwmarkfilelist_let
7989  let
7990  redir END
7991  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
7992  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
7993  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
7994  for flist in netrwmarkfilelist_list
7995   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
7996   unlet s:netrwmarkfilelist_{curbufnr}
7997   unlet s:netrwmarkfilemtch_{curbufnr}
7998  endfor
7999"  call Dret("s:NetrwUnmarkAll2")
8000endfun
8001
8002" ---------------------------------------------------------------------
8003" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
8004"
8005" Marked files are in two types of lists:
8006"    s:netrwmarkfilelist    -- holds complete paths to all marked files
8007"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
8008"
8009" Marked files suitable for use with 2match are in:
8010"    s:netrwmarkfilemtch_#   -- used with 2match to display marked files
8011fun! s:NetrwUnMarkFile(islocal)
8012"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
8013  let svpos    = winsaveview()
8014"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8015  let curbufnr = bufnr("%")
8016
8017  " unmark marked file list
8018  " (although I expect s:NetrwUpload() to do it, I'm just making sure)
8019  if exists("s:netrwmarkfilelist")
8020"   "   call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
8021   unlet s:netrwmarkfilelist
8022  endif
8023
8024  let ibuf= 1
8025  while ibuf < bufnr("$")
8026   if exists("s:netrwmarkfilelist_".ibuf)
8027    unlet s:netrwmarkfilelist_{ibuf}
8028    unlet s:netrwmarkfilemtch_{ibuf}
8029   endif
8030   let ibuf = ibuf + 1
8031  endwhile
8032  2match none
8033
8034"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8035"call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8036call winrestview(svpos)
8037"  call Dret("s:NetrwUnMarkFile")
8038endfun
8039
8040" ---------------------------------------------------------------------
8041" s:NetrwMenu: generates the menu for gvim and netrw {{{2
8042fun! s:NetrwMenu(domenu)
8043
8044  if !exists("g:NetrwMenuPriority")
8045   let g:NetrwMenuPriority= 80
8046  endif
8047
8048  if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8049"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
8050
8051   if !exists("s:netrw_menu_enabled") && a:domenu
8052"    call Decho("initialize menu",'~'.expand("<slnum>"))
8053    let s:netrw_menu_enabled= 1
8054    exe 'sil! menu '.g:NetrwMenuPriority.'.1      '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
8055    exe 'sil! menu '.g:NetrwMenuPriority.'.5      '.g:NetrwTopLvlMenu.'-Sep1-	:'
8056    exe 'sil! menu '.g:NetrwMenuPriority.'.6      '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
8057    exe 'sil! menu '.g:NetrwMenuPriority.'.7      '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
8058    if g:netrw_dirhistmax > 0
8059     exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
8060     exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
8061     exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
8062     exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
8063    else
8064     exe 'sil! menu '.g:NetrwMenuPriority.'.8     '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History	:echo "(disabled)"'."\<cr>"
8065    endif
8066    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1    '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o	o'
8067    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2    '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v	v'
8068    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3    '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t	t'
8069    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4    '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p	p'
8070    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
8071    exe 'sil! menu '.g:NetrwMenuPriority.'.9.6    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
8072    exe 'sil! menu '.g:NetrwMenuPriority.'.9.7    '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
8073    exe 'sil! menu '.g:NetrwMenuPriority.'.9.8    '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
8074    exe 'sil! menu '.g:NetrwMenuPriority.'.9.9    '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
8075    exe 'sil! menu '.g:NetrwMenuPriority.'.10     '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
8076    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
8077    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
8078    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
8079    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
8080    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
8081    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t	t'
8082    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
8083    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1   '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
8084    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
8085    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
8086    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
8087    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
8088    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
8089    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
8090    exe 'sil! menu '.g:NetrwMenuPriority.'.13     '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
8091    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
8092    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
8093    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3   '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
8094    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4   '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
8095    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5   '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
8096    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6   '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
8097    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7   '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
8098    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8   '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
8099    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9   '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
8100    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10  '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
8101    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11  '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
8102    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12  '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
8103    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13  '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
8104    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14  '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
8105    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15  '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
8106    exe 'sil! menu '.g:NetrwMenuPriority.'.15     '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
8107    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i	:let w:netrw_liststyle=0<cr><c-L>'
8108    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i	:let w:netrw_liststyle=1<cr><c-L>'
8109    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i	:let w:netrw_liststyle=2<cr><c-L>'
8110    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i	:let w:netrw_liststyle=3<cr><c-L>'
8111    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>'
8112    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>'
8113    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>'
8114    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3   '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
8115    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>'
8116    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>'
8117    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>'
8118    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>'
8119    exe 'sil! menu '.g:NetrwMenuPriority.'.17     '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
8120    exe 'sil! menu '.g:NetrwMenuPriority.'.18     '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
8121    let s:netrw_menucnt= 28
8122    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
8123    call s:NetrwTgtMenu()      " let bookmarks and history be easy targets
8124
8125   elseif !a:domenu
8126    let s:netrwcnt = 0
8127    let curwin     = winnr()
8128    windo if getline(2) =~ "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8129    exe curwin."wincmd w"
8130
8131    if s:netrwcnt <= 1
8132"     call Decho("clear menus",'~'.expand("<slnum>"))
8133     exe 'sil! unmenu '.g:NetrwTopLvlMenu
8134"     call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8135     sil! unlet s:netrw_menu_enabled
8136    endif
8137   endif
8138"   call Dret("NetrwMenu")
8139   return
8140  endif
8141
8142endfun
8143
8144" ---------------------------------------------------------------------
8145" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8146"                Used by the O maps (as <SID>NetrwObtain())
8147fun! s:NetrwObtain(islocal)
8148"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8149
8150  let ykeep= @@
8151  if exists("s:netrwmarkfilelist_{bufnr('%')}")
8152   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8153   call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8154   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
8155  else
8156   call netrw#Obtain(a:islocal,expand("<cWORD>"))
8157  endif
8158  let @@= ykeep
8159
8160"  call Dret("NetrwObtain")
8161endfun
8162
8163" ---------------------------------------------------------------------
8164" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
8165"   If there's only one window, then the window will first be split.
8166"   Returns:
8167"     choice = 0 : didn't have to choose
8168"     choice = 1 : saved modified file in window first
8169"     choice = 2 : didn't save modified file, opened window
8170"     choice = 3 : cancel open
8171fun! s:NetrwPrevWinOpen(islocal)
8172"  call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")")
8173
8174  let ykeep= @@
8175  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8176  let curdir = b:netrw_curdir
8177
8178  " get last window number and the word currently under the cursor
8179  let origwin   = winnr()
8180  let lastwinnr = winnr("$")
8181  let curword   = s:NetrwGetWord()
8182  let choice    = 0
8183  let s:treedir = s:NetrwTreeDir(a:islocal)
8184  let curdir    = s:treedir
8185"  call Decho("winnr($)#".lastwinnr." curword<".curword.">",'~'.expand("<slnum>"))
8186
8187  let didsplit = 0
8188  if lastwinnr == 1
8189   " if only one window, open a new one first
8190"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("<slnum>"))
8191   if g:netrw_preview
8192    " vertically split preview window
8193    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8194"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("<slnum>"))
8195    exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8196   else
8197    " horizontally split preview window
8198    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8199"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8200    exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8201   endif
8202   let didsplit = 1
8203"   call Decho("did split",'~'.expand("<slnum>"))
8204
8205  else
8206   NetrwKeepj call s:SaveBufVars()
8207   let eikeep= &ei
8208   setl ei=all
8209   wincmd p
8210"   call Decho("wincmd p  (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
8211
8212   " prevwinnr: the window number of the "prev" window
8213   " prevbufnr: the buffer number of the buffer in the "prev" window
8214   " bnrcnt   : the qty of windows open on the "prev" buffer
8215   let prevwinnr   = winnr()
8216   let prevbufnr   = bufnr("%")
8217   let prevbufname = bufname("%")
8218   let prevmod     = &mod
8219   let bnrcnt      = 0
8220   NetrwKeepj call s:RestoreBufVars()
8221"   call Decho("after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr,'~'.expand("<slnum>"))
8222
8223   " if the previous window's buffer has been changed (ie. its modified flag is set),
8224   " and it doesn't appear in any other extant window, then ask the
8225   " user if s/he wants to abandon modifications therein.
8226   if prevmod
8227"    call Decho("detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr(),'~'.expand("<slnum>"))
8228    windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8229"    call Decho("prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr,'~'.expand("<slnum>"))
8230    exe prevwinnr."wincmd w"
8231
8232    if bnrcnt == 1 && &hidden == 0
8233     " only one copy of the modified buffer in a window, and
8234     " hidden not set, so overwriting will lose the modified file.  Ask first...
8235     let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8236"     call Decho("(NetrwPrevWinOpen) prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("<slnum>"))
8237     let &ei= eikeep
8238
8239     if choice == 1
8240      " Yes -- write file & then browse
8241      let v:errmsg= ""
8242      sil w
8243      if v:errmsg != ""
8244       call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8245       exe origwin."wincmd w"
8246       let &ei = eikeep
8247       let @@  = ykeep
8248"       call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">")
8249       return choice
8250      endif
8251
8252     elseif choice == 2
8253      " No -- don't worry about changed file, just browse anyway
8254"      call Decho("don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")",'~'.expand("<slnum>"))
8255      echomsg "**note** changes to ".prevbufname." abandoned"
8256
8257     else
8258      " Cancel -- don't do this
8259"      call Decho("cancel, don't browse, switch to win#".origwin,'~'.expand("<slnum>"))
8260      exe origwin."wincmd w"
8261      let &ei= eikeep
8262      let @@ = ykeep
8263"      call Dret("s:NetrwPrevWinOpen ".choice." : cancelled")
8264      return choice
8265     endif
8266    endif
8267   endif
8268   let &ei= eikeep
8269  endif
8270
8271  " restore b:netrw_curdir (window split/enew may have lost it)
8272  let b:netrw_curdir= curdir
8273  if a:islocal < 2
8274   if a:islocal
8275    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
8276   else
8277    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
8278   endif
8279  endif
8280  let @@= ykeep
8281"  call Dret("s:NetrwPrevWinOpen ".choice)
8282  return choice
8283endfun
8284
8285" ---------------------------------------------------------------------
8286" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8287"                Always assumed to be local -> remote
8288"                call s:NetrwUpload(filename, target)
8289"                call s:NetrwUpload(filename, target, fromdirectory)
8290fun! s:NetrwUpload(fname,tgt,...)
8291"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
8292
8293  if a:tgt =~ '^\a\{3,}://'
8294   let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
8295  else
8296   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
8297  endif
8298"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
8299
8300  if a:0 > 0
8301   let fromdir= a:1
8302  else
8303   let fromdir= getcwd()
8304  endif
8305"  call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
8306
8307  if type(a:fname) == 1
8308   " handle uploading a single file using NetWrite
8309"   call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8310   1split
8311"   call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8312   exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8313"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8314   if a:tgt =~ '/$'
8315    let wfname= substitute(a:fname,'^.*/','','')
8316"    call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8317    exe "w! ".fnameescape(a:tgt.wfname)
8318   else
8319"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8320    exe "w ".fnameescape(a:tgt)
8321"    call Decho("done writing local->remote",'~'.expand("<slnum>"))
8322   endif
8323   q!
8324
8325  elseif type(a:fname) == 3
8326   " handle uploading a list of files via scp
8327"   call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8328   let curdir= getcwd()
8329   if a:tgt =~ '^scp:'
8330    call s:NetrwLcd(fromdir)
8331    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8332    let args    = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8333    if exists("g:netrw_port") && g:netrw_port != ""
8334     let useport= " ".g:netrw_scpport." ".g:netrw_port
8335    else
8336     let useport= ""
8337    endif
8338    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8339    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8340    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8341    call s:NetrwLcd(curdir)
8342
8343   elseif a:tgt =~ '^ftp:'
8344    call s:NetrwMethod(a:tgt)
8345
8346    if b:netrw_method == 2
8347     " handle uploading a list of files via ftp+.netrc
8348     let netrw_fname = b:netrw_fname
8349     sil NetrwKeepj new
8350"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8351
8352     NetrwKeepj put =g:netrw_ftpmode
8353"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8354
8355     if exists("g:netrw_ftpextracmd")
8356      NetrwKeepj put =g:netrw_ftpextracmd
8357"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8358     endif
8359
8360     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8361"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8362
8363     if tgtdir == ""
8364      let tgtdir= '/'
8365     endif
8366     NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8367"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8368
8369     for fname in a:fname
8370      NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8371"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8372     endfor
8373
8374     if exists("g:netrw_port") && g:netrw_port != ""
8375      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8376     else
8377"      call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8378      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8379     endif
8380     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8381     sil NetrwKeepj g/Local directory now/d
8382     call histdel("/",-1)
8383     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8384      call netrw#ErrorMsg(s:ERROR,getline(1),14)
8385     else
8386      bw!|q
8387     endif
8388
8389    elseif b:netrw_method == 3
8390     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8391     let netrw_fname= b:netrw_fname
8392     NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8393     let tmpbufnr= bufnr("%")
8394     setl ff=unix
8395
8396     if exists("g:netrw_port") && g:netrw_port != ""
8397      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8398"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8399     else
8400      NetrwKeepj put ='open '.g:netrw_machine
8401"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8402     endif
8403
8404     if exists("g:netrw_uid") && g:netrw_uid != ""
8405      if exists("g:netrw_ftp") && g:netrw_ftp == 1
8406       NetrwKeepj put =g:netrw_uid
8407"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8408       if exists("s:netrw_passwd")
8409        NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8410       endif
8411"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8412      elseif exists("s:netrw_passwd")
8413       NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8414"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8415      endif
8416     endif
8417
8418     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8419"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8420
8421     if exists("b:netrw_fname") && b:netrw_fname != ""
8422      NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8423"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8424     endif
8425
8426     if exists("g:netrw_ftpextracmd")
8427      NetrwKeepj put =g:netrw_ftpextracmd
8428"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8429     endif
8430
8431     for fname in a:fname
8432      NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8433"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8434     endfor
8435
8436     " perform ftp:
8437     " -i       : turns off interactive prompting from ftp
8438     " -n  unix : DON'T use <.netrc>, even though it exists
8439     " -n  win32: quit being obnoxious about password
8440     NetrwKeepj norm! 1Gdd
8441     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8442     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8443     sil NetrwKeepj g/Local directory now/d
8444     call histdel("/",-1)
8445     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8446      let debugkeep= &debug
8447      setl debug=msg
8448      call netrw#ErrorMsg(s:ERROR,getline(1),15)
8449      let &debug = debugkeep
8450      let mod    = 1
8451     else
8452      bw!|q
8453     endif
8454    elseif !exists("b:netrw_method") || b:netrw_method < 0
8455"     call Dfunc("netrw#NetrwUpload : unsupported method")
8456     return
8457    endif
8458   else
8459    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
8460   endif
8461  endif
8462
8463"  call Dret("s:NetrwUpload")
8464endfun
8465
8466" ---------------------------------------------------------------------
8467" s:NetrwPreview: {{{2
8468fun! s:NetrwPreview(path) range
8469"  call Dfunc("NetrwPreview(path<".a:path.">)")
8470  let ykeep= @@
8471  NetrwKeepj call s:NetrwOptionSave("s:")
8472  NetrwKeepj call s:NetrwSafeOptions()
8473  if has("quickfix")
8474   if !isdirectory(s:NetrwFile(a:path))
8475    if g:netrw_preview && !g:netrw_alto
8476     let pvhkeep = &pvh
8477     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8478     let &pvh    = winwidth(0) - winsz
8479    endif
8480    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8481    if exists("pvhkeep")
8482     let &pvh= pvhkeep
8483    endif
8484   elseif !exists("g:netrw_quiet")
8485    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
8486   endif
8487  elseif !exists("g:netrw_quiet")
8488   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
8489  endif
8490  NetrwKeepj call s:NetrwOptionRestore("s:")
8491  let @@= ykeep
8492"  call Dret("NetrwPreview")
8493endfun
8494
8495" ---------------------------------------------------------------------
8496" s:NetrwRefresh: {{{2
8497fun! s:NetrwRefresh(islocal,dirname)
8498"  call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction)
8499  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
8500  setl ma noro
8501"  call Decho("setl ma noro",'~'.expand("<slnum>"))
8502"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8503  let ykeep      = @@
8504
8505  " save the cursor position before refresh.
8506  let screenposn = winsaveview()
8507"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8508
8509"  call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8510"  call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
8511  sil! NetrwKeepj %d _
8512  if a:islocal
8513   NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
8514  else
8515   NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
8516  endif
8517
8518  " restore position
8519"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8520  NetrwKeepj call winrestview(screenposn)
8521
8522  " restore file marks
8523  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8524"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8525   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8526  else
8527"   call Decho("2match none  (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8528   2match none
8529  endif
8530
8531"  restore
8532  let @@= ykeep
8533"  call Dret("s:NetrwRefresh")
8534endfun
8535
8536" ---------------------------------------------------------------------
8537" s:NetrwRefreshDir: refreshes a directory by name {{{2
8538"                    Called by NetrwMarkFileCopy()
8539"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
8540fun! s:NetrwRefreshDir(islocal,dirname)
8541"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) g:netrw_fastbrowse=".g:netrw_fastbrowse)
8542  if g:netrw_fastbrowse == 0
8543   " slowest mode (keep buffers refreshed, local or remote)
8544"   call Decho("slowest mode: keep buffers refreshed, local or remote",'~'.expand("<slnum>"))
8545   let tgtwin= bufwinnr(a:dirname)
8546"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin,'~'.expand("<slnum>"))
8547
8548   if tgtwin > 0
8549    " tgtwin is being displayed, so refresh it
8550    let curwin= winnr()
8551"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")",'~'.expand("<slnum>"))
8552    exe tgtwin."wincmd w"
8553    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8554    exe curwin."wincmd w"
8555
8556   elseif bufnr(a:dirname) > 0
8557    let bn= bufnr(a:dirname)
8558"    call Decho("bd bufnr(".a:dirname.")=".bn,'~'.expand("<slnum>"))
8559    exe "sil keepj bd ".bn
8560   endif
8561
8562  elseif g:netrw_fastbrowse <= 1
8563"   call Decho("medium-speed mode: refresh local buffers only",'~'.expand("<slnum>"))
8564   NetrwKeepj call s:LocalBrowseRefresh()
8565  endif
8566"  call Dret("s:NetrwRefreshDir")
8567endfun
8568
8569" ---------------------------------------------------------------------
8570" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8571" window number to do its editing in.
8572" Supports   [count]C  where the count, if present, is used to specify
8573" a window to use for editing via the <cr> mapping.
8574fun! s:NetrwSetChgwin(...)
8575"  call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
8576  if a:0 > 0
8577"   call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8578   if a:1 == ""    " :NetrwC win#
8579    let g:netrw_chgwin= winnr()
8580   else              " :NetrwC
8581    let g:netrw_chgwin= a:1
8582   endif
8583  elseif v:count > 0 " [count]C
8584   let g:netrw_chgwin= v:count
8585  else               " C
8586   let g:netrw_chgwin= winnr()
8587  endif
8588  echo "editing window now set to window#".g:netrw_chgwin
8589"  call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
8590endfun
8591
8592" ---------------------------------------------------------------------
8593" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8594"          What this function does is to compute a priority for the patterns
8595"          in the g:netrw_sort_sequence.  It applies a substitute to any
8596"          "files" that satisfy each pattern, putting the priority / in
8597"          front.  An "*" pattern handles the default priority.
8598fun! s:NetrwSetSort()
8599"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
8600  let ykeep= @@
8601  if w:netrw_liststyle == s:LONGLIST
8602   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
8603  else
8604   let seqlist  = g:netrw_sort_sequence
8605  endif
8606  " sanity check -- insure that * appears somewhere
8607  if seqlist == ""
8608   let seqlist= '*'
8609  elseif seqlist !~ '\*'
8610   let seqlist= seqlist.',*'
8611  endif
8612  let priority = 1
8613  while seqlist != ""
8614   if seqlist =~ ','
8615    let seq     = substitute(seqlist,',.*$','','e')
8616    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
8617   else
8618    let seq     = seqlist
8619    let seqlist = ""
8620   endif
8621   if priority < 10
8622    let spriority= "00".priority.g:netrw_sepchr
8623   elseif priority < 100
8624    let spriority= "0".priority.g:netrw_sepchr
8625   else
8626    let spriority= priority.g:netrw_sepchr
8627   endif
8628"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
8629
8630   " sanity check
8631   if w:netrw_bannercnt > line("$")
8632    " apparently no files were left after a Hiding pattern was used
8633"    call Dret("SetSort : no files left after hiding")
8634    return
8635   endif
8636   if seq == '*'
8637    let starpriority= spriority
8638   else
8639    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
8640    call histdel("/",-1)
8641    " sometimes multiple sorting patterns will match the same file or directory.
8642    " The following substitute is intended to remove the excess matches.
8643    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
8644    NetrwKeepj call histdel("/",-1)
8645   endif
8646   let priority = priority + 1
8647  endwhile
8648  if exists("starpriority")
8649   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
8650   NetrwKeepj call histdel("/",-1)
8651  endif
8652
8653  " Following line associated with priority -- items that satisfy a priority
8654  " pattern get prefixed by ###/ which permits easy sorting by priority.
8655  " Sometimes files can satisfy multiple priority patterns -- only the latest
8656  " priority pattern needs to be retained.  So, at this point, these excess
8657  " priority prefixes need to be removed, but not directories that happen to
8658  " be just digits themselves.
8659  exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
8660  NetrwKeepj call histdel("/",-1)
8661  let @@= ykeep
8662
8663"  call Dret("SetSort")
8664endfun
8665
8666" ---------------------------------------------------------------------
8667" s:NetrwSetTgt: sets the target to the specified choice index {{{2
8668"    Implements [count]Tb  (bookhist<b>)
8669"               [count]Th  (bookhist<h>)
8670"               See :help netrw-qb for how to make the choice.
8671fun! s:NetrwSetTgt(islocal,bookhist,choice)
8672"  call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
8673
8674  if     a:bookhist == 'b'
8675   " supports choosing a bookmark as a target using a qb-generated list
8676   let choice= a:choice - 1
8677   if exists("g:netrw_bookmarklist[".choice."]")
8678    call netrw#MakeTgt(g:netrw_bookmarklist[choice])
8679   else
8680    echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
8681   endif
8682
8683  elseif a:bookhist == 'h'
8684   " supports choosing a history stack entry as a target using a qb-generated list
8685   let choice= (a:choice % g:netrw_dirhistmax) + 1
8686   if exists("g:netrw_dirhist_".choice)
8687    let histentry = g:netrw_dirhist_{choice}
8688    call netrw#MakeTgt(histentry)
8689   else
8690    echomsg "Sorry, history#".a:choice." not available!"
8691   endif
8692  endif
8693
8694  " refresh the display
8695  if !exists("b:netrw_curdir")
8696   let b:netrw_curdir= getcwd()
8697  endif
8698  call s:NetrwRefresh(a:islocal,b:netrw_curdir)
8699
8700"  call Dret("s:NetrwSetTgt")
8701endfun
8702
8703" =====================================================================
8704" s:NetrwSortStyle: change sorting style (name - time - size) and refresh display {{{2
8705fun! s:NetrwSortStyle(islocal)
8706"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
8707  NetrwKeepj call s:NetrwSaveWordPosn()
8708  let svpos= winsaveview()
8709"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8710
8711  let g:netrw_sort_by= (g:netrw_sort_by =~ '^n')? 'time' : (g:netrw_sort_by =~ '^t')? 'size' : (g:netrw_sort_by =~ '^siz')? 'exten' : 'name'
8712  NetrwKeepj norm! 0
8713  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8714"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8715  NetrwKeepj call winrestview(svpos)
8716
8717"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
8718endfun
8719
8720" ---------------------------------------------------------------------
8721" s:NetrwSplit: mode {{{2
8722"           =0 : net   and o
8723"           =1 : net   and t
8724"           =2 : net   and v
8725"           =3 : local and o
8726"           =4 : local and t
8727"           =5 : local and v
8728fun! s:NetrwSplit(mode)
8729"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
8730
8731  let ykeep= @@
8732  call s:SaveWinVars()
8733
8734  if a:mode == 0
8735   " remote and o
8736   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8737   if winsz == 0|let winsz= ""|endif
8738"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8739   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8740   let s:didsplit= 1
8741   NetrwKeepj call s:RestoreWinVars()
8742   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
8743   unlet s:didsplit
8744
8745  elseif a:mode == 1
8746   " remote and t
8747   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
8748"   call Decho("tabnew",'~'.expand("<slnum>"))
8749   tabnew
8750   let s:didsplit= 1
8751   NetrwKeepj call s:RestoreWinVars()
8752   NetrwKeepj call s:NetrwBrowse(0,newdir)
8753   unlet s:didsplit
8754
8755  elseif a:mode == 2
8756   " remote and v
8757   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8758   if winsz == 0|let winsz= ""|endif
8759"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
8760   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8761   let s:didsplit= 1
8762   NetrwKeepj call s:RestoreWinVars()
8763   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
8764   unlet s:didsplit
8765
8766  elseif a:mode == 3
8767   " local and o
8768   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8769   if winsz == 0|let winsz= ""|endif
8770"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8771   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8772   let s:didsplit= 1
8773   NetrwKeepj call s:RestoreWinVars()
8774   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8775   unlet s:didsplit
8776
8777  elseif a:mode == 4
8778   " local and t
8779   let cursorword  = s:NetrwGetWord()
8780   let eikeep      = &ei
8781   let netrw_winnr = winnr()
8782   let netrw_line  = line(".")
8783   let netrw_col   = virtcol(".")
8784   NetrwKeepj norm! H0
8785   let netrw_hline = line(".")
8786   setl ei=all
8787   exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8788   exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8789   let &ei          = eikeep
8790   let netrw_curdir = s:NetrwTreeDir(0)
8791"   call Decho("tabnew",'~'.expand("<slnum>"))
8792   tabnew
8793   let b:netrw_curdir = netrw_curdir
8794   let s:didsplit     = 1
8795   NetrwKeepj call s:RestoreWinVars()
8796   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
8797   if &ft == "netrw"
8798    setl ei=all
8799    exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8800    exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8801    let &ei= eikeep
8802   endif
8803   unlet s:didsplit
8804
8805  elseif a:mode == 5
8806   " local and v
8807   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8808   if winsz == 0|let winsz= ""|endif
8809"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
8810   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8811   let s:didsplit= 1
8812   NetrwKeepj call s:RestoreWinVars()
8813   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8814   "call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8815   unlet s:didsplit
8816
8817  else
8818   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
8819  endif
8820
8821  let @@= ykeep
8822"  call Dret("s:NetrwSplit")
8823endfun
8824
8825" ---------------------------------------------------------------------
8826" s:NetrwTgtMenu: {{{2
8827fun! s:NetrwTgtMenu()
8828  if !exists("s:netrw_menucnt")
8829   return
8830  endif
8831"  call Dfunc("s:NetrwTgtMenu()")
8832
8833  " the following test assures that gvim is running, has menus available, and has menus enabled.
8834  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8835   if exists("g:NetrwTopLvlMenu")
8836"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
8837    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
8838   endif
8839   if !exists("s:netrw_initbookhist")
8840    call s:NetrwBookHistRead()
8841   endif
8842
8843   " try to cull duplicate entries
8844   let tgtdict={}
8845
8846   " target bookmarked places
8847   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
8848"    call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
8849    let cnt= 1
8850    for bmd in g:netrw_bookmarklist
8851     if has_key(tgtdict,bmd)
8852      let cnt= cnt + 1
8853      continue
8854     endif
8855     let tgtdict[bmd]= cnt
8856     let ebmd= escape(bmd,g:netrw_menu_escape)
8857     " show bookmarks for goto menu
8858"     call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
8859     exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd."	:call netrw#MakeTgt('".bmd."')\<cr>"
8860     let cnt= cnt + 1
8861    endfor
8862   endif
8863
8864   " target directory browsing history
8865   if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
8866"    call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
8867    let histcnt = 1
8868    while histcnt <= g:netrw_dirhistmax
8869     let priority = g:netrw_dirhist_cnt + histcnt
8870     if exists("g:netrw_dirhist_{histcnt}")
8871      let histentry  = g:netrw_dirhist_{histcnt}
8872      if has_key(tgtdict,histentry)
8873       let histcnt = histcnt + 1
8874       continue
8875      endif
8876      let tgtdict[histentry] = histcnt
8877      let ehistentry         = escape(histentry,g:netrw_menu_escape)
8878"      call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
8879      exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry."	:call netrw#MakeTgt('".histentry."')\<cr>"
8880     endif
8881     let histcnt = histcnt + 1
8882    endwhile
8883   endif
8884  endif
8885"  call Dret("s:NetrwTgtMenu")
8886endfun
8887
8888" ---------------------------------------------------------------------
8889" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
8890" (full path directory with trailing slash returned)
8891fun! s:NetrwTreeDir(islocal)
8892"  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)
8893"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'))
8894"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'))
8895"  call Decho("w:netrw_treetop  =".(exists("w:netrw_treetop")?   w:netrw_treetop   : 'n/a'))
8896
8897  if exists("s:treedir")
8898   " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
8899   let treedir= s:treedir
8900   unlet s:treedir
8901"   call Dret("s:NetrwTreeDir ".treedir)
8902   return treedir
8903  endif
8904
8905  if !exists("b:netrw_curdir") || b:netrw_curdir == ""
8906   let b:netrw_curdir= getcwd()
8907  endif
8908  let treedir = b:netrw_curdir
8909"  call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>"))
8910
8911  let s:treecurpos= winsaveview()
8912"  call Decho("saving posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
8913
8914  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8915"   call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>"))
8916"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
8917
8918   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
8919   let curline= substitute(getline('.'),"\t -->.*$",'','')
8920   if curline =~ '/$'
8921"    call Decho("extract tree subdirectory from current line",'~'.expand("<slnum>"))
8922    let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
8923"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8924   elseif curline =~ '@$'
8925"    call Decho("handle symbolic link from current line",'~'.expand("<slnum>"))
8926    let treedir= resolve(substitute(substitute(getline('.'),'@.*$','','e'),'^|*\s*','','e'))
8927"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8928   else
8929"    call Decho("do not extract tree subdirectory from current line and set treedir to empty",'~'.expand("<slnum>"))
8930    let treedir= ""
8931   endif
8932
8933   " detect user attempting to close treeroot
8934"   call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>"))
8935"   call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
8936"   call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~ '^'.s:treedepthstring)? '=~' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>"))
8937   if curline !~ '^'.s:treedepthstring && getline('.') != '..'
8938"    call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>"))
8939    " now force a refresh
8940"    call Decho(".force refresh: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8941    sil! NetrwKeepj %d _
8942"    call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
8943    return b:netrw_curdir
8944"   else " Decho
8945"    call Decho(".user not attempting to close treeroot",'~'.expand("<slnum>"))
8946   endif
8947
8948"   call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>"))
8949   let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
8950"   call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(potentialdir),'~'.expand("<slnum>"))
8951
8952   " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
8953"   if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
8954"    let newdir          = w:netrw_treetop.'/'.potentialdir
8955" "   call Decho("apply NetrwTreePath to newdir<".newdir.">",'~'.expand("<slnum>"))
8956"    let treedir         = s:NetrwTreePath(newdir)
8957"    let w:netrw_treetop = newdir
8958" "   call Decho("newdir <".newdir.">",'~'.expand("<slnum>"))
8959"   else
8960"    call Decho("apply NetrwTreePath to treetop<".w:netrw_treetop.">",'~'.expand("<slnum>"))
8961    let treedir = s:NetrwTreePath(w:netrw_treetop)
8962"   endif
8963  endif
8964
8965  " sanity maintenance: keep those //s away...
8966  let treedir= substitute(treedir,'//$','/','')
8967"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8968
8969"  call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
8970  return treedir
8971endfun
8972
8973" ---------------------------------------------------------------------
8974" s:NetrwTreeDisplay: recursive tree display {{{2
8975fun! s:NetrwTreeDisplay(dir,depth)
8976"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
8977
8978  " insure that there are no folds
8979  setl nofen
8980
8981  " install ../ and shortdir
8982  if a:depth == ""
8983   call setline(line("$")+1,'../')
8984"   call Decho("setline#".line("$")." ../ (depth is zero)",'~'.expand("<slnum>"))
8985  endif
8986  if a:dir =~ '^\a\{3,}://'
8987   if a:dir == w:netrw_treetop
8988    let shortdir= a:dir
8989   else
8990    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
8991   endif
8992   call setline(line("$")+1,a:depth.shortdir)
8993  else
8994   let shortdir= substitute(a:dir,'^.*/','','e')
8995   call setline(line("$")+1,a:depth.shortdir.'/')
8996  endif
8997"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">",'~'.expand("<slnum>"))
8998
8999  " append a / to dir if its missing one
9000  let dir= a:dir
9001
9002  " display subtrees (if any)
9003  let depth= s:treedepthstring.a:depth
9004"  call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>"))
9005
9006"  call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>"))
9007  for entry in w:netrw_treedict[dir]
9008   if dir =~ '/$'
9009    let direntry= substitute(dir.entry,'[@/]$','','e')
9010   else
9011    let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
9012   endif
9013"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9014   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9015"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9016    NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
9017   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9018"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9019    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9020   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9021"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9022    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9023   else
9024"    call Decho("<".entry."> is not a key in treedict (no subtree)",'~'.expand("<slnum>"))
9025    sil! NetrwKeepj call setline(line("$")+1,depth.entry)
9026   endif
9027  endfor
9028
9029"  call Dret("NetrwTreeDisplay")
9030endfun
9031
9032" ---------------------------------------------------------------------
9033" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
9034fun! s:NetrwRefreshTreeDict(dir)
9035"  call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)")
9036  for entry in w:netrw_treedict[a:dir]
9037   let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
9038"   call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9039
9040   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9041"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9042    NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
9043    let liststar                   = s:NetrwGlob(direntry,'*')
9044    let listdotstar                = s:NetrwGlob(direntry,'.*')
9045    let w:netrw_treedict[direntry] = liststar + listdotstar
9046"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9047
9048   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9049"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9050    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9051    let liststar   = s:NetrwGlob(direntry.'/','*')
9052    let listdotstar= s:NetrwGlob(direntry.'/','.*')
9053    let w:netrw_treedict[direntry]= liststar + listdotstar
9054"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9055
9056   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9057"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9058    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9059    let liststar   = s:NetrwGlob(direntry.'/','*')
9060    let listdotstar= s:NetrwGlob(direntry.'/','.*')
9061"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9062
9063   else
9064"    call Decho('not updating w:netrw_treedict['.direntry.'] with entry<'.entry.'> (no subtree)',,'~'.expand("<slnum>"))
9065   endif
9066  endfor
9067"  call Dret("s:NetrwRefreshTreeDict")
9068endfun
9069
9070" ---------------------------------------------------------------------
9071" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
9072"                     Called by s:PerformListing()
9073fun! s:NetrwTreeListing(dirname)
9074  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9075"   call Dfunc("NetrwTreeListing() bufname<".expand("%").">")
9076"   call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
9077"   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>"))
9078"   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>"))
9079
9080   " update the treetop
9081"   call Decho("update the treetop",'~'.expand("<slnum>"))
9082   if !exists("w:netrw_treetop")
9083    let w:netrw_treetop= a:dirname
9084"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>"))
9085   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
9086    let w:netrw_treetop= a:dirname
9087"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
9088   endif
9089
9090   if !exists("w:netrw_treedict")
9091    " insure that we have a treedict, albeit empty
9092"    call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
9093    let w:netrw_treedict= {}
9094   endif
9095
9096   " update the dictionary for the current directory
9097"   call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>"))
9098"   call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9099   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
9100   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
9101"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
9102   exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9103
9104   " if past banner, record word
9105   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
9106    let fname= expand("<cword>")
9107   else
9108    let fname= ""
9109   endif
9110"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9111"   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>"))
9112
9113   " display from treetop on down
9114   NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
9115"   call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
9116
9117   " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
9118   while getline(1) =~ '^\s*$' && byte2line(1) > 0
9119"    call Decho("deleting blank line",'~'.expand("<slnum>"))
9120    1d
9121   endwhile
9122
9123   exe "setl ".g:netrw_bufsettings
9124
9125"   call Dret("NetrwTreeListing : bufname<".expand("%").">")
9126   return
9127  endif
9128endfun
9129
9130" ---------------------------------------------------------------------
9131" s:NetrwTreePath: returns path to current file in tree listing {{{2
9132"                  Normally, treetop is w:netrw_treetop, but a
9133"                  user of the function ( netrw#SetTreetop() )
9134"                  wipes that out prior to calling this function
9135fun! s:NetrwTreePath(treetop)
9136"  call Dfunc("s:NetrwTreePath() line#".line(".")."<".getline(".").">")
9137  let svpos = winsaveview()
9138"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9139  let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
9140"  call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
9141  let depth = substitute(depth,'^'.s:treedepthstring,'','')
9142"  call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
9143  let curline= getline('.')
9144"  call Decho("curline<".curline.'>','~'.expand("<slnum>"))
9145  if curline =~ '/$'
9146"   call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9147   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9148"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9149  elseif curline =~ '@\s\+-->'
9150"   call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9151   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9152   let treedir= substitute(treedir,'@\s\+-->.*$','','e')
9153"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9154  else
9155"   call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9156   let treedir= ""
9157  endif
9158  " construct treedir by searching backwards at correct depth
9159"  call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9160"  call Decho("initial      treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
9161  while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
9162   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9163   let treedir= dirname.treedir
9164   let depth  = substitute(depth,'^'.s:treedepthstring,'','')
9165"   call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
9166  endwhile
9167  if a:treetop =~ '/$'
9168   let treedir= a:treetop.treedir
9169  else
9170   let treedir= a:treetop.'/'.treedir
9171  endif
9172  let treedir= substitute(treedir,'//$','/','')
9173"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
9174  call winrestview(svpos)
9175"  call Dret("s:NetrwTreePath <".treedir.">")
9176  return treedir
9177endfun
9178
9179" ---------------------------------------------------------------------
9180" s:NetrwWideListing: {{{2
9181fun! s:NetrwWideListing()
9182
9183  if w:netrw_liststyle == s:WIDELIST
9184"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9185   " look for longest filename (cpf=characters per filename)
9186   " cpf: characters per filename
9187   " fpl: filenames per line
9188   " fpc: filenames per column
9189   setl ma noro
9190"   call Decho("setl ma noro",'~'.expand("<slnum>"))
9191   let b:netrw_cpf= 0
9192   if line("$") >= w:netrw_bannercnt
9193    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
9194    NetrwKeepj call histdel("/",-1)
9195   else
9196"    call Dret("NetrwWideListing")
9197    return
9198   endif
9199   let b:netrw_cpf= b:netrw_cpf + 2
9200"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
9201
9202   " determine qty files per line (fpl)
9203   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9204   if w:netrw_fpl <= 0
9205    let w:netrw_fpl= 1
9206   endif
9207"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
9208
9209   " make wide display
9210   "   fpc: files per column of wide listing
9211   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9212   NetrwKeepj call histdel("/",-1)
9213   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9214   let newcolstart = w:netrw_bannercnt + fpc
9215   let newcolend   = newcolstart + fpc - 1
9216"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9217   if has("clipboard")
9218    sil! let keepregstar = @*
9219    sil! let keepregplus = @+
9220   endif
9221   while line("$") >= newcolstart
9222    if newcolend > line("$") | let newcolend= line("$") | endif
9223    let newcolqty= newcolend - newcolstart
9224    exe newcolstart
9225    if newcolqty == 0
9226     exe "sil! NetrwKeepj norm! 0\<c-v>$hx".w:netrw_bannercnt."G$p"
9227    else
9228     exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$hx'.w:netrw_bannercnt.'G$p'
9229    endif
9230    exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
9231    exe 'sil! NetrwKeepj '.w:netrw_bannercnt
9232   endwhile
9233   if has("clipboard")
9234    sil! let @*= keepregstar
9235    sil! let @+= keepregplus
9236   endif
9237   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9238   NetrwKeepj call histdel("/",-1)
9239   exe 'nno <buffer> <silent> w	:call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9240   exe 'nno <buffer> <silent> b	:call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9241"   call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9242   exe "setl ".g:netrw_bufsettings
9243"   call Decho("(NetrwWideListing) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9244"   call Dret("NetrwWideListing")
9245   return
9246  else
9247   if hasmapto("w","n")
9248    sil! nunmap <buffer> w
9249   endif
9250   if hasmapto("b","n")
9251    sil! nunmap <buffer> b
9252   endif
9253  endif
9254
9255endfun
9256
9257" ---------------------------------------------------------------------
9258" s:PerformListing: {{{2
9259fun! s:PerformListing(islocal)
9260"  call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9261"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9262"  call Decho("settings: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (enter)",'~'.expand("<slnum>"))
9263
9264  " set up syntax highlighting {{{3
9265"  call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
9266  sil! setl ft=netrw
9267
9268  NetrwKeepj call s:NetrwSafeOptions()
9269  setl noro ma
9270"  call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
9271
9272"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
9273"   call Decho("(netrw) Processing your browsing request...",'~'.expand("<slnum>"))
9274"  endif								" Decho
9275
9276"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9277  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
9278   " force a refresh for tree listings
9279"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9280   sil! NetrwKeepj %d _
9281  endif
9282
9283  " save current directory on directory history list
9284  NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
9285
9286  " Set up the banner {{{3
9287  if g:netrw_banner
9288"   call Decho("--set up banner",'~'.expand("<slnum>"))
9289   NetrwKeepj call setline(1,'" ============================================================================')
9290   if exists("g:netrw_pchk")
9291    " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9292    " failure detections.
9293    NetrwKeepj call setline(2,'" Netrw Directory Listing')
9294   else
9295    NetrwKeepj call setline(2,'" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')')
9296   endif
9297   if exists("g:netrw_pchk")
9298    let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9299   else
9300    let curdir= b:netrw_curdir
9301   endif
9302   if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9303    NetrwKeepj call setline(3,'"   '.substitute(curdir,'/','\\','g'))
9304   else
9305    NetrwKeepj call setline(3,'"   '.curdir)
9306   endif
9307   let w:netrw_bannercnt= 3
9308   NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
9309  else
9310"   call Decho("--no banner",'~'.expand("<slnum>"))
9311   NetrwKeepj 1
9312   let w:netrw_bannercnt= 1
9313  endif
9314"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9315"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9316
9317  let sortby= g:netrw_sort_by
9318  if g:netrw_sort_direction =~ "^r"
9319   let sortby= sortby." reversed"
9320  endif
9321
9322  " Sorted by... {{{3
9323  if g:netrw_banner
9324"   call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9325   if g:netrw_sort_by =~ "^n"
9326"   call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9327    " sorted by name
9328    NetrwKeepj put ='\"   Sorted by      '.sortby
9329    NetrwKeepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
9330    let w:netrw_bannercnt= w:netrw_bannercnt + 2
9331   else
9332"   call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9333    " sorted by size or date
9334    NetrwKeepj put ='\"   Sorted by '.sortby
9335    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9336   endif
9337   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9338"  else " Decho
9339"   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>"))
9340  endif
9341
9342  " show copy/move target, if any
9343  if g:netrw_banner
9344   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9345"    call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9346    NetrwKeepj put =''
9347    if s:netrwmftgt_islocal
9348     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9349    else
9350     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9351    endif
9352    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9353   else
9354"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
9355   endif
9356   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9357  endif
9358
9359  " Hiding...  -or-  Showing... {{{3
9360  if g:netrw_banner
9361"   call Decho("--handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9362   if g:netrw_list_hide != "" && g:netrw_hide
9363    if g:netrw_hide == 1
9364     NetrwKeepj put ='\"   Hiding:        '.g:netrw_list_hide
9365    else
9366     NetrwKeepj put ='\"   Showing:       '.g:netrw_list_hide
9367    endif
9368    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9369   endif
9370   exe "NetrwKeepj ".w:netrw_bannercnt
9371
9372"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9373   let quickhelp   = g:netrw_quickhelp%len(s:QuickHelp)
9374"   call Decho("quickhelp   =".quickhelp,'~'.expand("<slnum>"))
9375   NetrwKeepj put ='\"   Quick Help: <F1>:help  '.s:QuickHelp[quickhelp]
9376"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9377   NetrwKeepj put ='\" =============================================================================='
9378   let w:netrw_bannercnt= w:netrw_bannercnt + 2
9379"  else " Decho
9380"   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>"))
9381  endif
9382
9383  " bannercnt should index the line just after the banner
9384  if g:netrw_banner
9385   let w:netrw_bannercnt= w:netrw_bannercnt + 1
9386   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9387"   call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9388"  else " Decho
9389"   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>"))
9390  endif
9391
9392  " get list of files
9393"  call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
9394  if a:islocal
9395   NetrwKeepj call s:LocalListing()
9396  else " remote
9397   NetrwKeepj let badresult= s:NetrwRemoteListing()
9398   if badresult
9399"    call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9400"    call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9401    return
9402   endif
9403  endif
9404
9405  " manipulate the directory listing (hide, sort) {{{3
9406  if !exists("w:netrw_bannercnt")
9407   let w:netrw_bannercnt= 0
9408  endif
9409"  call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9410"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9411"  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>"))
9412
9413  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9414"   call Decho("manipulate directory listing (hide)",'~'.expand("<slnum>"))
9415"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9416   if g:netrw_hide && g:netrw_list_hide != ""
9417    NetrwKeepj call s:NetrwListHide()
9418   endif
9419   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9420"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9421
9422    if g:netrw_sort_by =~ "^n"
9423     " sort by name
9424     NetrwKeepj call s:NetrwSetSort()
9425
9426     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9427"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9428      if g:netrw_sort_direction =~ 'n'
9429       " normal direction sorting
9430       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9431      else
9432       " reverse direction sorting
9433       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9434      endif
9435     endif
9436     " remove priority pattern prefix
9437"     call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9438     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9439     NetrwKeepj call histdel("/",-1)
9440
9441    elseif g:netrw_sort_by =~ "^ext"
9442     " sort by extension
9443     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9444     NetrwKeepj call histdel("/",-1)
9445     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9446     NetrwKeepj call histdel("/",-1)
9447     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9448     NetrwKeepj call histdel("/",-1)
9449     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9450"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9451      if g:netrw_sort_direction =~ 'n'
9452       " normal direction sorting
9453       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9454      else
9455       " reverse direction sorting
9456       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9457      endif
9458     endif
9459     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9460     NetrwKeepj call histdel("/",-1)
9461
9462    elseif a:islocal
9463     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9464"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9465      if g:netrw_sort_direction =~ 'n'
9466"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9467       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9468      else
9469"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9470       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9471      endif
9472     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9473     NetrwKeepj call histdel("/",-1)
9474     endif
9475    endif
9476
9477   elseif g:netrw_sort_direction =~ 'r'
9478"    call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9479    if !g:netrw_banner || w:netrw_bannercnt < line('$')
9480     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9481     call histdel("/",-1)
9482    endif
9483   endif
9484  endif
9485"  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>"))
9486
9487  " convert to wide/tree listing {{{3
9488"  call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9489"  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>"))
9490  NetrwKeepj call s:NetrwWideListing()
9491"  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>"))
9492  NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
9493"  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>"))
9494
9495  " resolve symbolic links if local and (thin or tree)
9496  if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
9497"   call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9498   g/@$/call s:ShowLink()
9499  endif
9500
9501  if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
9502   " place cursor on the top-left corner of the file listing
9503"   call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9504   exe 'sil! '.w:netrw_bannercnt
9505   sil! NetrwKeepj norm! 0
9506"   call Decho("  tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9507  else
9508"   call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9509"   call Decho("  w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9510"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
9511"   call Decho("  g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
9512  endif
9513
9514  " record previous current directory
9515  let w:netrw_prvdir= b:netrw_curdir
9516"  call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
9517
9518  " save certain window-oriented variables into buffer-oriented variables {{{3
9519"  call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9520"  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>"))
9521  NetrwKeepj call s:SetBufWinVars()
9522"  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>"))
9523  NetrwKeepj call s:NetrwOptionRestore("w:")
9524"  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>"))
9525
9526  " set display to netrw display settings
9527"  call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
9528  exe "setl ".g:netrw_bufsettings
9529"  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>"))
9530  if g:netrw_liststyle == s:LONGLIST
9531"   call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9532   exe "setl ts=".(g:netrw_maxfilenamelen+1)
9533  endif
9534
9535  if exists("s:treecurpos")
9536"   call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
9537"   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>"))
9538"   call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9539   NetrwKeepj call winrestview(s:treecurpos)
9540   unlet s:treecurpos
9541  endif
9542
9543"  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>"))
9544"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9545"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
9546endfun
9547
9548" ---------------------------------------------------------------------
9549" s:SetupNetrwStatusLine: {{{2
9550fun! s:SetupNetrwStatusLine(statline)
9551"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
9552
9553  if !exists("s:netrw_setup_statline")
9554   let s:netrw_setup_statline= 1
9555"   call Decho("do first-time status line setup",'~'.expand("<slnum>"))
9556
9557   if !exists("s:netrw_users_stl")
9558    let s:netrw_users_stl= &stl
9559   endif
9560   if !exists("s:netrw_users_ls")
9561    let s:netrw_users_ls= &laststatus
9562   endif
9563
9564   " set up User9 highlighting as needed
9565   let keepa= @a
9566   redir @a
9567   try
9568    hi User9
9569   catch /^Vim\%((\a\{3,})\)\=:E411/
9570    if &bg == "dark"
9571     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
9572    else
9573     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
9574    endif
9575   endtry
9576   redir END
9577   let @a= keepa
9578  endif
9579
9580  " set up status line (may use User9 highlighting)
9581  " insure that windows have a statusline
9582  " make sure statusline is displayed
9583  let &stl=a:statline
9584  setl laststatus=2
9585"  call Decho("stl=".&stl,'~'.expand("<slnum>"))
9586  redraw
9587
9588"  call Dret("SetupNetrwStatusLine : stl=".&stl)
9589endfun
9590
9591" ---------------------------------------------------------------------
9592"  Remote Directory Browsing Support:    {{{1
9593" ===========================================
9594
9595" ---------------------------------------------------------------------
9596" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
9597"  This function assumes that a long listing will be received.  Size, time,
9598"  and reverse sorts will be requested of the server but not otherwise
9599"  enforced here.
9600fun! s:NetrwRemoteFtpCmd(path,listcmd)
9601"  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 : "???")))
9602"  call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9603  " sanity check: {{{3
9604  if !exists("w:netrw_method")
9605   if exists("b:netrw_method")
9606    let w:netrw_method= b:netrw_method
9607   else
9608    call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
9609"    call Dret("NetrwRemoteFtpCmd")
9610    return
9611   endif
9612  endif
9613
9614  " WinXX ftp uses unix style input, so set ff to unix	" {{{3
9615  let ffkeep= &ff
9616  setl ma ff=unix noro
9617"  call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
9618
9619  " clear off any older non-banner lines	" {{{3
9620  " note that w:netrw_bannercnt indexes the line after the banner
9621"  call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _  (clear off old non-banner lines)",'~'.expand("<slnum>"))
9622  exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9623
9624  ".........................................
9625  if w:netrw_method == 2 || w:netrw_method == 5	" {{{3
9626   " ftp + <.netrc>:  Method #2
9627   if a:path != ""
9628    NetrwKeepj put ='cd \"'.a:path.'\"'
9629   endif
9630   if exists("g:netrw_ftpextracmd")
9631    NetrwKeepj put =g:netrw_ftpextracmd
9632"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9633   endif
9634   NetrwKeepj call setline(line("$")+1,a:listcmd)
9635"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9636   if exists("g:netrw_port") && g:netrw_port != ""
9637"    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>"))
9638    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)
9639   else
9640"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
9641    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
9642   endif
9643
9644  ".........................................
9645  elseif w:netrw_method == 3	" {{{3
9646   " ftp + machine,id,passwd,filename:  Method #3
9647    setl ff=unix
9648    if exists("g:netrw_port") && g:netrw_port != ""
9649     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
9650    else
9651     NetrwKeepj put ='open '.g:netrw_machine
9652    endif
9653
9654    " handle userid and password
9655    let host= substitute(g:netrw_machine,'\..*$','','')
9656"    call Decho("host<".host.">",'~'.expand("<slnum>"))
9657    if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
9658     call NetUserPass("ftp:".host)
9659    endif
9660    if exists("g:netrw_uid") && g:netrw_uid != ""
9661     if exists("g:netrw_ftp") && g:netrw_ftp == 1
9662      NetrwKeepj put =g:netrw_uid
9663      if exists("s:netrw_passwd") && s:netrw_passwd != ""
9664       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
9665      endif
9666     elseif exists("s:netrw_passwd")
9667      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
9668     endif
9669    endif
9670
9671   if a:path != ""
9672    NetrwKeepj put ='cd \"'.a:path.'\"'
9673   endif
9674   if exists("g:netrw_ftpextracmd")
9675    NetrwKeepj put =g:netrw_ftpextracmd
9676"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9677   endif
9678   NetrwKeepj call setline(line("$")+1,a:listcmd)
9679
9680   " perform ftp:
9681   " -i       : turns off interactive prompting from ftp
9682   " -n  unix : DON'T use <.netrc>, even though it exists
9683   " -n  win32: quit being obnoxious about password
9684   if exists("w:netrw_bannercnt")
9685"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9686    call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
9687"   else " Decho
9688"    call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
9689"    g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
9690   endif
9691
9692  ".........................................
9693  elseif w:netrw_method == 9	" {{{3
9694   " sftp username@machine: Method #9
9695   " s:netrw_sftp_cmd
9696   setl ff=unix
9697
9698   " restore settings
9699   let &ff= ffkeep
9700"   call Dret("NetrwRemoteFtpCmd")
9701   return
9702
9703  ".........................................
9704  else	" {{{3
9705   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
9706  endif
9707
9708  " cleanup for Windows " {{{3
9709  if has("win32") || has("win95") || has("win64") || has("win16")
9710   sil! NetrwKeepj %s/\r$//e
9711   NetrwKeepj call histdel("/",-1)
9712  endif
9713  if a:listcmd == "dir"
9714   " infer directory/link based on the file permission string
9715   sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
9716   sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
9717   NetrwKeepj call histdel("/",-1)
9718   NetrwKeepj call histdel("/",-1)
9719   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9720    exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
9721    NetrwKeepj call histdel("/",-1)
9722   endif
9723  endif
9724
9725  " ftp's listing doesn't seem to include ./ or ../ " {{{3
9726  if !search('^\.\/$\|\s\.\/$','wn')
9727   exe 'NetrwKeepj '.w:netrw_bannercnt
9728   NetrwKeepj put ='./'
9729  endif
9730  if !search('^\.\.\/$\|\s\.\.\/$','wn')
9731   exe 'NetrwKeepj '.w:netrw_bannercnt
9732   NetrwKeepj put ='../'
9733  endif
9734
9735  " restore settings " {{{3
9736  let &ff= ffkeep
9737"  call Dret("NetrwRemoteFtpCmd")
9738endfun
9739
9740" ---------------------------------------------------------------------
9741" s:NetrwRemoteListing: {{{2
9742fun! s:NetrwRemoteListing()
9743"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
9744
9745  if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
9746   let w:netrw_bannercnt= s:bannercnt
9747  endif
9748  if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
9749   let w:netrw_bannercnt= s:bannercnt
9750  endif
9751
9752  call s:RemotePathAnalysis(b:netrw_curdir)
9753
9754  " sanity check:
9755  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
9756"   call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
9757   if !executable("ftp")
9758"    call Decho("ftp is not executable",'~'.expand("<slnum>"))
9759    if !exists("g:netrw_quiet")
9760     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
9761    endif
9762    call s:NetrwOptionRestore("w:")
9763"    call Dret("s:NetrwRemoteListing -1")
9764    return -1
9765   endif
9766
9767  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
9768"   call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
9769   if !exists("g:netrw_quiet")
9770    if g:netrw_list_cmd == ""
9771     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)
9772    else
9773     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
9774    endif
9775   endif
9776
9777   NetrwKeepj call s:NetrwOptionRestore("w:")
9778"   call Dret("s:NetrwRemoteListing -1")
9779   return -1
9780  endif  " (remote handling sanity check)
9781"  call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
9782
9783  if exists("b:netrw_method")
9784"   call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
9785   let w:netrw_method= b:netrw_method
9786  endif
9787
9788  if s:method == "ftp"
9789   " use ftp to get remote file listing {{{3
9790"   call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
9791   let s:method  = "ftp"
9792   let listcmd = g:netrw_ftp_list_cmd
9793   if g:netrw_sort_by =~ '^t'
9794    let listcmd= g:netrw_ftp_timelist_cmd
9795   elseif g:netrw_sort_by =~ '^s'
9796    let listcmd= g:netrw_ftp_sizelist_cmd
9797   endif
9798"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
9799   call s:NetrwRemoteFtpCmd(s:path,listcmd)
9800"   exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
9801
9802   " report on missing file or directory messages
9803   if search('[Nn]o such file or directory\|Failed to change directory')
9804    let mesg= getline(".")
9805    if exists("w:netrw_bannercnt")
9806     setl ma
9807     exe w:netrw_bannercnt.",$d _"
9808     setl noma
9809    endif
9810    NetrwKeepj call s:NetrwOptionRestore("w:")
9811    call netrw#ErrorMsg(s:WARNING,mesg,96)
9812"    call Dret("s:NetrwRemoteListing : -1")
9813    return -1
9814   endif
9815
9816   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9817    " shorten the listing
9818"    call Decho("generate short listing",'~'.expand("<slnum>"))
9819    exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
9820
9821    " cleanup
9822    if g:netrw_ftp_browse_reject != ""
9823     exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
9824     NetrwKeepj call histdel("/",-1)
9825    endif
9826    sil! NetrwKeepj %s/\r$//e
9827    NetrwKeepj call histdel("/",-1)
9828
9829    " if there's no ../ listed, then put ../ in
9830    let line1= line(".")
9831    exe "sil! NetrwKeepj ".w:netrw_bannercnt
9832    let line2= search('\.\.\/\%(\s\|$\)','cnW')
9833"    call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2."  w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9834    if line2 == 0
9835"     call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
9836     sil! NetrwKeepj put='../'
9837    endif
9838    exe "sil! NetrwKeepj ".line1
9839    sil! NetrwKeepj norm! 0
9840
9841"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
9842    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9843"     call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
9844     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
9845     NetrwKeepj call histdel("/",-1)
9846    else " normal ftp cleanup
9847"     call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
9848     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
9849     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
9850     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
9851     NetrwKeepj call histdel("/",-1)
9852     NetrwKeepj call histdel("/",-1)
9853     NetrwKeepj call histdel("/",-1)
9854    endif
9855   endif
9856
9857   else
9858   " use ssh to get remote file listing {{{3
9859"   call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
9860   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
9861"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
9862   if g:netrw_scp_cmd =~ '^pscp'
9863"    call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
9864    exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
9865    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
9866    sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
9867    sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
9868    sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
9869    NetrwKeepj call histdel("/",-1)
9870    NetrwKeepj call histdel("/",-1)
9871    NetrwKeepj call histdel("/",-1)
9872    if g:netrw_liststyle != s:LONGLIST
9873     sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
9874     NetrwKeepj call histdel("/",-1)
9875    endif
9876   else
9877    if s:path == ""
9878"     call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
9879     exe "NetrwKeepj keepalt r! ".listcmd
9880    else
9881"     call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
9882     exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
9883"     call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
9884    endif
9885   endif
9886
9887   " cleanup
9888   if g:netrw_ssh_browse_reject != ""
9889"    call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
9890    exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
9891    NetrwKeepj call histdel("/",-1)
9892   endif
9893  endif
9894
9895  if w:netrw_liststyle == s:LONGLIST
9896   " do a long listing; these substitutions need to be done prior to sorting {{{3
9897"   call Decho("fix long listing:",'~'.expand("<slnum>"))
9898
9899   if s:method == "ftp"
9900    " cleanup
9901    exe "sil! NetrwKeepj ".w:netrw_bannercnt
9902    while getline('.') =~ g:netrw_ftp_browse_reject
9903     sil! NetrwKeepj d
9904    endwhile
9905    " if there's no ../ listed, then put ../ in
9906    let line1= line(".")
9907    sil! NetrwKeepj 1
9908    sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
9909    let line2= line(".")
9910    if line2 == 0
9911     if b:netrw_curdir != '/'
9912      exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
9913     endif
9914    endif
9915    exe "sil! NetrwKeepj ".line1
9916    sil! NetrwKeepj norm! 0
9917   endif
9918
9919   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9920"    call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
9921    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/'
9922   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
9923"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9924    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
9925    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
9926    exe 'sil NetrwKeepj '.w:netrw_bannercnt
9927    NetrwKeepj call histdel("/",-1)
9928    NetrwKeepj call histdel("/",-1)
9929    NetrwKeepj call histdel("/",-1)
9930   endif
9931  endif
9932
9933"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
9934"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
9935"  endif " Decho
9936
9937"  call Dret("s:NetrwRemoteListing 0")
9938  return 0
9939endfun
9940
9941" ---------------------------------------------------------------------
9942" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
9943fun! s:NetrwRemoteRm(usrhost,path) range
9944"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
9945"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
9946  let svpos= winsaveview()
9947"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9948
9949  let all= 0
9950  if exists("s:netrwmarkfilelist_{bufnr('%')}")
9951   " remove all marked files
9952"   call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>"))
9953   for fname in s:netrwmarkfilelist_{bufnr("%")}
9954    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
9955    if ok =~ 'q\%[uit]'
9956     break
9957    elseif ok =~ 'a\%[ll]'
9958     let all= 1
9959    endif
9960   endfor
9961   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
9962
9963  else
9964   " remove files specified by range
9965"   call Decho("remove files specified by range",'~'.expand("<slnum>"))
9966
9967   " preparation for removing multiple files/directories
9968   let keepsol = &l:sol
9969   setl nosol
9970   let ctr    = a:firstline
9971
9972   " remove multiple files and directories
9973   while ctr <= a:lastline
9974    exe "NetrwKeepj ".ctr
9975    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
9976    if ok =~ 'q\%[uit]'
9977     break
9978    elseif ok =~ 'a\%[ll]'
9979     let all= 1
9980    endif
9981    let ctr= ctr + 1
9982   endwhile
9983   let &l:sol = keepsol
9984  endif
9985
9986  " refresh the (remote) directory listing
9987"  call Decho("refresh remote directory listing",'~'.expand("<slnum>"))
9988  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
9989"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9990  NetrwKeepj call winrestview(svpos)
9991
9992"  call Dret("s:NetrwRemoteRm")
9993endfun
9994
9995" ---------------------------------------------------------------------
9996" s:NetrwRemoteRmFile: {{{2
9997fun! s:NetrwRemoteRmFile(path,rmfile,all)
9998"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
9999
10000  let all= a:all
10001  let ok = ""
10002
10003  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
10004   " attempt to remove file
10005"    call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
10006   if !all
10007    echohl Statement
10008"    call Decho("case all=0:",'~'.expand("<slnum>"))
10009    call inputsave()
10010    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10011    call inputrestore()
10012    echohl NONE
10013    if ok == ""
10014     let ok="no"
10015    endif
10016    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10017    if ok =~ 'a\%[ll]'
10018     let all= 1
10019    endif
10020   endif
10021
10022   if all || ok =~ 'y\%[es]' || ok == ""
10023"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
10024    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10025"     call Decho("case ftp:",'~'.expand("<slnum>"))
10026     let path= a:path
10027     if path =~ '^\a\{3,}://'
10028      let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
10029     endif
10030     sil! NetrwKeepj .,$d _
10031     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
10032    else
10033"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
10034     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
10035"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10036     if !exists("b:netrw_curdir")
10037      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
10038      let ok="q"
10039     else
10040      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
10041"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10042"      call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
10043"      call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
10044      if remotedir != ""
10045       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
10046      else
10047       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
10048      endif
10049"      call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
10050      let ret= system(netrw_rm_cmd)
10051      if v:shell_error != 0
10052       if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
10053        call netrw#ErrorMsg(s:ERROR,"remove failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-c)",102)
10054       else
10055        call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10056       endif
10057      else if ret != 0
10058       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10059      endif
10060"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10061     endif
10062    endif
10063   elseif ok =~ 'q\%[uit]'
10064"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10065   endif
10066
10067  else
10068   " attempt to remove directory
10069"    call Decho("attempt to remove directory",'~'.expand("<slnum>"))
10070   if !all
10071    call inputsave()
10072    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10073    call inputrestore()
10074    if ok == ""
10075     let ok="no"
10076    endif
10077    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10078    if ok =~ 'a\%[ll]'
10079     let all= 1
10080    endif
10081   endif
10082
10083   if all || ok =~ 'y\%[es]' || ok == ""
10084    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10085     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
10086    else
10087     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
10088     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
10089"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
10090     let ret= system(netrw_rmdir_cmd)
10091"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10092
10093     if v:shell_error != 0
10094"      call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
10095      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
10096"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
10097      let ret= system(netrw_rmf_cmd)
10098"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10099
10100      if v:shell_error != 0 && !exists("g:netrw_quiet")
10101      	NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
10102      endif
10103     endif
10104    endif
10105
10106   elseif ok =~ 'q\%[uit]'
10107"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10108   endif
10109  endif
10110
10111"  call Dret("s:NetrwRemoteRmFile ".ok)
10112  return ok
10113endfun
10114
10115" ---------------------------------------------------------------------
10116" s:NetrwRemoteRename: rename a remote file or directory {{{2
10117fun! s:NetrwRemoteRename(usrhost,path) range
10118"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
10119
10120  " preparation for removing multiple files/directories
10121  let svpos      = winsaveview()
10122"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10123  let ctr        = a:firstline
10124  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10125
10126  " rename files given by the markfilelist
10127  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10128   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10129"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10130    if exists("subfrom")
10131     let newname= substitute(oldname,subfrom,subto,'')
10132"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10133    else
10134     call inputsave()
10135     let newname= input("Moving ".oldname." to : ",oldname)
10136     call inputrestore()
10137     if newname =~ '^s/'
10138      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10139      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10140      let newname = substitute(oldname,subfrom,subto,'')
10141"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10142     endif
10143    endif
10144
10145    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10146     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10147    else
10148     let oldname= s:ShellEscape(a:path.oldname)
10149     let newname= s:ShellEscape(a:path.newname)
10150"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10151     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10152    endif
10153
10154   endfor
10155   call s:NetrwUnMarkFile(1)
10156
10157  else
10158
10159  " attempt to rename files/directories
10160   let keepsol= &l:sol
10161   setl nosol
10162   while ctr <= a:lastline
10163    exe "NetrwKeepj ".ctr
10164
10165    let oldname= s:NetrwGetWord()
10166"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10167
10168    call inputsave()
10169    let newname= input("Moving ".oldname." to : ",oldname)
10170    call inputrestore()
10171
10172    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10173     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10174    else
10175     let oldname= s:ShellEscape(a:path.oldname)
10176     let newname= s:ShellEscape(a:path.newname)
10177"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10178     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10179    endif
10180
10181    let ctr= ctr + 1
10182   endwhile
10183   let &l:sol= keepsol
10184  endif
10185
10186  " refresh the directory
10187  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10188"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10189  NetrwKeepj call winrestview(svpos)
10190
10191"  call Dret("NetrwRemoteRename")
10192endfun
10193
10194" ---------------------------------------------------------------------
10195"  Local Directory Browsing Support:    {{{1
10196" ==========================================
10197
10198" ---------------------------------------------------------------------
10199" netrw#FileUrlRead: handles reading file://* files {{{2
10200"   Should accept:   file://localhost/etc/fstab
10201"                    file:///etc/fstab
10202"                    file:///c:/WINDOWS/clock.avi
10203"                    file:///c|/WINDOWS/clock.avi
10204"                    file://localhost/c:/WINDOWS/clock.avi
10205"                    file://localhost/c|/WINDOWS/clock.avi
10206"                    file://c:/foo.txt
10207"                    file:///c:/foo.txt
10208" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
10209fun! netrw#FileUrlRead(fname)
10210"  call Dfunc("netrw#FileUrlRead(fname<".a:fname.">)")
10211  let fname = a:fname
10212  if fname =~ '^file://localhost/'
10213"   call Decho('converting file://localhost/   -to-  file:///','~'.expand("<slnum>"))
10214   let fname= substitute(fname,'^file://localhost/','file:///','')
10215"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10216  endif
10217  if (has("win32") || has("win95") || has("win64") || has("win16"))
10218   if fname  =~ '^file:///\=\a[|:]/'
10219"    call Decho('converting file:///\a|/   -to-  file://\a:/','~'.expand("<slnum>"))
10220    let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10221"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10222   endif
10223  endif
10224  let fname2396 = netrw#RFC2396(fname)
10225  let fname2396e= fnameescape(fname2396)
10226  let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
10227  if (has("win32") || has("win95") || has("win64") || has("win16"))
10228"   call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10229   if plainfname =~ '^/\+\a:'
10230"    call Decho('removing leading "/"s','~'.expand("<slnum>"))
10231    let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10232   endif
10233  endif
10234"  call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10235"  call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
10236  exe "sil doau BufReadPre ".fname2396e
10237  exe 'NetrwKeepj r '.plainfname
10238  exe 'sil! bdelete '.plainfname
10239  exe 'keepalt file! '.plainfname
10240  NetrwKeepj 1d
10241"  call Decho("setl nomod",'~'.expand("<slnum>"))
10242  setl nomod
10243"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10244"  call Dret("netrw#FileUrlRead")
10245  exe "sil doau BufReadPost ".fname2396e
10246endfun
10247
10248" ---------------------------------------------------------------------
10249" netrw#LocalBrowseCheck: {{{2
10250fun! netrw#LocalBrowseCheck(dirname)
10251  " This function is called by netrwPlugin.vim's s:LocalBrowse(), s:NetrwRexplore(), and by <cr> when atop listed file/directory
10252  " unfortunate interaction -- split window debugging can't be
10253  " used here, must use D-echoRemOn or D-echoTabOn -- the BufEnter
10254  " event triggers another call to LocalBrowseCheck() when attempts
10255  " to write to the DBG buffer are made.
10256  " The &ft == "netrw" test was installed because the BufEnter event
10257  " would hit when re-entering netrw windows, creating unexpected
10258  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
10259"  call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">")
10260"  call Decho("isdir<".a:dirname.">=".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).expand("<slnum>"))
10261"  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>"))
10262"  call Dredir("ls!","ls!")
10263"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10264"  call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
10265
10266  let ykeep= @@
10267  if isdirectory(s:NetrwFile(a:dirname))
10268"   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>"))
10269
10270   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10271"    call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10272"    call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10273    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10274
10275   elseif &ft == "netrw" && line("$") == 1
10276"    call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10277    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10278
10279   elseif exists("s:treeforceredraw")
10280"    call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10281    unlet s:treeforceredraw
10282    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10283   endif
10284
10285"   call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10286"   call Dret("netrw#LocalBrowseCheck")
10287   return
10288  endif
10289
10290  " following code wipes out currently unused netrw buffers
10291  "       IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10292  "   AND IF the listing style is not a tree listing
10293  if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
10294"   call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10295   let ibuf    = 1
10296   let buflast = bufnr("$")
10297   while ibuf <= buflast
10298    if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10299     exe "sil! keepj keepalt ".ibuf."bw!"
10300    endif
10301    let ibuf= ibuf + 1
10302   endwhile
10303  endif
10304  let @@= ykeep
10305"  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>"))
10306"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10307  " not a directory, ignore it
10308"  call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
10309endfun
10310
10311" ---------------------------------------------------------------------
10312" s:LocalBrowseRefresh: this function is called after a user has {{{2
10313" performed any shell command.  The idea is to cause all local-browsing
10314" buffers to be refreshed after a user has executed some shell command,
10315" on the chance that s/he removed/created a file/directory with it.
10316fun! s:LocalBrowseRefresh()
10317"  call Dfunc("s:LocalBrowseRefresh() tabpagenr($)=".tabpagenr("$"))
10318"  call Decho("s:netrw_browselist =".(exists("s:netrw_browselist")?  string(s:netrw_browselist)  : '<n/a>'),'~'.expand("<slnum>"))
10319"  call Decho("w:netrw_bannercnt  =".(exists("w:netrw_bannercnt")?   string(w:netrw_bannercnt)   : '<n/a>'),'~'.expand("<slnum>"))
10320
10321  " determine which buffers currently reside in a tab
10322  if !exists("s:netrw_browselist")
10323"   call Dret("s:LocalBrowseRefresh : browselist is empty")
10324   return
10325  endif
10326  if !exists("w:netrw_bannercnt")
10327"   call Dret("s:LocalBrowseRefresh : don't refresh when focus not on netrw window")
10328   return
10329  endif
10330  if exists("s:netrw_events") && s:netrw_events == 1
10331   " s:LocalFastBrowser gets called (indirectly) from a
10332   let s:netrw_events= 2
10333"   call Dret("s:LocalBrowseRefresh : avoid initial double refresh")
10334   return
10335  endif
10336  let itab       = 1
10337  let buftablist = []
10338  let ykeep      = @@
10339  while itab <= tabpagenr("$")
10340   let buftablist = buftablist + tabpagebuflist()
10341   let itab       = itab + 1
10342   tabn
10343  endwhile
10344"  call Decho("buftablist".string(buftablist),'~'.expand("<slnum>"))
10345"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("<slnum>"))
10346  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10347  "   | refresh any netrw window
10348  "   | wipe out any non-displaying netrw buffer
10349  let curwin = winnr()
10350  let ibl    = 0
10351  for ibuf in s:netrw_browselist
10352"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("<slnum>"))
10353   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10354    " wipe out any non-displaying netrw buffer
10355"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("<slnum>"))
10356    exe "sil! keepj bd ".fnameescape(ibuf)
10357    call remove(s:netrw_browselist,ibl)
10358"    call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10359    continue
10360   elseif index(tabpagebuflist(),ibuf) != -1
10361    " refresh any netrw buffer
10362"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>"))
10363    exe bufwinnr(ibuf)."wincmd w"
10364    if getline(".") =~ 'Quick Help'
10365     " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10366     " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10367     let g:netrw_quickhelp= g:netrw_quickhelp - 1
10368    endif
10369"    call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>"))
10370    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10371     NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10372    endif
10373    NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10374   endif
10375   let ibl= ibl + 1
10376"   call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("<slnum>"))
10377  endfor
10378"  call Decho("restore window: exe ".curwin."wincmd w",'~'.expand("<slnum>"))
10379  exe curwin."wincmd w"
10380  let @@= ykeep
10381
10382"  call Dret("s:LocalBrowseRefresh")
10383endfun
10384
10385" ---------------------------------------------------------------------
10386" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10387"
10388"     g:netrw_    Directory Is
10389"     fastbrowse  Local  Remote
10390"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
10391"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
10392"  fast   2         H      H
10393"
10394"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10395"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
10396"                       (re-using a buffer may not be as accurate)
10397"
10398"  s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds whena med or fast browsing
10399"                   =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10400"                       BufEnter may be first event, then a FocusGained event.  Ignore the first FocusGained event.
10401"                       If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10402"                   =2: autocmds installed (doesn't ignore any FocusGained events)
10403fun! s:LocalFastBrowser()
10404"  call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
10405"  call Decho("s:netrw_events        ".(exists("s:netrw_events")? "exists"    : 'n/a'),'~'.expand("<slnum>"))
10406"  call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")?  "installed" : "not installed"),'~'.expand("<slnum>"))
10407"  call Decho("autocmd: FocusGained  ".(exists("#FocusGained")?   "installed" : "not installed"),'~'.expand("<slnum>"))
10408
10409  " initialize browselist, a list of buffer numbers that the local browser has used
10410  if !exists("s:netrw_browselist")
10411"   call Decho("initialize s:netrw_browselist",'~'.expand("<slnum>"))
10412   let s:netrw_browselist= []
10413  endif
10414
10415  " append current buffer to fastbrowse list
10416  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
10417"   call Decho("appendng current buffer to browselist",'~'.expand("<slnum>"))
10418   call add(s:netrw_browselist,bufnr("%"))
10419"   call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10420  endif
10421
10422  " enable autocmd events to handle refreshing/removing local browser buffers
10423  "    If local browse buffer is currently showing: refresh it
10424  "    If local browse buffer is currently hidden : wipe it
10425  "    g:netrw_fastbrowse=0 : slow   speed, never re-use directory listing
10426  "                      =1 : medium speed, re-use directory listing for remote only
10427  "                      =2 : fast   speed, always re-use directory listing when possible
10428  if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
10429   let s:netrw_events= 1
10430   augroup AuNetrwEvent
10431    au!
10432    if (has("win32") || has("win95") || has("win64") || has("win16"))
10433"     call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
10434     au ShellCmdPost			*	call s:LocalBrowseRefresh()
10435    else
10436"     call Decho("installing autocmds: ShellCmdPost FocusGained",'~'.expand("<slnum>"))
10437     au ShellCmdPost,FocusGained	*	call s:LocalBrowseRefresh()
10438    endif
10439   augroup END
10440
10441  " user must have changed fastbrowse to its fast setting, so remove
10442  " the associated autocmd events
10443  elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
10444"   call Decho("remove AuNetrwEvent autcmd group",'~'.expand("<slnum>"))
10445   unlet s:netrw_events
10446   augroup AuNetrwEvent
10447    au!
10448   augroup END
10449   augroup! AuNetrwEvent
10450  endif
10451
10452"  call Dret("LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
10453endfun
10454
10455" ---------------------------------------------------------------------
10456"  s:LocalListing: does the job of "ls" for local directories {{{2
10457fun! s:LocalListing()
10458"  call Dfunc("s:LocalListing()")
10459"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10460"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
10461"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10462
10463"  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
10464"  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
10465"  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>"))
10466
10467  " get the list of files contained in the current directory
10468  let dirname    = b:netrw_curdir
10469  let dirnamelen = strlen(b:netrw_curdir)
10470  if v:version == 704 && has("patch656")
10471"   call Decho("using glob with patch656",'~'.expand("<slnum>"))
10472   let filelist   = glob(s:ComposePath(dirname,"*"),0,1,1)
10473   let filelist   = filelist + glob(s:ComposePath(dirname,".*"),0,1,1)
10474  else
10475"   call Decho("using glob without patch656",'~'.expand("<slnum>"))
10476   let filelist   = glob(s:ComposePath(dirname,"*"),0,1)
10477   let filelist   = filelist + glob(s:ComposePath(dirname,".*"),0,1)
10478  endif
10479"  call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10480
10481  if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
10482"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10483  elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
10484    " include ../ in the glob() entry if its missing
10485"   call Decho("forcibly including on \"..\"",'~'.expand("<slnum>"))
10486   let filelist= filelist+[s:ComposePath(b:netrw_curdir,"../")]
10487"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10488  endif
10489
10490"  call Decho("before while: dirname<".dirname.">",'~'.expand("<slnum>"))
10491"  call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>"))
10492"  call Decho("before while: filelist=".string(filelist),'~'.expand("<slnum>"))
10493
10494  if get(g:, 'netrw_dynamic_maxfilenamelen', 0)
10495   let filelistcopy           = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10496   let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
10497"   call Decho("dynamic_maxfilenamelen: filenames             =".string(filelistcopy),'~'.expand("<slnum>"))
10498"   call Decho("dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen,'~'.expand("<slnum>"))
10499  endif
10500"  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>"))
10501
10502  for filename in filelist
10503"   call Decho(" ",'~'.expand("<slnum>"))
10504"   call Decho("for filename in filelist: filename<".filename.">",'~'.expand("<slnum>"))
10505
10506   if getftype(filename) == "link"
10507    " indicate a symbolic link
10508"    call Decho("indicate <".filename."> is a symbolic link with trailing @",'~'.expand("<slnum>"))
10509    let pfile= filename."@"
10510
10511   elseif getftype(filename) == "socket"
10512    " indicate a socket
10513"    call Decho("indicate <".filename."> is a socket with trailing =",'~'.expand("<slnum>"))
10514    let pfile= filename."="
10515
10516   elseif getftype(filename) == "fifo"
10517    " indicate a fifo
10518"    call Decho("indicate <".filename."> is a fifo with trailing |",'~'.expand("<slnum>"))
10519    let pfile= filename."|"
10520
10521   elseif isdirectory(s:NetrwFile(filename))
10522    " indicate a directory
10523"    call Decho("indicate <".filename."> is a directory with trailing /",'~'.expand("<slnum>"))
10524    let pfile= filename."/"
10525
10526   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10527    if (has("win32") || has("win95") || has("win64") || has("win16"))
10528     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10529      " indicate an executable
10530"      call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10531      let pfile= filename."*"
10532     else
10533      " normal file
10534      let pfile= filename
10535     endif
10536    elseif executable(filename)
10537     " indicate an executable
10538"     call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10539     let pfile= filename."*"
10540    else
10541     " normal file
10542     let pfile= filename
10543    endif
10544
10545   else
10546    " normal file
10547    let pfile= filename
10548   endif
10549"   call Decho("pfile<".pfile."> (after *@/ appending)",'~'.expand("<slnum>"))
10550
10551   if pfile =~ '//$'
10552    let pfile= substitute(pfile,'//$','/','e')
10553"    call Decho("change // to /: pfile<".pfile.">",'~'.expand("<slnum>"))
10554   endif
10555   let pfile= strpart(pfile,dirnamelen)
10556   let pfile= substitute(pfile,'^[/\\]','','e')
10557"   call Decho("filename<".filename.">",'~'.expand("<slnum>"))
10558"   call Decho("pfile   <".pfile.">",'~'.expand("<slnum>"))
10559
10560   if w:netrw_liststyle == s:LONGLIST
10561    let sz   = getfsize(filename)
10562    if g:netrw_sizestyle =~ "[hH]"
10563     let sz= s:NetrwHumanReadable(sz)
10564    endif
10565    let fsz  = strpart("               ",1,15-strlen(sz)).sz
10566    let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
10567"    call Decho("sz=".sz." fsz=".fsz,'~'.expand("<slnum>"))
10568   endif
10569
10570   if     g:netrw_sort_by =~ "^t"
10571    " sort by time (handles time up to 1 quintillion seconds, US)
10572"    call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>"))
10573    let t  = getftime(filename)
10574    let ft = strpart("000000000000000000",1,18-strlen(t)).t
10575"    call Decho("exe NetrwKeepj put ='".ft.'/'.filename."'",'~'.expand("<slnum>"))
10576    let ftpfile= ft.'/'.pfile
10577    sil! NetrwKeepj put=ftpfile
10578
10579   elseif g:netrw_sort_by =~ "^s"
10580    " sort by size (handles file sizes up to 1 quintillion bytes, US)
10581"    call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>"))
10582    let sz   = getfsize(filename)
10583    if g:netrw_sizestyle =~ "[hH]"
10584     let sz= s:NetrwHumanReadable(sz)
10585    endif
10586    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
10587"    call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>"))
10588    let fszpfile= fsz.'/'.pfile
10589    sil! NetrwKeepj put =fszpfile
10590
10591   else
10592    " sort by name
10593"    call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("<slnum>"))
10594    sil! NetrwKeepj put=pfile
10595   endif
10596  endfor
10597
10598  " cleanup any windows mess at end-of-line
10599  sil! NetrwKeepj g/^$/d
10600  sil! NetrwKeepj %s/\r$//e
10601  call histdel("/",-1)
10602"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
10603  exe "setl ts=".(g:netrw_maxfilenamelen+1)
10604
10605"  call Dret("s:LocalListing")
10606endfun
10607
10608" ---------------------------------------------------------------------
10609" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
10610fun! s:NetrwLocalExecute(cmd)
10611"  call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
10612  let ykeep= @@
10613  " sanity check
10614  if !executable(a:cmd)
10615   call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
10616   let @@= ykeep
10617"   call Dret("s:NetrwLocalExecute")
10618   return
10619  endif
10620
10621  let optargs= input(":!".a:cmd,"","file")
10622"  call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
10623  let result= system(a:cmd.optargs)
10624"  call Decho("result,'~'.expand("<slnum>"))
10625
10626  " strip any ansi escape sequences off
10627  let result = substitute(result,"\e\\[[0-9;]*m","","g")
10628
10629  " show user the result(s)
10630  echomsg result
10631  let @@= ykeep
10632
10633"  call Dret("s:NetrwLocalExecute")
10634endfun
10635
10636" ---------------------------------------------------------------------
10637" s:NetrwLocalRename: rename a local file or directory {{{2
10638fun! s:NetrwLocalRename(path) range
10639"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
10640
10641  " preparation for removing multiple files/directories
10642  let ykeep    = @@
10643  let ctr      = a:firstline
10644  let svpos    = winsaveview()
10645"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10646
10647  " rename files given by the markfilelist
10648  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10649   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10650"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10651    if exists("subfrom")
10652     let newname= substitute(oldname,subfrom,subto,'')
10653"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10654    else
10655     call inputsave()
10656     let newname= input("Moving ".oldname." to : ",oldname,"file")
10657     call inputrestore()
10658     if newname =~ ''
10659      " two ctrl-x's : ignore all of string preceding the ctrl-x's
10660      let newname = substitute(newname,'^.*','','')
10661     elseif newname =~ ''
10662      " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
10663      let newname = substitute(newname,'[^/]*','','')
10664     endif
10665     if newname =~ '^s/'
10666      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10667      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10668"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10669      let newname = substitute(oldname,subfrom,subto,'')
10670     endif
10671    endif
10672    call rename(oldname,newname)
10673   endfor
10674   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10675
10676  else
10677
10678   " attempt to rename files/directories
10679   while ctr <= a:lastline
10680    exe "NetrwKeepj ".ctr
10681
10682    " sanity checks
10683    if line(".") < w:netrw_bannercnt
10684     let ctr= ctr + 1
10685     continue
10686    endif
10687    let curword= s:NetrwGetWord()
10688    if curword == "./" || curword == "../"
10689     let ctr= ctr + 1
10690     continue
10691    endif
10692
10693    NetrwKeepj norm! 0
10694    let oldname= s:ComposePath(a:path,curword)
10695"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10696
10697    call inputsave()
10698    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
10699    call inputrestore()
10700
10701    call rename(oldname,newname)
10702"   call Decho("renaming <".oldname."> to <".newname.">",'~'.expand("<slnum>"))
10703
10704    let ctr= ctr + 1
10705   endwhile
10706  endif
10707
10708  " refresh the directory
10709"  call Decho("refresh the directory listing",'~'.expand("<slnum>"))
10710  NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10711"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10712  NetrwKeepj call winrestview(svpos)
10713  let @@= ykeep
10714
10715"  call Dret("NetrwLocalRename")
10716endfun
10717
10718" ---------------------------------------------------------------------
10719" s:NetrwLocalRm: {{{2
10720fun! s:NetrwLocalRm(path) range
10721"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
10722"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10723
10724  " preparation for removing multiple files/directories
10725  let ykeep = @@
10726  let ret   = 0
10727  let all   = 0
10728  let svpos = winsaveview()
10729"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10730
10731  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10732   " remove all marked files
10733"   call Decho("remove all marked files",'~'.expand("<slnum>"))
10734   for fname in s:netrwmarkfilelist_{bufnr("%")}
10735    let ok= s:NetrwLocalRmFile(a:path,fname,all)
10736    if ok =~ 'q\%[uit]' || ok == "no"
10737     break
10738    elseif ok =~ 'a\%[ll]'
10739     let all= 1
10740    endif
10741   endfor
10742   call s:NetrwUnMarkFile(1)
10743
10744  else
10745  " remove (multiple) files and directories
10746"   call Decho("remove files in range [".a:firstline.",".a:lastline."]",'~'.expand("<slnum>"))
10747
10748   let keepsol= &l:sol
10749   setl nosol
10750   let ctr = a:firstline
10751   while ctr <= a:lastline
10752    exe "NetrwKeepj ".ctr
10753
10754    " sanity checks
10755    if line(".") < w:netrw_bannercnt
10756     let ctr= ctr + 1
10757     continue
10758    endif
10759    let curword= s:NetrwGetWord()
10760    if curword == "./" || curword == "../"
10761     let ctr= ctr + 1
10762     continue
10763    endif
10764    let ok= s:NetrwLocalRmFile(a:path,curword,all)
10765    if ok =~ 'q\%[uit]' || ok == "no"
10766     break
10767    elseif ok =~ 'a\%[ll]'
10768     let all= 1
10769    endif
10770    let ctr= ctr + 1
10771   endwhile
10772   let &l:sol= keepsol
10773  endif
10774
10775  " refresh the directory
10776"  call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>"))
10777  if bufname("%") != "NetrwMessage"
10778   NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10779"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10780   NetrwKeepj call winrestview(svpos)
10781  endif
10782  let @@= ykeep
10783
10784"  call Dret("s:NetrwLocalRm")
10785endfun
10786
10787" ---------------------------------------------------------------------
10788" s:NetrwLocalRmFile: remove file fname given the path {{{2
10789"                     Give confirmation prompt unless all==1
10790fun! s:NetrwLocalRmFile(path,fname,all)
10791"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
10792
10793  let all= a:all
10794  let ok = ""
10795  NetrwKeepj norm! 0
10796  let rmfile= s:NetrwFile(s:ComposePath(a:path,a:fname))
10797"  call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
10798
10799  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
10800   " attempt to remove file
10801"   call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
10802   if !all
10803    echohl Statement
10804    call inputsave()
10805    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10806    call inputrestore()
10807    echohl NONE
10808    if ok == ""
10809     let ok="no"
10810    endif
10811"    call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
10812    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10813"    call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
10814    if ok =~ 'a\%[ll]'
10815     let all= 1
10816    endif
10817   endif
10818
10819   if all || ok =~ 'y\%[es]' || ok == ""
10820    let ret= s:NetrwDelete(rmfile)
10821"    call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
10822   endif
10823
10824  else
10825   " attempt to remove directory
10826   if !all
10827    echohl Statement
10828    call inputsave()
10829    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10830    call inputrestore()
10831    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10832    if ok == ""
10833     let ok="no"
10834    endif
10835    if ok =~ 'a\%[ll]'
10836     let all= 1
10837    endif
10838   endif
10839   let rmfile= substitute(rmfile,'[\/]$','','e')
10840
10841   if all || ok =~ 'y\%[es]' || ok == ""
10842    if v:version < 704 || !has("patch1109")
10843" "    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>"))
10844     call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile))
10845" "    call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>"))
10846
10847     if v:shell_error != 0
10848" "     call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
10849      let errcode= s:NetrwDelete(rmfile)
10850" "     call Decho("errcode=".errcode,'~'.expand("<slnum>"))
10851
10852      if errcode != 0
10853       if has("unix")
10854" "       call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
10855	call system("rm ".s:ShellEscape(rmfile))
10856	if v:shell_error != 0 && !exists("g:netrw_quiet")
10857	 call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
10858	 let ok="no"
10859	endif
10860       elseif !exists("g:netrw_quiet")
10861	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
10862	let ok="no"
10863       endif
10864      endif
10865     endif
10866    else
10867     if delete(rmfile,"d")
10868      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
10869     endif
10870    endif
10871   endif
10872  endif
10873
10874"  call Dret("s:NetrwLocalRmFile ".ok)
10875  return ok
10876endfun
10877
10878" ---------------------------------------------------------------------
10879" Support Functions: {{{1
10880
10881" ---------------------------------------------------------------------
10882" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
10883"   0: marked file list of current buffer
10884"   1: marked file target
10885fun! netrw#Access(ilist)
10886  if     a:ilist == 0
10887   if exists("s:netrwmarkfilelist_".bufnr('%'))
10888    return s:netrwmarkfilelist_{bufnr('%')}
10889   else
10890    return "no-list-buf#".bufnr('%')
10891   endif
10892  elseif a:ilist == 1
10893   return s:netrwmftgt
10894endfun
10895
10896" ---------------------------------------------------------------------
10897" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
10898fun! netrw#Call(funcname,...)
10899"  call Dfunc("netrw#Call(funcname<".a:funcname.">,".string(a:000).")")
10900  if a:0 > 0
10901   exe "call s:".a:funcname."(".string(a:000).")"
10902  else
10903   exe "call s:".a:funcname."()"
10904  endif
10905"  call Dret("netrw#Call")
10906endfun
10907
10908" ------------------------------------------------------------------------
10909
10910" ---------------------------------------------------------------------
10911" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
10912"               I expect this function to be used in
10913"                 :PChkAssert netrw#Expose("netrwmarkfilelist")
10914"               for example.
10915fun! netrw#Expose(varname)
10916"   call Dfunc("netrw#Expose(varname<".a:varname.">)")
10917  exe "let retval= s:".a:varname
10918  if exists("g:netrw_pchk")
10919   if type(retval) == 3
10920    let retval = copy(retval)
10921    let i      = 0
10922    while i < len(retval)
10923     let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
10924     let i        = i + 1
10925    endwhile
10926   endif
10927"    call Dret("netrw#Expose ".string(retval))
10928   return string(retval)
10929  endif
10930
10931"  call Dret("netrw#Expose ".string(retval))
10932  return retval
10933endfun
10934
10935" ---------------------------------------------------------------------
10936" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
10937fun! netrw#Modify(varname,newvalue)
10938"  call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
10939  exe "let s:".a:varname."= ".string(a:newvalue)
10940"  call Dret("netrw#Modify")
10941endfun
10942
10943" ---------------------------------------------------------------------
10944"  netrw#RFC2396: converts %xx into characters {{{2
10945fun! netrw#RFC2396(fname)
10946"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
10947  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
10948"  call Dret("netrw#RFC2396 ".fname)
10949  return fname
10950endfun
10951
10952" ---------------------------------------------------------------------
10953" netrw#UserMaps: supports user-specified maps {{{2
10954"                 see :help function()
10955"
10956"                 g:Netrw_UserMaps is a List with members such as:
10957"                       [[keymap sequence, function reference],...]
10958"
10959"                 The referenced function may return a string,
10960"                 	refresh : refresh the display
10961"                 	-other- : this string will be executed
10962"                 or it may return a List of strings.
10963"
10964"                 Each keymap-sequence will be set up with a nnoremap
10965"                 to invoke netrw#UserMaps(islocal).
10966"                 Related functions:
10967"                   netrw#Expose(varname)          -- see s:varname variables
10968"                   netrw#Modify(varname,newvalue) -- modify value of s:varname variable
10969"                   netrw#Call(funcname,...)       -- call internal netrw function with optional arguments
10970fun! netrw#UserMaps(islocal)
10971"  call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
10972"  call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
10973
10974   " set up usermaplist
10975   if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
10976"    call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
10977    for umap in g:Netrw_UserMaps
10978"     call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
10979"     call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
10980     " if umap[0] is a string and umap[1] is a string holding a function name
10981     if type(umap[0]) == 1 && type(umap[1]) == 1
10982"      call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
10983      exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
10984      else
10985       call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
10986     endif
10987    endfor
10988   endif
10989"  call Dret("netrw#UserMaps")
10990endfun
10991
10992" ---------------------------------------------------------------------
10993" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
10994fun! netrw#WinPath(path)
10995"  call Dfunc("netrw#WinPath(path<".a:path.">)")
10996  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
10997   " remove cygdrive prefix, if present
10998   let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
10999   " remove trailing slash (Win95)
11000   let path = substitute(path, '\(\\\|/\)$', '', 'g')
11001   " remove escaped spaces
11002   let path = substitute(path, '\ ', ' ', 'g')
11003   " convert slashes to backslashes
11004   let path = substitute(path, '/', '\', 'g')
11005  else
11006   let path= a:path
11007  endif
11008"  call Dret("netrw#WinPath <".path.">")
11009  return path
11010endfun
11011
11012" ---------------------------------------------------------------------
11013"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
11014fun! s:ComposePath(base,subdir)
11015"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
11016
11017  if has("amiga")
11018"   call Decho("amiga",'~'.expand("<slnum>"))
11019   let ec = a:base[s:Strlen(a:base)-1]
11020   if ec != '/' && ec != ':'
11021    let ret = a:base . "/" . a:subdir
11022   else
11023    let ret = a:base . a:subdir
11024   endif
11025
11026  elseif a:subdir =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
11027"   call Decho("windows",'~'.expand("<slnum>"))
11028   let ret= a:subdir
11029
11030  elseif a:base =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
11031"   call Decho("windows",'~'.expand("<slnum>"))
11032   if a:base =~ '[/\\]$'
11033    let ret= a:base.a:subdir
11034   else
11035    let ret= a:base.'/'.a:subdir
11036   endif
11037
11038  elseif a:base =~ '^\a\{3,}://'
11039"   call Decho("remote linux/macos",'~'.expand("<slnum>"))
11040   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
11041   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
11042   if a:subdir == '../'
11043    if curpath =~ '[^/]/[^/]\+/$'
11044     let curpath= substitute(curpath,'[^/]\+/$','','')
11045    else
11046     let curpath=""
11047    endif
11048    let ret= urlbase.curpath
11049   else
11050    let ret= urlbase.curpath.a:subdir
11051   endif
11052"   call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
11053"   call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
11054"   call Decho("ret<".ret.">",'~'.expand("<slnum>"))
11055
11056  else
11057"   call Decho("local linux/macos",'~'.expand("<slnum>"))
11058   let ret = substitute(a:base."/".a:subdir,"//","/","g")
11059   if a:base =~ '^//'
11060    " keeping initial '//' for the benefit of network share listing support
11061    let ret= '/'.ret
11062   endif
11063   let ret= simplify(ret)
11064  endif
11065
11066"  call Dret("s:ComposePath ".ret)
11067  return ret
11068endfun
11069
11070" ---------------------------------------------------------------------
11071" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
11072"   Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
11073fun! s:DeleteBookmark(fname)
11074"  call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
11075  call s:MergeBookmarks()
11076
11077  if exists("g:netrw_bookmarklist")
11078   let indx= index(g:netrw_bookmarklist,a:fname)
11079   if indx == -1
11080    let indx= 0
11081    while indx < len(g:netrw_bookmarklist)
11082     if g:netrw_bookmarklist[indx] =~ a:fname
11083      call remove(g:netrw_bookmarklist,indx)
11084      let indx= indx - 1
11085     endif
11086     let indx= indx + 1
11087    endwhile
11088   else
11089    " remove exact match
11090    call remove(g:netrw_bookmarklist,indx)
11091   endif
11092  endif
11093
11094"  call Dret("s:DeleteBookmark")
11095endfun
11096
11097" ---------------------------------------------------------------------
11098" s:FileReadable: o/s independent filereadable {{{2
11099fun! s:FileReadable(fname)
11100"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
11101
11102  if g:netrw_cygwin
11103   let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
11104  else
11105   let ret= filereadable(s:NetrwFile(a:fname))
11106  endif
11107
11108"  call Dret("s:FileReadable ".ret)
11109  return ret
11110endfun
11111
11112" ---------------------------------------------------------------------
11113"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
11114"                 Places correct suffix on end of temporary filename,
11115"                 using the suffix provided with fname
11116fun! s:GetTempfile(fname)
11117"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
11118
11119  if !exists("b:netrw_tmpfile")
11120   " get a brand new temporary filename
11121   let tmpfile= tempname()
11122"   call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
11123
11124   let tmpfile= substitute(tmpfile,'\','/','ge')
11125"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
11126
11127   " sanity check -- does the temporary file's directory exist?
11128   if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
11129"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11130    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
11131"    call Dret("s:GetTempfile getcwd<".getcwd().">")
11132    return ""
11133   endif
11134
11135   " let netrw#NetSource() know about the tmpfile
11136   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
11137"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
11138
11139   " o/s dependencies
11140   if g:netrw_cygwin != 0
11141    let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
11142   elseif has("win32") || has("win95") || has("win64") || has("win16")
11143    if !exists("+shellslash") || !&ssl
11144     let tmpfile = substitute(tmpfile,'/','\','g')
11145    endif
11146   else
11147    let tmpfile = tmpfile
11148   endif
11149   let b:netrw_tmpfile= tmpfile
11150"   call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
11151  else
11152   " re-use temporary filename
11153   let tmpfile= b:netrw_tmpfile
11154"   call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
11155  endif
11156
11157  " use fname's suffix for the temporary file
11158  if a:fname != ""
11159   if a:fname =~ '\.[^./]\+$'
11160"    call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11161    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11162     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11163    elseif a:fname =~ '.txz$'
11164     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11165    else
11166     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11167    endif
11168"    call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11169    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11170"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11171    let tmpfile .= suffix
11172"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11173    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
11174   endif
11175  endif
11176
11177"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11178"  call Dret("s:GetTempfile <".tmpfile.">")
11179  return tmpfile
11180endfun
11181
11182" ---------------------------------------------------------------------
11183" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
11184"               a correct command for use with a system() call
11185fun! s:MakeSshCmd(sshcmd)
11186"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
11187  if s:user == ""
11188   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
11189  else
11190   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
11191  endif
11192  if exists("g:netrw_port") && g:netrw_port != ""
11193   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
11194  elseif exists("s:port") && s:port != ""
11195   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
11196  else
11197   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
11198  endif
11199"  call Dret("s:MakeSshCmd <".sshcmd.">")
11200  return sshcmd
11201endfun
11202
11203" ---------------------------------------------------------------------
11204" s:MakeBookmark: enters a bookmark into Netrw's bookmark system   {{{2
11205fun! s:MakeBookmark(fname)
11206"  call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
11207
11208  if !exists("g:netrw_bookmarklist")
11209   let g:netrw_bookmarklist= []
11210  endif
11211
11212  if index(g:netrw_bookmarklist,a:fname) == -1
11213   " curdir not currently in g:netrw_bookmarklist, so include it
11214   if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11215    call add(g:netrw_bookmarklist,a:fname.'/')
11216   elseif a:fname !~ '/'
11217    call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11218   else
11219    call add(g:netrw_bookmarklist,a:fname)
11220   endif
11221   call sort(g:netrw_bookmarklist)
11222  endif
11223
11224"  call Dret("s:MakeBookmark")
11225endfun
11226
11227" ---------------------------------------------------------------------
11228" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11229fun! s:MergeBookmarks()
11230"  call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
11231  " get bookmarks from .netrwbook file
11232  let savefile= s:NetrwHome()."/.netrwbook"
11233  if filereadable(s:NetrwFile(savefile))
11234"   call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11235   NetrwKeepj call s:NetrwBookHistSave()
11236"   call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11237   NetrwKeepj call delete(savefile)
11238  endif
11239"  call Dret("s:MergeBookmarks")
11240endfun
11241
11242" ---------------------------------------------------------------------
11243" s:NetrwBMShow: {{{2
11244fun! s:NetrwBMShow()
11245"  call Dfunc("s:NetrwBMShow()")
11246  redir => bmshowraw
11247   menu
11248  redir END
11249  let bmshowlist = split(bmshowraw,'\n')
11250  if bmshowlist != []
11251   let bmshowfuncs= filter(bmshowlist,'v:val =~ "<SNR>\\d\\+_BMShow()"')
11252   if bmshowfuncs != []
11253    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11254    if bmshowfunc =~ '^call.*BMShow()'
11255     exe "sil! NetrwKeepj ".bmshowfunc
11256    endif
11257   endif
11258  endif
11259"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
11260endfun
11261
11262" ---------------------------------------------------------------------
11263" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
11264fun! s:NetrwCursor()
11265  if !exists("w:netrw_liststyle")
11266   let w:netrw_liststyle= g:netrw_liststyle
11267  endif
11268"  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)
11269
11270  if &ft != "netrw"
11271   " if the current window isn't a netrw directory listing window, then use user cursorline/column
11272   " settings.  Affects when netrw is used to read/write a file using scp/ftp/etc.
11273"   call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
11274   let &l:cursorline   = s:netrw_usercul
11275   let &l:cursorcolumn = s:netrw_usercuc
11276
11277  elseif g:netrw_cursor == 4
11278   " all styles: cursorline, cursorcolumn
11279"   call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
11280   setl cursorline
11281   setl cursorcolumn
11282
11283  elseif g:netrw_cursor == 3
11284   " thin-long-tree: cursorline, user's cursorcolumn
11285   " wide          : cursorline, cursorcolumn
11286   if w:netrw_liststyle == s:WIDELIST
11287"    call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11288    setl cursorline
11289    setl cursorcolumn
11290   else
11291"    call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11292    setl cursorline
11293    let &l:cursorcolumn   = s:netrw_usercuc
11294   endif
11295
11296  elseif g:netrw_cursor == 2
11297   " thin-long-tree: cursorline, user's cursorcolumn
11298   " wide          : cursorline, user's cursorcolumn
11299"   call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11300   let &l:cursorcolumn = s:netrw_usercuc
11301   setl cursorline
11302
11303  elseif g:netrw_cursor == 1
11304   " thin-long-tree: user's cursorline, user's cursorcolumn
11305   " wide          : cursorline,        user's cursorcolumn
11306   let &l:cursorcolumn = s:netrw_usercuc
11307   if w:netrw_liststyle == s:WIDELIST
11308"    call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11309    setl cursorline
11310   else
11311"    call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11312    let &l:cursorline   = s:netrw_usercul
11313   endif
11314
11315  else
11316   " all styles: user's cursorline, user's cursorcolumn
11317"   call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11318   let &l:cursorline   = s:netrw_usercul
11319   let &l:cursorcolumn = s:netrw_usercuc
11320  endif
11321
11322"  call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
11323endfun
11324
11325" ---------------------------------------------------------------------
11326" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11327fun! s:RestoreCursorline()
11328"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
11329  if exists("s:netrw_usercul")
11330   let &l:cursorline   = s:netrw_usercul
11331  endif
11332  if exists("s:netrw_usercuc")
11333   let &l:cursorcolumn = s:netrw_usercuc
11334  endif
11335"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
11336endfun
11337
11338" ---------------------------------------------------------------------
11339" s:NetrwDelete: Deletes a file. {{{2
11340"           Uses Steve Hall's idea to insure that Windows paths stay
11341"           acceptable.  No effect on Unix paths.
11342"  Examples of use:  let result= s:NetrwDelete(path)
11343fun! s:NetrwDelete(path)
11344"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
11345
11346  let path = netrw#WinPath(a:path)
11347  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
11348   if exists("+shellslash")
11349    let sskeep= &shellslash
11350    setl noshellslash
11351    let result      = delete(path)
11352    let &shellslash = sskeep
11353   else
11354"    call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11355    let result= delete(path)
11356   endif
11357  else
11358"   call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11359   let result= delete(path)
11360  endif
11361  if result < 0
11362   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
11363  endif
11364
11365"  call Dret("s:NetrwDelete ".result)
11366  return result
11367endfun
11368
11369" ---------------------------------------------------------------------
11370" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
11371fun! s:NetrwEnew(...)
11372"  call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$"))
11373"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
11374
11375  " grab a function-local-variable copy of buffer variables
11376"  call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
11377  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
11378  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
11379  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
11380  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
11381  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11382  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
11383  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
11384  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
11385  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11386  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11387  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
11388  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
11389  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
11390  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
11391  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
11392  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
11393
11394  NetrwKeepj call s:NetrwOptionRestore("w:")
11395"  call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>"))
11396  " when tree listing uses file TreeListing... a new buffer is made.
11397  " Want the old buffer to be unlisted.
11398  setl nobl
11399  let netrw_keepdiff= &l:diff
11400  noswapfile NetrwKeepj keepalt enew!
11401  let &l:diff= netrw_keepdiff
11402"  call Decho("bufnr($)=".bufnr("$")." winnr($)=".winnr("$"),'~'.expand("<slnum>"))
11403  NetrwKeepj call s:NetrwOptionSave("w:")
11404
11405  " copy function-local-variables to buffer variable equivalents
11406"  call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
11407  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
11408  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
11409  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
11410  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
11411  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
11412  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
11413  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
11414  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
11415  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11416  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11417  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
11418  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
11419  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
11420  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
11421  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
11422  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
11423
11424  if a:0 > 0
11425   let b:netrw_curdir= a:1
11426   if b:netrw_curdir =~ '/$'
11427    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11428     setl nobl
11429     file NetrwTreeListing
11430     setl nobl bt=nowrite bh=hide
11431     nno <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
11432     nno <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
11433    else
11434     exe "sil! keepalt file ".fnameescape(b:netrw_curdir)
11435    endif
11436   endif
11437  endif
11438
11439"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
11440endfun
11441
11442" ---------------------------------------------------------------------
11443" s:NetrwExe: executes a string using "!" {{{2
11444fun! s:NetrwExe(cmd)
11445"  call Dfunc("s:NetrwExe(a:cmd)")
11446  if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin
11447    let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
11448    set shell& shellcmdflag& shellxquote& shellxescape&
11449    set shellquote& shellpipe& shellredir& shellslash&
11450    exe a:cmd
11451    let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
11452  else
11453   exe a:cmd
11454  endif
11455"  call Dret("s:NetrwExe")
11456endfun
11457
11458" ---------------------------------------------------------------------
11459" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
11460fun! s:NetrwInsureWinVars()
11461"  call Dfunc("s:NetrwInsureWinVars() win#".winnr())
11462  if !exists("w:netrw_liststyle")
11463   let curbuf = bufnr("%")
11464   let curwin = winnr()
11465   let iwin   = 1
11466   while iwin <= winnr("$")
11467    exe iwin."wincmd w"
11468    if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
11469     " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
11470     let winvars= w:
11471     break
11472    endif
11473    let iwin= iwin + 1
11474   endwhile
11475   exe "keepalt ".curwin."wincmd w"
11476   if exists("winvars")
11477"    call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
11478    for k in keys(winvars)
11479     let w:{k}= winvars[k]
11480    endfor
11481   endif
11482  endif
11483"  call Dret("s:NetrwInsureWinVars win#".winnr())
11484endfun
11485
11486" ---------------------------------------------------------------------
11487" s:NetrwLcd: handles changing the (local) directory {{{2
11488fun! s:NetrwLcd(newdir)
11489"  call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
11490
11491  try
11492   exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
11493  catch /^Vim\%((\a\+)\)\=:E344/
11494     " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
11495     " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
11496     " 'root' (ie. '\').  The share name may start with either backslashes ('\\Foo') or
11497     " forward slashes ('//Foo'), depending on whether backslashes have been converted to
11498     " forward slashes by earlier code; so check for both.
11499     if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
11500       if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
11501         let dirname = '\'
11502	 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
11503       endif
11504     endif
11505  catch /^Vim\%((\a\+)\)\=:E472/
11506   call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
11507   if exists("w:netrw_prvdir")
11508    let a:newdir= w:netrw_prvdir
11509   else
11510    call s:NetrwOptionRestore("w:")
11511"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
11512    exe "setl ".g:netrw_bufsettings
11513"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11514    let a:newdir= dirname
11515"    call Dret("s:NetrwBrowse : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
11516    return
11517   endif
11518  endtry
11519
11520"  call Dret("s:NetrwLcd")
11521endfun
11522
11523" ------------------------------------------------------------------------
11524" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
11525" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
11526fun! s:NetrwSaveWordPosn()
11527"  call Dfunc("NetrwSaveWordPosn()")
11528  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
11529"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
11530endfun
11531
11532" ---------------------------------------------------------------------
11533" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
11534"                       1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
11535fun! s:NetrwHumanReadable(sz)
11536"  call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
11537
11538  if g:netrw_sizestyle == 'h'
11539   if a:sz >= 1000000000
11540    let sz = printf("%.1f",a:sz/1000000000.0)."g"
11541   elseif a:sz >= 10000000
11542    let sz = printf("%d",a:sz/1000000)."m"
11543   elseif a:sz >= 1000000
11544    let sz = printf("%.1f",a:sz/1000000.0)."m"
11545   elseif a:sz >= 10000
11546    let sz = printf("%d",a:sz/1000)."k"
11547   elseif a:sz >= 1000
11548    let sz = printf("%.1f",a:sz/1000.0)."k"
11549   else
11550    let sz= a:sz
11551   endif
11552
11553  elseif g:netrw_sizestyle == 'H'
11554   if a:sz >= 1073741824
11555    let sz = printf("%.1f",a:sz/1073741824.0)."G"
11556   elseif a:sz >= 10485760
11557    let sz = printf("%d",a:sz/1048576)."M"
11558   elseif a:sz >= 1048576
11559    let sz = printf("%.1f",a:sz/1048576.0)."M"
11560   elseif a:sz >= 10240
11561    let sz = printf("%d",a:sz/1024)."K"
11562   elseif a:sz >= 1024
11563    let sz = printf("%.1f",a:sz/1024.0)."K"
11564   else
11565    let sz= a:sz
11566   endif
11567
11568  else
11569   let sz= a:sz
11570  endif
11571
11572"  call Dret("s:NetrwHumanReadable ".sz)
11573  return sz
11574endfun
11575
11576" ---------------------------------------------------------------------
11577" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
11578"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
11579fun! s:NetrwRestoreWordPosn()
11580"  call Dfunc("NetrwRestoreWordPosn()")
11581  sil! call search(s:netrw_saveword,'w')
11582"  call Dret("NetrwRestoreWordPosn")
11583endfun
11584
11585" ---------------------------------------------------------------------
11586" s:RestoreBufVars: {{{2
11587fun! s:RestoreBufVars()
11588"  call Dfunc("s:RestoreBufVars()")
11589
11590  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
11591  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
11592  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
11593  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
11594  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
11595  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
11596
11597"  call Dret("s:RestoreBufVars")
11598endfun
11599
11600" ---------------------------------------------------------------------
11601" s:RemotePathAnalysis: {{{2
11602fun! s:RemotePathAnalysis(dirname)
11603"  call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
11604
11605  "                method   ://    user  @      machine      :port            /path
11606  let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
11607  let s:method  = substitute(a:dirname,dirpat,'\1','')
11608  let s:user    = substitute(a:dirname,dirpat,'\3','')
11609  let s:machine = substitute(a:dirname,dirpat,'\4','')
11610  let s:port    = substitute(a:dirname,dirpat,'\5','')
11611  let s:path    = substitute(a:dirname,dirpat,'\6','')
11612  let s:fname   = substitute(s:path,'^.*/\ze.','','')
11613  if s:machine =~ '@'
11614   let dirpat    = '^\(.*\)@\(.\{-}\)$'
11615   let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')
11616   let s:machine = substitute(s:machine,dirpat,'\2','')
11617  endif
11618
11619"  call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
11620"  call Decho("set up s:user   <".s:user   .">",'~'.expand("<slnum>"))
11621"  call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
11622"  call Decho("set up s:port   <".s:port.">",'~'.expand("<slnum>"))
11623"  call Decho("set up s:path   <".s:path   .">",'~'.expand("<slnum>"))
11624"  call Decho("set up s:fname  <".s:fname  .">",'~'.expand("<slnum>"))
11625
11626"  call Dret("s:RemotePathAnalysis")
11627endfun
11628
11629" ---------------------------------------------------------------------
11630" s:RemoteSystem: runs a command on a remote host using ssh {{{2
11631"                 Returns status
11632" Runs system() on
11633"    [cd REMOTEDIRPATH;] a:cmd
11634" Note that it doesn't do s:ShellEscape(a:cmd)!
11635fun! s:RemoteSystem(cmd)
11636"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
11637  if !executable(g:netrw_ssh_cmd)
11638   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
11639  elseif !exists("b:netrw_curdir")
11640   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
11641  else
11642   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
11643   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
11644   if remotedir != ""
11645    let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
11646   else
11647    let cmd= cmd.' '
11648   endif
11649   let cmd= cmd.a:cmd
11650"   call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
11651   let ret= system(cmd)
11652  endif
11653"  call Dret("s:RemoteSystem ".ret)
11654  return ret
11655endfun
11656
11657" ---------------------------------------------------------------------
11658" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
11659fun! s:RestoreWinVars()
11660"  call Dfunc("s:RestoreWinVars()")
11661  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
11662  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
11663  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
11664  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
11665  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
11666  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
11667  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
11668  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
11669  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
11670  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
11671  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
11672  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
11673  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
11674  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
11675  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
11676  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
11677  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
11678  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
11679"  call Dret("s:RestoreWinVars")
11680endfun
11681
11682" ---------------------------------------------------------------------
11683" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
11684"
11685"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
11686"             is true) and a command, :Rexplore, which call this function.
11687"
11688"             s:nbcd_curpos_{bufnr('%')} is set up by s:NetrwBrowseChgDir()
11689"
11690"             s:rexposn_BUFNR used to save/restore cursor position
11691fun! s:NetrwRexplore(islocal,dirname)
11692  if exists("s:netrwdrag")
11693   return
11694  endif
11695"  call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
11696"  call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
11697"  call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
11698
11699  if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
11700   " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
11701"   call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
11702   exe "NetrwKeepj e ".w:netrw_rexfile
11703   unlet w:netrw_rexfile
11704"   call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%").">  (ft=".&ft.")")
11705   return
11706"  else " Decho
11707"   call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
11708"   call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
11709  endif
11710
11711  " ---------------------------
11712  " :Rex issued while in a file
11713  " ---------------------------
11714
11715  " record current file so :Rex can return to it from netrw
11716  let w:netrw_rexfile= expand("%")
11717"  call Decho("set w:netrw_rexfile<".w:netrw_rexfile.">  (win#".winnr().")",'~'.expand("<slnum>"))
11718
11719  if !exists("w:netrw_rexlocal")
11720"   call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
11721   return
11722  endif
11723"  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>"))
11724  if w:netrw_rexlocal
11725   NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
11726  else
11727   NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
11728  endif
11729  if exists("s:initbeval")
11730   setl beval
11731  endif
11732  if exists("s:rexposn_".bufnr("%"))
11733"   call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
11734   " restore position in directory listing
11735"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
11736   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
11737   if exists("s:rexposn_".bufnr('%'))
11738    unlet s:rexposn_{bufnr('%')}
11739   endif
11740  else
11741"   call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
11742  endif
11743
11744  if exists("s:explore_match")
11745   exe "2match netrwMarkFile /".s:explore_match."/"
11746  endif
11747
11748"  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>"))
11749"  call Dret("s:NetrwRexplore : ft=".&ft)
11750endfun
11751
11752" ---------------------------------------------------------------------
11753" s:SaveBufVars: save selected b: variables to s: variables {{{2
11754"                use s:RestoreBufVars() to restore b: variables from s: variables
11755fun! s:SaveBufVars()
11756"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
11757
11758  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
11759  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
11760  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
11761  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
11762  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
11763  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
11764
11765"  call Dret("s:SaveBufVars")
11766endfun
11767
11768" ---------------------------------------------------------------------
11769" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
11770fun! s:SaveWinVars()
11771"  call Dfunc("s:SaveWinVars() win#".winnr())
11772  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
11773  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
11774  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
11775  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
11776  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
11777  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
11778  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
11779  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
11780  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
11781  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
11782  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
11783  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
11784  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
11785  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
11786  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
11787  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
11788  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
11789  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
11790"  call Dret("s:SaveWinVars")
11791endfun
11792
11793" ---------------------------------------------------------------------
11794" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
11795"   To allow separate windows to have their own activities, such as
11796"   Explore **/pattern, several variables have been made window-oriented.
11797"   However, when the user splits a browser window (ex: ctrl-w s), these
11798"   variables are not inherited by the new window.  SetBufWinVars() and
11799"   UseBufWinVars() get around that.
11800fun! s:SetBufWinVars()
11801"  call Dfunc("s:SetBufWinVars() win#".winnr())
11802  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
11803  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
11804  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
11805  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
11806  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
11807  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
11808  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
11809  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
11810  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
11811  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
11812"  call Dret("s:SetBufWinVars")
11813endfun
11814
11815" ---------------------------------------------------------------------
11816" s:SetRexDir: set directory for :Rexplore {{{2
11817fun! s:SetRexDir(islocal,dirname)
11818"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
11819  let w:netrw_rexdir         = a:dirname
11820  let w:netrw_rexlocal       = a:islocal
11821  let s:rexposn_{bufnr("%")} = winsaveview()
11822"  call Decho("setting w:netrw_rexdir  =".w:netrw_rexdir)
11823"  call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal)
11824"  call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
11825"  call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to SavePosn",'~'.expand("<slnum>"))
11826"  call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
11827endfun
11828
11829" ---------------------------------------------------------------------
11830" s:ShowLink: used to modify thin and tree listings to show links {{{2
11831fun! s:ShowLink()
11832" "  call Dfunc("s:ShowLink()")
11833" "  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
11834" "  call Decho(printf("line#%4d: %s",line("."),getline(".")),'~'.expand("<slnum>"))
11835  if exists("b:netrw_curdir")
11836   norm! $?\a
11837   let fname   = b:netrw_curdir.'/'.s:NetrwGetWord()
11838   let resname = resolve(fname)
11839" "   call Decho("fname         <".fname.">",'~'.expand("<slnum>"))
11840" "   call Decho("resname       <".resname.">",'~'.expand("<slnum>"))
11841" "   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
11842   if resname =~ '^\M'.b:netrw_curdir.'/'
11843    let dirlen  = strlen(b:netrw_curdir)
11844    let resname = strpart(resname,dirlen+1)
11845" "    call Decho("resname<".resname.">  (b:netrw_curdir elided)",'~'.expand("<slnum>"))
11846   endif
11847   let modline = getline(".")."\t --> ".resname
11848" "   call Decho("fname  <".fname.">",'~'.expand("<slnum>"))
11849" "   call Decho("modline<".modline.">",'~'.expand("<slnum>"))
11850   setl noro ma
11851   call setline(".",modline)
11852   setl ro noma nomod
11853  endif
11854" "  call Dret("s:ShowLink".((exists("fname")? ' : '.fname : 'n/a')))
11855endfun
11856
11857" ---------------------------------------------------------------------
11858" s:ShowStyle: {{{2
11859fun! s:ShowStyle()
11860  if !exists("w:netrw_liststyle")
11861   let liststyle= g:netrw_liststyle
11862  else
11863   let liststyle= w:netrw_liststyle
11864  endif
11865  if     liststyle == s:THINLIST
11866   return s:THINLIST.":thin"
11867  elseif liststyle == s:LONGLIST
11868   return s:LONGLIST.":long"
11869  elseif liststyle == s:WIDELIST
11870   return s:WIDELIST.":wide"
11871  elseif liststyle == s:TREELIST
11872   return s:TREELIST.":tree"
11873  else
11874   return 'n/a'
11875  endif
11876endfun
11877
11878" ---------------------------------------------------------------------
11879" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
11880"           Solution from Nicolai Weibull, vim docs (:help strlen()),
11881"           Tony Mechelynck, and my own invention.
11882fun! s:Strlen(x)
11883"  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
11884
11885  if v:version >= 703 && exists("*strdisplaywidth")
11886   let ret= strdisplaywidth(a:x)
11887
11888  elseif type(g:Align_xstrlen) == 1
11889   " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
11890   exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
11891
11892  elseif g:Align_xstrlen == 1
11893   " number of codepoints (Latin a + combining circumflex is two codepoints)
11894   " (comment from TM, solution from NW)
11895   let ret= strlen(substitute(a:x,'.','c','g'))
11896
11897  elseif g:Align_xstrlen == 2
11898   " number of spacing codepoints (Latin a + combining circumflex is one spacing
11899   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
11900   " (comment from TM, solution from TM)
11901   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
11902
11903  elseif g:Align_xstrlen == 3
11904   " virtual length (counting, for instance, tabs as anything between 1 and
11905   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
11906   " preceded by lam, one otherwise, etc.)
11907   " (comment from TM, solution from me)
11908   let modkeep= &l:mod
11909   exe "norm! o\<esc>"
11910   call setline(line("."),a:x)
11911   let ret= virtcol("$") - 1
11912   d
11913   NetrwKeepj norm! k
11914   let &l:mod= modkeep
11915
11916  else
11917   " at least give a decent default
11918    let ret= strlen(a:x)
11919  endif
11920"  "" call Dret("s:Strlen ".ret)
11921  return ret
11922endfun
11923
11924" ---------------------------------------------------------------------
11925" s:ShellEscape: shellescape(), or special windows handling {{{2
11926fun! s:ShellEscape(s, ...)
11927  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
11928    return printf('"%s"', substitute(a:s, '"', '""', 'g'))
11929  endif
11930  let f = a:0 > 0 ? a:1 : 0
11931  return shellescape(a:s, f)
11932endfun
11933
11934" ---------------------------------------------------------------------
11935" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
11936fun! s:TreeListMove(dir)
11937"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
11938  let curline      = getline('.')
11939  let prvline      = (line(".") > 1)?         getline(line(".")-1) : ''
11940  let nxtline      = (line(".") < line("$"))? getline(line(".")+1) : ''
11941  let curindent    = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
11942  let indentm1     = substitute(curindent,'^'.s:treedepthstring,'','')
11943  let treedepthchr = substitute(s:treedepthstring,' ','','g')
11944  let stopline     = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
11945"  call Decho("prvline  <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
11946"  call Decho("curline  <".curline."> #".line(".")    , '~'.expand("<slnum>"))
11947"  call Decho("nxtline  <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
11948"  call Decho("curindent<".curindent.">"              , '~'.expand("<slnum>"))
11949"  call Decho("indentm1 <".indentm1.">"               , '~'.expand("<slnum>"))
11950  "  COMBAK : need to handle when on a directory
11951  "  COMBAK : need to handle ]] and ][.  In general, needs work!!!
11952  if curline !~ '/$'
11953   if     a:dir == '[[' && prvline != ''
11954    NetrwKeepj norm! 0
11955    let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
11956"    call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
11957   elseif a:dir == '[]' && nxtline != ''
11958    NetrwKeepj norm! 0
11959"    call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>')
11960    let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
11961    if nl != 0
11962     NetrwKeepj norm! k
11963    else
11964     NetrwKeepj norm! G
11965    endif
11966"    call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
11967   endif
11968  endif
11969
11970"  call Dret("s:TreeListMove")
11971endfun
11972
11973" ---------------------------------------------------------------------
11974" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
11975"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
11976"                      can't be called except via emenu.  But due to locale, that menu line may not be called
11977"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
11978fun! s:UpdateBuffersMenu()
11979"  call Dfunc("s:UpdateBuffersMenu()")
11980  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
11981   try
11982    sil emenu Buffers.Refresh\ menu
11983   catch /^Vim\%((\a\+)\)\=:E/
11984    let v:errmsg= ""
11985    sil NetrwKeepj call s:NetrwBMShow()
11986   endtry
11987  endif
11988"  call Dret("s:UpdateBuffersMenu")
11989endfun
11990
11991" ---------------------------------------------------------------------
11992" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
11993"              Matching function to s:SetBufWinVars()
11994fun! s:UseBufWinVars()
11995"  call Dfunc("s:UseBufWinVars()")
11996  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
11997  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
11998  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
11999  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
12000  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
12001  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
12002  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
12003  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
12004  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
12005  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
12006"  call Dret("s:UseBufWinVars")
12007endfun
12008
12009" ---------------------------------------------------------------------
12010" s:UserMaps: supports user-defined UserMaps {{{2
12011"               * calls a user-supplied funcref(islocal,curdir)
12012"               * interprets result
12013"             See netrw#UserMaps()
12014fun! s:UserMaps(islocal,funcname)
12015"  call Dfunc("s:UserMaps(islocal=".a:islocal.",funcname<".a:funcname.">)")
12016
12017  if !exists("b:netrw_curdir")
12018   let b:netrw_curdir= getcwd()
12019  endif
12020  let Funcref = function(a:funcname)
12021  let result  = Funcref(a:islocal)
12022
12023  if     type(result) == 1
12024   " if result from user's funcref is a string...
12025"   call Decho("result string from user funcref<".result.">",'~'.expand("<slnum>"))
12026   if result == "refresh"
12027"    call Decho("refreshing display",'~'.expand("<slnum>"))
12028    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12029   elseif result != ""
12030"    call Decho("executing result<".result.">",'~'.expand("<slnum>"))
12031    exe result
12032   endif
12033
12034  elseif type(result) == 3
12035   " if result from user's funcref is a List...
12036"   call Decho("result List from user funcref<".string(result).">",'~'.expand("<slnum>"))
12037   for action in result
12038    if action == "refresh"
12039"     call Decho("refreshing display",'~'.expand("<slnum>"))
12040     call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12041    elseif action != ""
12042"     call Decho("executing action<".action.">",'~'.expand("<slnum>"))
12043     exe action
12044    endif
12045   endfor
12046  endif
12047
12048"  call Dret("s:UserMaps")
12049endfun
12050
12051" ---------------------------------------------------------------------
12052" Settings Restoration: {{{1
12053let &cpo= s:keepcpo
12054unlet s:keepcpo
12055
12056" ------------------------------------------------------------------------
12057" Modelines: {{{1
12058" vim:ts=8 fdm=marker
12059