xref: /vim-8.2.3635/runtime/autoload/netrw.vim (revision fb094e14)
1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		Nov 03, 2017
4" Version:	162
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()
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
26" Check that vim has patches that netrw requires.
27" Patches needed: 1557, and 213.
28" (netrw will benefit from vim's having patch#656, too)
29let s:needspatches=[1557,213]
30if exists("s:needspatches")
31 for ptch in s:needspatches
32  if v:version < 704 || (v:version == 704 && !has("patch".ptch))
33   if !exists("s:needpatch{ptch}")
34    unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch#".ptch
35   endif
36   let s:needpatch{ptch}= 1
37   finish
38  endif
39 endfor
40endif
41
42let g:loaded_netrw = "v162"
43if !exists("s:NOTE")
44 let s:NOTE    = 0
45 let s:WARNING = 1
46 let s:ERROR   = 2
47endif
48
49let s:keepcpo= &cpo
50setl cpo&vim
51"let g:dechofuncname= 1
52"DechoRemOn
53"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw,'~'.expand("<slnum>"))
54
55" ======================
56"  Netrw Variables: {{{1
57" ======================
58
59" ---------------------------------------------------------------------
60" netrw#ErrorMsg: {{{2
61"   0=note     = s:NOTE
62"   1=warning  = s:WARNING
63"   2=error    = s:ERROR
64"   Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number)
65"          netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number)
66"          (this function can optionally take a list of messages)
67"  Mar 21, 2017 : max errnum currently is 105
68fun! netrw#ErrorMsg(level,msg,errnum)
69"  call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
70
71  if a:level < g:netrw_errorlvl
72"   call Dret("netrw#ErrorMsg : suppressing level=".a:level." since g:netrw_errorlvl=".g:netrw_errorlvl)
73   return
74  endif
75
76  if a:level == 1
77   let level= "**warning** (netrw) "
78  elseif a:level == 2
79   let level= "**error** (netrw) "
80  else
81   let level= "**note** (netrw) "
82  endif
83"  call Decho("level=".level,'~'.expand("<slnum>"))
84
85  if g:netrw_use_errorwindow
86   " (default) netrw creates a one-line window to show error/warning
87   " messages (reliably displayed)
88
89   " record current window number
90   let s:winBeforeErr= winnr()
91"   call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>"))
92
93   " getting messages out reliably is just plain difficult!
94   " This attempt splits the current window, creating a one line window.
95   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
96"    call Decho("write to NetrwMessage buffer",'~'.expand("<slnum>"))
97    exe bufwinnr("NetrwMessage")."wincmd w"
98"    call Decho("setl ma noro",'~'.expand("<slnum>"))
99    setl ma noro
100    if type(a:msg) == 3
101     for msg in a:msg
102      NetrwKeepj call setline(line("$")+1,level.msg)
103     endfor
104    else
105     NetrwKeepj call setline(line("$")+1,level.a:msg)
106    endif
107    NetrwKeepj $
108   else
109"    call Decho("create a NetrwMessage buffer window",'~'.expand("<slnum>"))
110    bo 1split
111    sil! call s:NetrwEnew()
112    sil! NetrwKeepj call s:NetrwSafeOptions()
113    setl bt=nofile
114    NetrwKeepj file NetrwMessage
115"    call Decho("setl ma noro",'~'.expand("<slnum>"))
116    setl ma noro
117    if type(a:msg) == 3
118     for msg in a:msg
119      NetrwKeepj call setline(line("$")+1,level.msg)
120     endfor
121    else
122     NetrwKeepj call setline(line("$"),level.a:msg)
123    endif
124    NetrwKeepj $
125   endif
126"   call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr(),'~'.expand("<slnum>"))
127   if &fo !~ '[ta]'
128    syn clear
129    syn match netrwMesgNote	"^\*\*note\*\*"
130    syn match netrwMesgWarning	"^\*\*warning\*\*"
131    syn match netrwMesgError	"^\*\*error\*\*"
132    hi link netrwMesgWarning WarningMsg
133    hi link netrwMesgError   Error
134   endif
135"   call Decho("setl noma ro bh=wipe",'~'.expand("<slnum>"))
136   setl ro nomod noma bh=wipe
137
138  else
139   " (optional) netrw will show messages using echomsg.  Even if the
140   " message doesn't appear, at least it'll be recallable via :messages
141"   redraw!
142   if a:level == s:WARNING
143    echohl WarningMsg
144   elseif a:level == s:ERROR
145    echohl Error
146   endif
147
148   if type(a:msg) == 3
149     for msg in a:msg
150      unsilent echomsg level.msg
151     endfor
152   else
153    unsilent echomsg level.a:msg
154   endif
155
156"   call Decho("echomsg ***netrw*** ".a:msg,'~'.expand("<slnum>"))
157   echohl None
158  endif
159
160"  call Dret("netrw#ErrorMsg")
161endfun
162
163" ---------------------------------------------------------------------
164" s:NetrwInit: initializes variables if they haven't been defined {{{2
165"            Loosely,  varname = value.
166fun s:NetrwInit(varname,value)
167" call Decho("varname<".a:varname."> value=".a:value,'~'.expand("<slnum>"))
168  if !exists(a:varname)
169   if type(a:value) == 0
170    exe "let ".a:varname."=".a:value
171   elseif type(a:value) == 1 && a:value =~ '^[{[]'
172    exe "let ".a:varname."=".a:value
173   elseif type(a:value) == 1
174    exe "let ".a:varname."="."'".a:value."'"
175   else
176    exe "let ".a:varname."=".a:value
177   endif
178  endif
179endfun
180
181" ---------------------------------------------------------------------
182"  Netrw Constants: {{{2
183call s:NetrwInit("g:netrw_dirhist_cnt",0)
184if !exists("s:LONGLIST")
185 call s:NetrwInit("s:THINLIST",0)
186 call s:NetrwInit("s:LONGLIST",1)
187 call s:NetrwInit("s:WIDELIST",2)
188 call s:NetrwInit("s:TREELIST",3)
189 call s:NetrwInit("s:MAXLIST" ,4)
190endif
191
192" ---------------------------------------------------------------------
193" Default option values: {{{2
194let g:netrw_localcopycmdopt    = ""
195let g:netrw_localcopydircmdopt = ""
196let g:netrw_localmkdiropt      = ""
197let g:netrw_localmovecmdopt    = ""
198let g:netrw_localrmdiropt      = ""
199
200" ---------------------------------------------------------------------
201" Default values for netrw's global protocol variables {{{2
202call s:NetrwInit("g:netrw_use_errorwindow",1)
203
204if !exists("g:netrw_dav_cmd")
205 if executable("cadaver")
206  let g:netrw_dav_cmd	= "cadaver"
207 elseif executable("curl")
208  let g:netrw_dav_cmd	= "curl"
209 else
210  let g:netrw_dav_cmd   = ""
211 endif
212endif
213if !exists("g:netrw_fetch_cmd")
214 if executable("fetch")
215  let g:netrw_fetch_cmd	= "fetch -o"
216 else
217  let g:netrw_fetch_cmd	= ""
218 endif
219endif
220if !exists("g:netrw_file_cmd")
221 if executable("elinks")
222  call s:NetrwInit("g:netrw_file_cmd","elinks")
223 elseif executable("links")
224  call s:NetrwInit("g:netrw_file_cmd","links")
225 endif
226endif
227if !exists("g:netrw_ftp_cmd")
228  let g:netrw_ftp_cmd	= "ftp"
229endif
230let s:netrw_ftp_cmd= g:netrw_ftp_cmd
231if !exists("g:netrw_ftp_options")
232 let g:netrw_ftp_options= "-i -n"
233endif
234if !exists("g:netrw_http_cmd")
235 if executable("curl")
236  let g:netrw_http_cmd	= "curl"
237  call s:NetrwInit("g:netrw_http_xcmd","-L -o")
238 elseif executable("wget")
239  let g:netrw_http_cmd	= "wget"
240  call s:NetrwInit("g:netrw_http_xcmd","-q -O")
241 elseif executable("elinks")
242  let g:netrw_http_cmd = "elinks"
243  call s:NetrwInit("g:netrw_http_xcmd","-source >")
244 elseif executable("fetch")
245  let g:netrw_http_cmd	= "fetch"
246  call s:NetrwInit("g:netrw_http_xcmd","-o")
247 elseif executable("links")
248  let g:netrw_http_cmd = "links"
249  call s:NetrwInit("g:netrw_http_xcmd","-http.extra-header ".shellescape("Accept-Encoding: identity", 1)." -source >")
250 else
251  let g:netrw_http_cmd	= ""
252 endif
253endif
254call s:NetrwInit("g:netrw_http_put_cmd","curl -T")
255call s:NetrwInit("g:netrw_keepj","keepj")
256call s:NetrwInit("g:netrw_rcp_cmd"  , "rcp")
257call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
258call s:NetrwInit("g:netrw_rsync_sep", "/")
259if !exists("g:netrw_scp_cmd")
260 if executable("scp")
261  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
262 elseif executable("pscp")
263  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable('c:\private.ppk')
264   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -i c:\private.ppk')
265  else
266   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
267  endif
268 else
269  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
270 endif
271endif
272
273call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
274call s:NetrwInit("g:netrw_ssh_cmd"  , "ssh")
275
276if (has("win32") || has("win95") || has("win64") || has("win16"))
277  \ && exists("g:netrw_use_nt_rcp")
278  \ && g:netrw_use_nt_rcp
279  \ && executable( $SystemRoot .'/system32/rcp.exe')
280 let s:netrw_has_nt_rcp = 1
281 let s:netrw_rcpmode    = '-b'
282else
283 let s:netrw_has_nt_rcp = 0
284 let s:netrw_rcpmode    = ''
285endif
286
287" ---------------------------------------------------------------------
288" Default values for netrw's global variables {{{2
289" Cygwin Detection ------- {{{3
290if !exists("g:netrw_cygwin")
291 if has("win32") || has("win95") || has("win64") || has("win16")
292  if  has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
293   let g:netrw_cygwin= 1
294  else
295   let g:netrw_cygwin= 0
296  endif
297 else
298  let g:netrw_cygwin= 0
299 endif
300endif
301" Default values - a-c ---------- {{{3
302call s:NetrwInit("g:netrw_alto"        , &sb)
303call s:NetrwInit("g:netrw_altv"        , &spr)
304call s:NetrwInit("g:netrw_banner"      , 1)
305call s:NetrwInit("g:netrw_browse_split", 0)
306call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro nornu")
307call s:NetrwInit("g:netrw_chgwin"      , -1)
308call s:NetrwInit("g:netrw_compress"    , "gzip")
309call s:NetrwInit("g:netrw_ctags"       , "ctags")
310if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
311 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
312 let g:netrw_cursor= g:netrw_cursorline
313endif
314call s:NetrwInit("g:netrw_cursor"      , 2)
315let s:netrw_usercul = &cursorline
316let s:netrw_usercuc = &cursorcolumn
317call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
318" Default values - d-g ---------- {{{3
319call s:NetrwInit("s:didstarstar",0)
320call s:NetrwInit("g:netrw_dirhist_cnt"      , 0)
321call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }')
322call s:NetrwInit("g:netrw_dirhistmax"       , 10)
323call s:NetrwInit("g:netrw_errorlvl"  , s:NOTE)
324call s:NetrwInit("g:netrw_fastbrowse"       , 1)
325call 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$')
326if !exists("g:netrw_ftp_list_cmd")
327 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
328  let g:netrw_ftp_list_cmd     = "ls -lF"
329  let g:netrw_ftp_timelist_cmd = "ls -tlF"
330  let g:netrw_ftp_sizelist_cmd = "ls -slF"
331 else
332  let g:netrw_ftp_list_cmd     = "dir"
333  let g:netrw_ftp_timelist_cmd = "dir"
334  let g:netrw_ftp_sizelist_cmd = "dir"
335 endif
336endif
337call s:NetrwInit("g:netrw_ftpmode",'binary')
338" Default values - h-lh ---------- {{{3
339call s:NetrwInit("g:netrw_hide",1)
340if !exists("g:netrw_ignorenetrc")
341 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
342  let g:netrw_ignorenetrc= 1
343 else
344  let g:netrw_ignorenetrc= 0
345 endif
346endif
347call s:NetrwInit("g:netrw_keepdir",1)
348if !exists("g:netrw_list_cmd")
349 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
350  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
351   " provide a pscp-based listing command
352   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
353  endif
354  if exists("g:netrw_list_cmd_options")
355   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
356  else
357   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
358  endif
359 elseif executable(g:netrw_ssh_cmd)
360  " provide a scp-based default listing command
361  if exists("g:netrw_list_cmd_options")
362   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
363  else
364   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
365  endif
366 else
367"  call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
368  let g:netrw_list_cmd= ""
369 endif
370endif
371call s:NetrwInit("g:netrw_list_hide","")
372" Default values - lh-lz ---------- {{{3
373if exists("g:netrw_local_copycmd")
374 let g:netrw_localcopycmd= g:netrw_local_copycmd
375 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_copycmd is deprecated in favor of g:netrw_localcopycmd",84)
376endif
377if !exists("g:netrw_localcmdshell")
378 let g:netrw_localcmdshell= ""
379endif
380if !exists("g:netrw_localcopycmd")
381 if has("win32") || has("win95") || has("win64") || has("win16")
382  if g:netrw_cygwin
383   let g:netrw_localcopycmd= "cp"
384  else
385   let g:netrw_localcopycmd   = expand("$COMSPEC")
386   let g:netrw_localcopycmdopt= " /c copy"
387  endif
388 elseif has("unix") || has("macunix")
389  let g:netrw_localcopycmd= "cp"
390 else
391  let g:netrw_localcopycmd= ""
392 endif
393endif
394if !exists("g:netrw_localcopydircmd")
395 if has("win32") || has("win95") || has("win64") || has("win16")
396  if g:netrw_cygwin
397   let g:netrw_localcopydircmd   = "cp"
398   let g:netrw_localcopydircmdopt= " -R"
399  else
400   let g:netrw_localcopydircmd   = expand("$COMSPEC")
401   let g:netrw_localcopydircmdopt= " /c xcopy /e /c /h /i /k"
402  endif
403 elseif has("unix")
404  let g:netrw_localcopydircmd   = "cp"
405  let g:netrw_localcopydircmdopt= " -R"
406 elseif has("macunix")
407  let g:netrw_localcopydircmd   = "cp"
408  let g:netrw_localcopydircmdopt= " -R"
409 else
410  let g:netrw_localcopydircmd= ""
411 endif
412endif
413if exists("g:netrw_local_mkdir")
414 let g:netrw_localmkdir= g:netrw_local_mkdir
415 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
416endif
417if has("win32") || has("win95") || has("win64") || has("win16")
418  if g:netrw_cygwin
419   call s:NetrwInit("g:netrw_localmkdir","mkdir")
420  else
421   let g:netrw_localmkdir   = expand("$COMSPEC")
422   let g:netrw_localmkdiropt= " /c mkdir"
423  endif
424else
425 call s:NetrwInit("g:netrw_localmkdir","mkdir")
426endif
427call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
428if exists("g:netrw_local_movecmd")
429 let g:netrw_localmovecmd= g:netrw_local_movecmd
430 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
431endif
432if !exists("g:netrw_localmovecmd")
433 if has("win32") || has("win95") || has("win64") || has("win16")
434  if g:netrw_cygwin
435   let g:netrw_localmovecmd= "mv"
436  else
437   let g:netrw_localmovecmd   = expand("$COMSPEC")
438   let g:netrw_localmovecmdopt= " /c move"
439  endif
440 elseif has("unix") || has("macunix")
441  let g:netrw_localmovecmd= "mv"
442 else
443  let g:netrw_localmovecmd= ""
444 endif
445endif
446if v:version < 704 || (v:version == 704 && !has("patch1107"))
447 " 1109 provides for delete(tmpdir,"d") which is what will be used
448 if exists("g:netrw_local_rmdir")
449  let g:netrw_localrmdir= g:netrw_local_rmdir
450  call netrw#ErrorMsg(s:NOTE,"g:netrw_local_rmdir is deprecated in favor of g:netrw_localrmdir",86)
451 endif
452 if has("win32") || has("win95") || has("win64") || has("win16")
453   if g:netrw_cygwin
454    call s:NetrwInit("g:netrw_localrmdir","rmdir")
455   else
456    let g:netrw_localrmdir   = expand("$COMSPEC")
457    let g:netrw_localrmdiropt= " /c rmdir"
458   endif
459 else
460  call s:NetrwInit("g:netrw_localrmdir","rmdir")
461 endif
462endif
463call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
464" sanity checks
465if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
466 let g:netrw_liststyle= s:THINLIST
467endif
468if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
469 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
470endif
471" Default values - m-r ---------- {{{3
472call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
473call s:NetrwInit("g:netrw_maxfilenamelen", 32)
474call s:NetrwInit("g:netrw_menu"          , 1)
475call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
476call s:NetrwInit("g:netrw_mousemaps"     , (exists("+mouse") && &mouse =~# '[anh]'))
477call s:NetrwInit("g:netrw_retmap"        , 0)
478if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
479 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
480elseif has("win32") || has("win95") || has("win64") || has("win16")
481 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
482else
483 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
484endif
485call s:NetrwInit("g:netrw_preview"       , 0)
486call s:NetrwInit("g:netrw_scpport"       , "-P")
487call s:NetrwInit("g:netrw_servername"    , "NETRWSERVER")
488call s:NetrwInit("g:netrw_sshport"       , "-p")
489call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
490call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
491call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
492call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
493" Default values - q-s ---------- {{{3
494call s:NetrwInit("g:netrw_quickhelp",0)
495let s:QuickHelp= ["-:go up dir  D:delete  R:rename  s:sort-by  x:special",
496   \              "(create new)  %:file  d:directory",
497   \              "(windows split&open) o:horz  v:vert  p:preview",
498   \              "i:style  qf:file info  O:obtain  r:reverse",
499   \              "(marks)  mf:mark file  mt:set target  mm:move  mc:copy",
500   \              "(bookmarks)  mb:make  mB:delete  qb:list  gb:go to",
501   \              "(history)  qb:list  u:go up  U:go down",
502   \              "(targets)  mt:target Tb:use bookmark  Th:use history"]
503" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
504call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
505if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
506 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
507else
508 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
509endif
510call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
511call s:NetrwInit("g:netrw_sort_options"  , "")
512call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
513if !exists("g:netrw_sort_sequence")
514 if has("unix")
515  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
516 else
517  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
518 endif
519endif
520call s:NetrwInit("g:netrw_special_syntax"   , 0)
521call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
522call s:NetrwInit("g:netrw_suppress_gx_mesg",  1)
523call s:NetrwInit("g:netrw_use_noswf"        , 1)
524call s:NetrwInit("g:netrw_sizestyle"        ,"b")
525" Default values - t-w ---------- {{{3
526call s:NetrwInit("g:netrw_timefmt","%c")
527if !exists("g:netrw_xstrlen")
528 if exists("g:Align_xstrlen")
529  let g:netrw_xstrlen= g:Align_xstrlen
530 elseif exists("g:drawit_xstrlen")
531  let g:netrw_xstrlen= g:drawit_xstrlen
532 elseif &enc == "latin1" || !has("multi_byte")
533  let g:netrw_xstrlen= 0
534 else
535  let g:netrw_xstrlen= 1
536 endif
537endif
538call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
539call s:NetrwInit("g:netrw_win95ftp",1)
540call s:NetrwInit("g:netrw_winsize",50)
541call s:NetrwInit("g:netrw_wiw",1)
542if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
543" ---------------------------------------------------------------------
544" Default values for netrw's script variables: {{{2
545call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
546if has("win32") || has("win95") || has("win64") || has("win16")
547 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
548else
549 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
550endif
551call s:NetrwInit("g:netrw_menu_escape",'.&? \')
552call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
553call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
554if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
555 let s:treedepthstring= "│ "
556else
557 let s:treedepthstring= "| "
558endif
559call s:NetrwInit("s:netrw_posn",'{}')
560
561" BufEnter event ignored by decho when following variable is true
562"  Has a side effect that doau BufReadPost doesn't work, so
563"  files read by network transfer aren't appropriately highlighted.
564"let g:decho_bufenter = 1	"Decho
565
566" ======================
567"  Netrw Initialization: {{{1
568" ======================
569if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
570" call Decho("installed beval events",'~'.expand("<slnum>"))
571 let &l:bexpr = "netrw#BalloonHelp()"
572 au FileType netrw	setl beval
573 au WinLeave *		if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
574 au VimEnter * 		let s:initbeval= &beval
575"else " Decho
576" if v:version < 700           | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>"))     | endif
577" if !has("balloon_eval")      | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>"))        | endif
578" if exists("s:initbeval")     | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>"))                | endif
579" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>"))            | endif
580" if !has("syntax")            | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
581" if exists("g:syntax_on")     | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>"))                | endif
582endif
583au WinEnter *	if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
584
585if g:netrw_keepj =~# "keepj"
586 com! -nargs=*	NetrwKeepj	keepj <args>
587else
588 let g:netrw_keepj= ""
589 com! -nargs=*	NetrwKeepj	<args>
590endif
591
592" ==============================
593"  Netrw Utility Functions: {{{1
594" ==============================
595
596" ---------------------------------------------------------------------
597" netrw#BalloonHelp: {{{2
598if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
599" call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
600 fun! netrw#BalloonHelp()
601   if &ft != "netrw"
602    return ""
603   endif
604   if !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
605    let mesg= ""
606   elseif     v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
607    let mesg = "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
608   elseif     getline(v:beval_lnum) =~ '^"\s*/'
609    let mesg = "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
610   elseif     v:beval_text == "Sorted" || v:beval_text == "by"
611    let mesg = 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
612   elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
613    let mesg = "S: edit sorting sequence"
614   elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
615    let mesg = "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
616   elseif v:beval_text == "Quick" || v:beval_text == "Help"
617    let mesg = "Help: press <F1>"
618   elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
619    let mesg = "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
620   else
621    let mesg= ""
622   endif
623   return mesg
624 endfun
625"else " Decho
626" if v:version < 700            |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
627" if !has("balloon_eval")       |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>"))       |endif
628" if !has("syntax")             |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>"))                  |endif
629" if !exists("g:syntax_on")     |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>"))                  |endif
630" if  exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>"))           |endif
631endif
632
633" ------------------------------------------------------------------------
634" netrw#Explore: launch the local browser in the directory of the current file {{{2
635"          indx:  == -1: Nexplore
636"                 == -2: Pexplore
637"                 ==  +: this is overloaded:
638"                      * If Nexplore/Pexplore is in use, then this refers to the
639"                        indx'th item in the w:netrw_explore_list[] of items which
640"                        matched the */pattern **/pattern *//pattern **//pattern
641"                      * If Hexplore or Vexplore, then this will override
642"                        g:netrw_winsize to specify the qty of rows or columns the
643"                        newly split window should have.
644"          dosplit==0: the window will be split iff the current file has been modified and hidden not set
645"          dosplit==1: the window will be split before running the local browser
646"          style == 0: Explore     style == 1: Explore!
647"                == 2: Hexplore    style == 3: Hexplore!
648"                == 4: Vexplore    style == 5: Vexplore!
649"                == 6: Texplore
650fun! netrw#Explore(indx,dosplit,style,...)
651"  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)
652"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
653  if !exists("b:netrw_curdir")
654   let b:netrw_curdir= getcwd()
655"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
656  endif
657
658  " record current file for Rexplore's benefit
659  if &ft != "netrw"
660   let w:netrw_rexfile= expand("%:p")
661  endif
662
663  " record current directory
664  let curdir     = simplify(b:netrw_curdir)
665  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
666  if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
667   let curdir= substitute(curdir,'\','/','g')
668  endif
669"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">",'~'.expand("<slnum>"))
670
671  " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
672  " will end up with backslashes here.  Solution: strip off backslashes that precede white space and
673  " try Explore again.
674  if a:0 > 0
675"   call Decho('considering retry: a:1<'.a:1.'>: '.
676     \ ((a:1 =~ "\\\s")?                   'has backslash whitespace' : 'does not have backslash whitespace').', '.
677     \ ((filereadable(s:NetrwFile(a:1)))?  'is readable'              : 'is not readable').', '.
678     \ ((isdirectory(s:NetrwFile(a:1))))?  'is a directory'           : 'is not a directory',
679     \ '~'.expand("<slnum>"))
680   if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
681"    call Decho("re-trying Explore with <".substitute(a:1,'\\\(\s\)','\1','g').">",'~'.expand("<slnum>"))
682    call netrw#Explore(a:indx,a:dosplit,a:style,substitute(a:1,'\\\(\s\)','\1','g'))
683"    call Dret("netrw#Explore : returning from retry")
684    return
685"   else " Decho
686"    call Decho("retry not needed",'~'.expand("<slnum>"))
687   endif
688  endif
689
690  " save registers
691  if has("clipboard")
692   sil! let keepregstar = @*
693   sil! let keepregplus = @+
694  endif
695  sil! let keepregslash= @/
696
697  " if   dosplit
698  " -or- file has been modified AND file not hidden when abandoned
699  " -or- Texplore used
700  if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
701"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified",'~'.expand("<slnum>"))
702   call s:SaveWinVars()
703   let winsz= g:netrw_winsize
704   if a:indx > 0
705    let winsz= a:indx
706   endif
707
708   if a:style == 0      " Explore, Sexplore
709"    call Decho("style=0: Explore or Sexplore",'~'.expand("<slnum>"))
710    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
711    if winsz == 0|let winsz= ""|endif
712    exe "noswapfile ".winsz."wincmd s"
713"    call Decho("exe noswapfile ".winsz."wincmd s",'~'.expand("<slnum>"))
714
715   elseif a:style == 1  "Explore!, Sexplore!
716"    call Decho("style=1: Explore! or Sexplore!",'~'.expand("<slnum>"))
717    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
718    if winsz == 0|let winsz= ""|endif
719    exe "keepalt noswapfile ".winsz."wincmd v"
720"    call Decho("exe keepalt noswapfile ".winsz."wincmd v",'~'.expand("<slnum>"))
721
722   elseif a:style == 2  " Hexplore
723"    call Decho("style=2: Hexplore",'~'.expand("<slnum>"))
724    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
725    if winsz == 0|let winsz= ""|endif
726    exe "keepalt noswapfile bel ".winsz."wincmd s"
727"    call Decho("exe keepalt noswapfile bel ".winsz."wincmd s",'~'.expand("<slnum>"))
728
729   elseif a:style == 3  " Hexplore!
730"    call Decho("style=3: Hexplore!",'~'.expand("<slnum>"))
731    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
732    if winsz == 0|let winsz= ""|endif
733    exe "keepalt noswapfile abo ".winsz."wincmd s"
734"    call Decho("exe keepalt noswapfile abo ".winsz."wincmd s",'~'.expand("<slnum>"))
735
736   elseif a:style == 4  " Vexplore
737"    call Decho("style=4: Vexplore",'~'.expand("<slnum>"))
738    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
739    if winsz == 0|let winsz= ""|endif
740    exe "keepalt noswapfile lefta ".winsz."wincmd v"
741"    call Decho("exe keepalt noswapfile lefta ".winsz."wincmd v",'~'.expand("<slnum>"))
742
743   elseif a:style == 5  " Vexplore!
744"    call Decho("style=5: Vexplore!",'~'.expand("<slnum>"))
745    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
746    if winsz == 0|let winsz= ""|endif
747    exe "keepalt noswapfile rightb ".winsz."wincmd v"
748"    call Decho("exe keepalt noswapfile rightb ".winsz."wincmd v",'~'.expand("<slnum>"))
749
750   elseif a:style == 6  " Texplore
751    call s:SaveBufVars()
752"    call Decho("style  = 6: Texplore",'~'.expand("<slnum>"))
753    exe "keepalt tabnew ".fnameescape(curdir)
754"    call Decho("exe keepalt tabnew ".fnameescape(curdir),'~'.expand("<slnum>"))
755    call s:RestoreBufVars()
756   endif
757   call s:RestoreWinVars()
758"  else " Decho
759"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6",'~'.expand("<slnum>"))
760  endif
761  NetrwKeepj norm! 0
762
763  if a:0 > 0
764"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">",'~'.expand("<slnum>"))
765   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
766"    call Decho("..case a:1<".a:1.">: starts with ~ and unix or cygwin",'~'.expand("<slnum>"))
767    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
768"    call Decho("..using dirname<".dirname.">  (case: ~ && unix||cygwin)",'~'.expand("<slnum>"))
769   elseif a:1 == '.'
770"    call Decho("..case a:1<".a:1.">: matches .",'~'.expand("<slnum>"))
771    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
772    if dirname !~ '/$'
773     let dirname= dirname."/"
774    endif
775"    call Decho("..using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")",'~'.expand("<slnum>"))
776   elseif a:1 =~ '\$'
777"    call Decho("..case a:1<".a:1.">: matches ending $",'~'.expand("<slnum>"))
778    let dirname= simplify(expand(a:1))
779"    call Decho("..using user-specified dirname<".dirname."> with $env-var",'~'.expand("<slnum>"))
780   elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
781"    call Decho("..case a:1<".a:1.">: other, not pattern or filepattern",'~'.expand("<slnum>"))
782    let dirname= simplify(a:1)
783"    call Decho("..using user-specified dirname<".dirname.">",'~'.expand("<slnum>"))
784   else
785"    call Decho("..case a:1: pattern or filepattern",'~'.expand("<slnum>"))
786    let dirname= a:1
787   endif
788  else
789   " clear explore
790"   call Decho("case a:0=".a:0.": clearing Explore list",'~'.expand("<slnum>"))
791   call s:NetrwClearExplore()
792"   call Dret("netrw#Explore : cleared list")
793   return
794  endif
795
796"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
797  if dirname =~ '\.\./\=$'
798   let dirname= simplify(fnamemodify(dirname,':p:h'))
799  elseif dirname =~ '\.\.' || dirname == '.'
800   let dirname= simplify(fnamemodify(dirname,':p'))
801  endif
802"  call Decho("dirname<".dirname.">  (after simplify)",'~'.expand("<slnum>"))
803
804  if dirname =~ '^\*//'
805   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
806"   call Decho("case starpat=1: Explore *//pattern",'~'.expand("<slnum>"))
807   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
808   let starpat= 1
809"   call Decho("..Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
810   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
811
812  elseif dirname =~ '^\*\*//'
813   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
814"   call Decho("case starpat=2: Explore **//pattern",'~'.expand("<slnum>"))
815   let pattern= substitute(dirname,'^\*\*//','','')
816   let starpat= 2
817"   call Decho("..Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
818
819  elseif dirname =~ '/\*\*/'
820   " handle .../**/.../filepat
821"   call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
822   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
823   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
824    let b:netrw_curdir = prefixdir
825   else
826    let b:netrw_curdir= getcwd().'/'.prefixdir
827   endif
828   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
829   let starpat= 4
830"   call Decho("..pwd<".getcwd()."> dirname<".dirname.">",'~'.expand("<slnum>"))
831"   call Decho("..case Explore ../**/../filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
832
833  elseif dirname =~ '^\*/'
834   " case starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
835   let starpat= 3
836"   call Decho("case starpat=3: Explore */filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
837
838  elseif dirname=~ '^\*\*/'
839   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
840   let starpat= 4
841"   call Decho("case starpat=4: Explore **/filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
842
843  else
844   let starpat= 0
845"   call Decho("case starpat=0: default",'~'.expand("<slnum>"))
846  endif
847
848  if starpat == 0 && a:indx >= 0
849   " [Explore Hexplore Vexplore Sexplore] [dirname]
850"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname.">, handles Explore Hexplore Vexplore Sexplore",'~'.expand("<slnum>"))
851   if dirname == ""
852    let dirname= curfiledir
853"    call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>"))
854   endif
855   if dirname =~# '^scp://' || dirname =~ '^ftp://'
856    call netrw#Nread(2,dirname)
857   else
858    if dirname == ""
859     let dirname= getcwd()
860    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
861     " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
862     " depending on whether backslashes have been converted to forward slashes by earlier code).
863     if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
864      let dirname= b:netrw_curdir."/".dirname
865     endif
866    elseif dirname !~ '^/'
867     let dirname= b:netrw_curdir."/".dirname
868    endif
869"    call Decho("..calling LocalBrowseCheck(dirname<".dirname.">)",'~'.expand("<slnum>"))
870    call netrw#LocalBrowseCheck(dirname)
871"    call Decho(" modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
872"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
873   endif
874   if exists("w:netrw_bannercnt")
875    " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
876    " If one wants to return the same place in the netrw window, use :Rex instead.
877    exe w:netrw_bannercnt
878   endif
879
880"   call Decho("curdir<".curdir.">",'~'.expand("<slnum>"))
881   " ---------------------------------------------------------------------
882   " Jan 24, 2013: not sure why the following was present.  See P08-Ingelrest
883"   if has("win32") || has("win95") || has("win64") || has("win16")
884"    NetrwKeepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
885"   else
886"    NetrwKeepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
887"   endif
888   " ---------------------------------------------------------------------
889
890  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
891  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
892  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
893  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
894  elseif a:indx <= 0
895   " Nexplore, Pexplore, Explore: handle starpat
896"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx,'~'.expand("<slnum>"))
897   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
898"    call Decho("..set up <s-up> and <s-down> maps",'~'.expand("<slnum>"))
899    let s:didstarstar= 1
900    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
901    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
902   endif
903
904   if has("path_extra")
905"    call Decho("..starpat=".starpat.": has +path_extra",'~'.expand("<slnum>"))
906    if !exists("w:netrw_explore_indx")
907     let w:netrw_explore_indx= 0
908    endif
909
910    let indx = a:indx
911"    call Decho("..starpat=".starpat.": set indx= [a:indx=".indx."]",'~'.expand("<slnum>"))
912
913    if indx == -1
914     " Nexplore
915"     call Decho("..case Nexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
916     if !exists("w:netrw_explore_list") " sanity check
917      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
918      if has("clipboard")
919       sil! let @* = keepregstar
920       sil! let @+ = keepregplus
921      endif
922      sil! let @/ = keepregslash
923"      call Dret("netrw#Explore")
924      return
925     endif
926     let indx= w:netrw_explore_indx
927     if indx < 0                        | let indx= 0                           | endif
928     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
929     let curfile= w:netrw_explore_list[indx]
930"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
931     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
932      let indx= indx + 1
933"      call Decho("....indx=".indx." (Nexplore while loop)",'~'.expand("<slnum>"))
934     endwhile
935     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
936"     call Decho("....Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
937
938    elseif indx == -2
939     " Pexplore
940"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
941     if !exists("w:netrw_explore_list") " sanity check
942      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
943      if has("clipboard")
944       sil! let @* = keepregstar
945       sil! let @+ = keepregplus
946      endif
947      sil! let @/ = keepregslash
948"      call Dret("netrw#Explore")
949      return
950     endif
951     let indx= w:netrw_explore_indx
952     if indx < 0                        | let indx= 0                           | endif
953     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
954     let curfile= w:netrw_explore_list[indx]
955"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
956     while indx >= 0 && curfile == w:netrw_explore_list[indx]
957      let indx= indx - 1
958"      call Decho("....indx=".indx." (Pexplore while loop)",'~'.expand("<slnum>"))
959     endwhile
960     if indx < 0                        | let indx= 0                           | endif
961"     call Decho("....Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
962
963    else
964     " Explore -- initialize
965     " build list of files to Explore with Nexplore/Pexplore
966"     call Decho("..starpat=".starpat.": case Explore: initialize (indx=".indx.")",'~'.expand("<slnum>"))
967     NetrwKeepj keepalt call s:NetrwClearExplore()
968     let w:netrw_explore_indx= 0
969     if !exists("b:netrw_curdir")
970      let b:netrw_curdir= getcwd()
971     endif
972"     call Decho("....starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
973
974     " switch on starpat to build the w:netrw_explore_list of files
975     if starpat == 1
976      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
977"      call Decho("..case starpat=".starpat.": build *//pattern list  (curdir-only srch for files containing pattern)  &hls=".&hls,'~'.expand("<slnum>"))
978"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
979      try
980       exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
981      catch /^Vim\%((\a\+)\)\=:E480/
982       keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
983"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
984       return
985      endtry
986      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
987      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
988
989     elseif starpat == 2
990      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
991"      call Decho("..case starpat=".starpat.": build **//pattern list  (recursive descent files containing pattern)",'~'.expand("<slnum>"))
992"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
993      try
994       exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
995      catch /^Vim\%((\a\+)\)\=:E480/
996       keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
997       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
998       if has("clipboard")
999	sil! let @* = keepregstar
1000	sil! let @+ = keepregplus
1001       endif
1002       sil! let @/ = keepregslash
1003"       call Dret("netrw#Explore : no files matched pattern")
1004       return
1005      endtry
1006      let s:netrw_curdir       = b:netrw_curdir
1007      let w:netrw_explore_list = getqflist()
1008      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
1009      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1010
1011     elseif starpat == 3
1012      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
1013"      call Decho("..case starpat=".starpat.": build */filepat list  (curdir-only srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1014      let filepat= substitute(dirname,'^\*/','','')
1015      let filepat= substitute(filepat,'^[%#<]','\\&','')
1016"      call Decho("....b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
1017"      call Decho("....filepat<".filepat.">",'~'.expand("<slnum>"))
1018      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
1019      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
1020
1021     elseif starpat == 4
1022      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
1023"      call Decho("..case starpat=".starpat.": build **/filepat list  (recursive descent srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
1024      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
1025      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
1026     endif " switch on starpat to build w:netrw_explore_list
1027
1028     let w:netrw_explore_listlen = len(w:netrw_explore_list)
1029"     call Decho("....w:netrw_explore_list<".string(w:netrw_explore_list).">",'~'.expand("<slnum>"))
1030"     call Decho("....w:netrw_explore_listlen=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1031
1032     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1033      keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1034      if has("clipboard")
1035       sil! let @* = keepregstar
1036       sil! let @+ = keepregplus
1037      endif
1038      sil! let @/ = keepregslash
1039"      call Dret("netrw#Explore : no files matched")
1040      return
1041     endif
1042    endif  " if indx ... endif
1043
1044    " NetrwStatusLine support - for exploring support
1045    let w:netrw_explore_indx= indx
1046"    call Decho("....w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1047
1048    " wrap the indx around, but issue a note
1049    if indx >= w:netrw_explore_listlen || indx < 0
1050"     call Decho("....wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")",'~'.expand("<slnum>"))
1051     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1052     let w:netrw_explore_indx= indx
1053     keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
1054    endif
1055
1056    exe "let dirfile= w:netrw_explore_list[".indx."]"
1057"    call Decho("....dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">",'~'.expand("<slnum>"))
1058    let newdir= substitute(dirfile,'/[^/]*$','','e')
1059"    call Decho("....newdir<".newdir.">",'~'.expand("<slnum>"))
1060
1061"    call Decho("....calling LocalBrowseCheck(newdir<".newdir.">)",'~'.expand("<slnum>"))
1062    call netrw#LocalBrowseCheck(newdir)
1063    if !exists("w:netrw_liststyle")
1064     let w:netrw_liststyle= g:netrw_liststyle
1065    endif
1066    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1067     keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1068    else
1069     keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1070    endif
1071    let w:netrw_explore_mtchcnt = indx + 1
1072    let w:netrw_explore_bufnr   = bufnr("%")
1073    let w:netrw_explore_line    = line(".")
1074    keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
1075"    call Decho("....explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line,'~'.expand("<slnum>"))
1076
1077   else
1078"    call Decho("..your vim does not have +path_extra",'~'.expand("<slnum>"))
1079    if !exists("g:netrw_quiet")
1080     keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1081    endif
1082    if has("clipboard")
1083     sil! let @* = keepregstar
1084     sil! let @+ = keepregplus
1085    endif
1086    sil! let @/ = keepregslash
1087"    call Dret("netrw#Explore : missing +path_extra")
1088    return
1089   endif
1090
1091  else
1092"   call Decho("..default case: Explore newdir<".dirname.">",'~'.expand("<slnum>"))
1093   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1094    sil! unlet w:netrw_treedict
1095    sil! unlet w:netrw_treetop
1096   endif
1097   let newdir= dirname
1098   if !exists("b:netrw_curdir")
1099    NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1100   else
1101    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
1102   endif
1103  endif
1104
1105  " visual display of **/ **// */ Exploration files
1106"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"),'~'.expand("<slnum>"))
1107"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">",'~'.expand("<slnum>"))
1108  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
1109"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"),'~'.expand("<slnum>"))
1110   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1111    " only update match list when current directory isn't the same as before
1112"    call Decho("only update match list when current directory not the same as before",'~'.expand("<slnum>"))
1113    let s:explore_prvdir = b:netrw_curdir
1114    let s:explore_match  = ""
1115    let dirlen           = strlen(b:netrw_curdir)
1116    if b:netrw_curdir !~ '/$'
1117     let dirlen= dirlen + 1
1118    endif
1119    let prvfname= ""
1120    for fname in w:netrw_explore_list
1121"     call Decho("fname<".fname.">",'~'.expand("<slnum>"))
1122     if fname =~ '^'.b:netrw_curdir
1123      if s:explore_match == ""
1124       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1125      else
1126       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1127      endif
1128     elseif fname !~ '^/' && fname != prvfname
1129      if s:explore_match == ""
1130       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1131      else
1132       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1133      endif
1134     endif
1135     let prvfname= fname
1136    endfor
1137"    call Decho("explore_match<".s:explore_match.">",'~'.expand("<slnum>"))
1138    if has("syntax") && exists("g:syntax_on") && g:syntax_on
1139     exe "2match netrwMarkFile /".s:explore_match."/"
1140    endif
1141   endif
1142   echo "<s-up>==Pexplore  <s-down>==Nexplore"
1143  else
1144   2match none
1145   if exists("s:explore_match")  | unlet s:explore_match  | endif
1146   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
1147   echo " "
1148"   call Decho("cleared explore match list",'~'.expand("<slnum>"))
1149  endif
1150
1151  " since Explore may be used to initialize netrw's browser,
1152  " there's no danger of a late FocusGained event on initialization.
1153  " Consequently, set s:netrw_events to 2.
1154  let s:netrw_events= 2
1155  if has("clipboard")
1156   sil! let @* = keepregstar
1157   sil! let @+ = keepregplus
1158  endif
1159  sil! let @/ = keepregslash
1160"  call Dret("netrw#Explore : @/<".@/.">")
1161endfun
1162
1163" ---------------------------------------------------------------------
1164" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
1165fun! netrw#Lexplore(count,rightside,...)
1166"  call Dfunc("netrw#Lexplore(count=".a:count." rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
1167  let curwin= winnr()
1168
1169  if a:0 > 0 && a:1 != ""
1170   " if a netrw window is already on the left-side of the tab
1171   " and a directory has been specified, explore with that
1172   " directory.
1173"   call Decho("case has input argument(s) (a:1<".a:1.">)")
1174   let a1 = expand(a:1)
1175"   call Decho("a:1<".a:1.">  curwin#".curwin,'~'.expand("<slnum>"))
1176   exe "1wincmd w"
1177   if &ft == "netrw"
1178"    call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
1179    exe "Explore ".fnameescape(a1)
1180    exe curwin."wincmd w"
1181    if exists("t:netrw_lexposn")
1182"     call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
1183     unlet t:netrw_lexposn
1184    endif
1185"    call Dret("netrw#Lexplore")
1186    return
1187   endif
1188   exe curwin."wincmd w"
1189  else
1190   let a1= ""
1191"   call Decho("no input arguments")
1192  endif
1193
1194  if exists("t:netrw_lexbufnr")
1195   " check if t:netrw_lexbufnr refers to a netrw window
1196   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1197"   call Decho("lexwinnr= bufwinnr(t:netrw_lexbufnr#".t:netrw_lexbufnr.")=".lexwinnr)
1198  else
1199   let lexwinnr= 0
1200"   call Decho("t:netrw_lexbufnr doesn't exist")
1201  endif
1202"  call Decho("lexwinnr=".lexwinnr,'~'.expand("<slnum>"))
1203
1204  if lexwinnr > 0
1205   " close down netrw explorer window
1206"   call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
1207   exe lexwinnr."wincmd w"
1208   let g:netrw_winsize = -winwidth(0)
1209   let t:netrw_lexposn = winsaveview()
1210"   call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1211"   call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
1212   close
1213   if lexwinnr < curwin
1214    let curwin= curwin - 1
1215   endif
1216   if lexwinnr != curwin
1217    exe curwin."wincmd w"
1218   endif
1219   unlet t:netrw_lexbufnr
1220"   call Decho("unlet t:netrw_lexbufnr")
1221
1222  else
1223   " open netrw explorer window
1224"   call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
1225   exe "1wincmd w"
1226   let keep_altv    = g:netrw_altv
1227   let g:netrw_altv = 0
1228   if a:count != 0
1229    let netrw_winsize   = g:netrw_winsize
1230    let g:netrw_winsize = a:count
1231   endif
1232   let curfile= expand("%")
1233"   call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
1234   exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1235"   call Decho("new buf#".bufnr("%")." win#".winnr())
1236   if a:0 > 0 && a1 != ""
1237"    call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
1238    call netrw#Explore(0,0,0,a1)
1239    exe "Explore ".fnameescape(a1)
1240   elseif curfile =~ '^\a\{3,}://'
1241"    call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
1242    call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
1243   else
1244"    call Decho("case 3: Explore .",'~'.expand("<slnum>"))
1245    call netrw#Explore(0,0,0,".")
1246   endif
1247   if a:count != 0
1248    let g:netrw_winsize = netrw_winsize
1249   endif
1250   setlocal winfixwidth
1251   let g:netrw_altv     = keep_altv
1252   let t:netrw_lexbufnr = bufnr("%")
1253"   call Decho("let t:netrw_lexbufnr=".t:netrw_lexbufnr)
1254"   call Decho("t:netrw_lexposn".(exists("t:netrw_lexposn")? string(t:netrw_lexposn) : " n/a"))
1255   if exists("t:netrw_lexposn")
1256"    call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1257"    call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1258    call winrestview(t:netrw_lexposn)
1259    unlet t:netrw_lexposn
1260   endif
1261  endif
1262
1263  " set up default window for editing via <cr>
1264  if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
1265   if a:rightside
1266    let g:netrw_chgwin= 1
1267   else
1268    let g:netrw_chgwin= 2
1269   endif
1270"   call Decho("let g:netrw_chgwin=".g:netrw_chgwin)
1271  endif
1272
1273"  call Dret("netrw#Lexplore")
1274endfun
1275
1276" ---------------------------------------------------------------------
1277" netrw#Clean: remove netrw {{{2
1278" supports :NetrwClean  -- remove netrw from first directory on runtimepath
1279"          :NetrwClean! -- remove netrw from all directories on runtimepath
1280fun! netrw#Clean(sys)
1281"  call Dfunc("netrw#Clean(sys=".a:sys.")")
1282
1283  if a:sys
1284   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
1285  else
1286   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
1287  endif
1288"  call Decho("choice=".choice,'~'.expand("<slnum>"))
1289  let diddel= 0
1290  let diddir= ""
1291
1292  if choice == 1
1293   for dir in split(&rtp,',')
1294    if filereadable(dir."/plugin/netrwPlugin.vim")
1295"     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1296     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
1297     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1298     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
1299     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
1300     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
1301     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
1302     let diddir= dir
1303     let diddel= diddel + 1
1304     if !a:sys|break|endif
1305    endif
1306   endfor
1307  endif
1308
1309   echohl WarningMsg
1310  if diddel == 0
1311   echomsg "netrw is either not installed or not removable"
1312  elseif diddel == 1
1313   echomsg "removed one copy of netrw from <".diddir.">"
1314  else
1315   echomsg "removed ".diddel." copies of netrw"
1316  endif
1317   echohl None
1318
1319"  call Dret("netrw#Clean")
1320endfun
1321
1322" ---------------------------------------------------------------------
1323" netrw#MakeTgt: make a target out of the directory name provided {{{2
1324fun! netrw#MakeTgt(dname)
1325"  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1326   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
1327  let svpos               = winsaveview()
1328"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1329  let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
1330"  call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
1331  if s:netrwmftgt_islocal
1332   let netrwmftgt= simplify(a:dname)
1333  else
1334   let netrwmftgt= a:dname
1335  endif
1336  if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
1337   " re-selected target, so just clear it
1338   unlet s:netrwmftgt s:netrwmftgt_islocal
1339  else
1340   let s:netrwmftgt= netrwmftgt
1341  endif
1342  if g:netrw_fastbrowse <= 1
1343   call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
1344  endif
1345"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
1346  call winrestview(svpos)
1347"  call Dret("netrw#MakeTgt")
1348endfun
1349
1350" ---------------------------------------------------------------------
1351" netrw#Obtain: {{{2
1352"   netrw#Obtain(islocal,fname[,tgtdirectory])
1353"     islocal=0  obtain from remote source
1354"            =1  obtain from local source
1355"     fname  :   a filename or a list of filenames
1356"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
1357fun! netrw#Obtain(islocal,fname,...)
1358"  call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
1359  " NetrwStatusLine support - for obtaining support
1360
1361  if type(a:fname) == 1
1362   let fnamelist= [ a:fname ]
1363  elseif type(a:fname) == 3
1364   let fnamelist= a:fname
1365  else
1366   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1367"   call Dret("netrw#Obtain")
1368   return
1369  endif
1370"  call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
1371  if a:0 > 0
1372   let tgtdir= a:1
1373  else
1374   let tgtdir= getcwd()
1375  endif
1376"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
1377
1378  if exists("b:netrw_islocal") && b:netrw_islocal
1379   " obtain a file from local b:netrw_curdir to (local) tgtdir
1380"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1381   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1382    let topath= s:ComposePath(tgtdir,"")
1383    if (has("win32") || has("win95") || has("win64") || has("win16"))
1384     " transfer files one at time
1385"     call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1386     for fname in fnamelist
1387"      call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1388      call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1389      if v:shell_error != 0
1390       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1391"       call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1392       return
1393      endif
1394     endfor
1395    else
1396     " transfer files with one command
1397"     call Decho("transfer files with one command",'~'.expand("<slnum>"))
1398     let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1399"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1400     call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".filelist." ".s:ShellEscape(topath))
1401     if v:shell_error != 0
1402      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1403"      call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1404      return
1405     endif
1406    endif
1407   elseif !exists("b:netrw_curdir")
1408    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
1409   else
1410    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
1411   endif
1412
1413  else
1414   " obtain files from remote b:netrw_curdir to local tgtdir
1415"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1416   if type(a:fname) == 1
1417    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
1418   endif
1419   call s:NetrwMethod(b:netrw_curdir)
1420
1421   if b:netrw_method == 4
1422    " obtain file using scp
1423"    call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1424    if exists("g:netrw_port") && g:netrw_port != ""
1425     let useport= " ".g:netrw_scpport." ".g:netrw_port
1426    else
1427     let useport= ""
1428    endif
1429    if b:netrw_fname =~ '/'
1430     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1431    else
1432     let path= ""
1433    endif
1434    let filelist= join(map(deepcopy(fnamelist),'escape(s:ShellEscape(g:netrw_machine.":".path.v:val,1)," ")'))
1435    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
1436
1437   elseif b:netrw_method == 2
1438    " obtain file using ftp + .netrc
1439"     call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1440     call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1441     let tmpbufnr= bufnr("%")
1442     setl ff=unix
1443     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1444      NetrwKeepj put =g:netrw_ftpmode
1445"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1446     endif
1447
1448     if exists("b:netrw_fname") && b:netrw_fname != ""
1449      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1450"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1451     endif
1452
1453     if exists("g:netrw_ftpextracmd")
1454      NetrwKeepj put =g:netrw_ftpextracmd
1455"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1456     endif
1457     for fname in fnamelist
1458      call setline(line("$")+1,'get "'.fname.'"')
1459"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1460     endfor
1461     if exists("g:netrw_port") && g:netrw_port != ""
1462      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1463     else
1464      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1465     endif
1466     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1467     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1468      let debugkeep= &debug
1469      setl debug=msg
1470      call netrw#ErrorMsg(s:ERROR,getline(1),4)
1471      let &debug= debugkeep
1472     endif
1473
1474   elseif b:netrw_method == 3
1475    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1476"    call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1477    call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1478    let tmpbufnr= bufnr("%")
1479    setl ff=unix
1480
1481    if exists("g:netrw_port") && g:netrw_port != ""
1482     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1483"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1484    else
1485     NetrwKeepj put ='open '.g:netrw_machine
1486"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1487    endif
1488
1489    if exists("g:netrw_uid") && g:netrw_uid != ""
1490     if exists("g:netrw_ftp") && g:netrw_ftp == 1
1491      NetrwKeepj put =g:netrw_uid
1492"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1493      if exists("s:netrw_passwd") && s:netrw_passwd != ""
1494       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1495      endif
1496"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1497     elseif exists("s:netrw_passwd")
1498      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1499"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1500     endif
1501    endif
1502
1503    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1504     NetrwKeepj put =g:netrw_ftpmode
1505"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1506    endif
1507
1508    if exists("b:netrw_fname") && b:netrw_fname != ""
1509     NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1510"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1511    endif
1512
1513    if exists("g:netrw_ftpextracmd")
1514     NetrwKeepj put =g:netrw_ftpextracmd
1515"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1516    endif
1517
1518    if exists("g:netrw_ftpextracmd")
1519     NetrwKeepj put =g:netrw_ftpextracmd
1520"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1521    endif
1522    for fname in fnamelist
1523     NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1524    endfor
1525"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1526
1527    " perform ftp:
1528    " -i       : turns off interactive prompting from ftp
1529    " -n  unix : DON'T use <.netrc>, even though it exists
1530    " -n  win32: quit being obnoxious about password
1531    NetrwKeepj norm! 1Gdd
1532    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1533    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1534    if getline(1) !~ "^$"
1535"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1536     if !exists("g:netrw_quiet")
1537      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1538     endif
1539    endif
1540
1541   elseif b:netrw_method == 9
1542    " obtain file using sftp
1543"    call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1544    if a:fname =~ '/'
1545     let localfile= substitute(a:fname,'^.*/','','')
1546    else
1547     let localfile= a:fname
1548    endif
1549    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))
1550
1551   elseif !exists("b:netrw_method") || b:netrw_method < 0
1552    " probably a badly formed url; protocol not recognized
1553"    call Dret("netrw#Obtain : unsupported method")
1554    return
1555
1556   else
1557    " protocol recognized but not supported for Obtain (yet?)
1558    if !exists("g:netrw_quiet")
1559     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1560    endif
1561"    call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1562    return
1563   endif
1564
1565   " restore status line
1566   if type(a:fname) == 1 && exists("s:netrw_users_stl")
1567    NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
1568   endif
1569
1570  endif
1571
1572  " cleanup
1573  if exists("tmpbufnr")
1574   if bufnr("%") != tmpbufnr
1575    exe tmpbufnr."bw!"
1576   else
1577    q!
1578   endif
1579  endif
1580
1581"  call Dret("netrw#Obtain")
1582endfun
1583
1584" ---------------------------------------------------------------------
1585" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1586fun! netrw#Nread(mode,fname)
1587"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
1588  let svpos= winsaveview()
1589"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1590  call netrw#NetRead(a:mode,a:fname)
1591"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1592  call winrestview(svpos)
1593
1594  if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
1595   if exists("w:netrw_bannercnt")
1596    " start with cursor just after the banner
1597    exe w:netrw_bannercnt
1598   endif
1599  endif
1600"  call Dret("netrw#Nread")
1601endfun
1602
1603" ------------------------------------------------------------------------
1604" s:NetrwOptionRestore: restore options (based on prior s:NetrwOptionSave) {{{2
1605fun! s:NetrwOptionRestore(vt)
1606"  call Dfunc("s:NetrwOptionRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
1607"  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>"))
1608  if !exists("{a:vt}netrw_optionsave")
1609"   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>"))
1610"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1611"   call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist")
1612   return
1613  endif
1614  unlet {a:vt}netrw_optionsave
1615
1616  if exists("+acd")
1617   if exists("{a:vt}netrw_acdkeep")
1618"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1619    let curdir = getcwd()
1620    let &l:acd = {a:vt}netrw_acdkeep
1621    unlet {a:vt}netrw_acdkeep
1622    if &l:acd
1623     call s:NetrwLcd(curdir)
1624    endif
1625   endif
1626  endif
1627  call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai")
1628  call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw")
1629  call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl")
1630  call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt")
1631  call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb")
1632  call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit")
1633  call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci")
1634  call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin")
1635  call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino")
1636  call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com")
1637  call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo")
1638  call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff")
1639  call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen")
1640  if exists("g:netrw_ffkeep") && g:netrw_ffkeep
1641   call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff")
1642  endif
1643  call s:NetrwRestoreSetting(a:vt."netrw_fokeep","&l:fo")
1644  call s:NetrwRestoreSetting(a:vt."netrw_gdkeep","&l:gd")
1645  call s:NetrwRestoreSetting(a:vt."netrw_hidkeep","&l:hidden")
1646  call s:NetrwRestoreSetting(a:vt."netrw_imkeep","&l:im")
1647  call s:NetrwRestoreSetting(a:vt."netrw_iskkeep","&l:isk")
1648  call s:NetrwRestoreSetting(a:vt."netrw_lskeep","&l:ls")
1649  call s:NetrwRestoreSetting(a:vt."netrw_makeep","&l:ma")
1650  call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic")
1651  call s:NetrwRestoreSetting(a:vt."netrw_modkeep","&l:mod")
1652  call s:NetrwRestoreSetting(a:vt."netrw_nukeep","&l:nu")
1653  call s:NetrwRestoreSetting(a:vt."netrw_rnukeep","&l:rnu")
1654  call s:NetrwRestoreSetting(a:vt."netrw_repkeep","&l:report")
1655  call s:NetrwRestoreSetting(a:vt."netrw_rokeep","&l:ro")
1656  call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
1657  call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell")
1658  call s:NetrwRestoreSetting(a:vt."netrw_twkeep","&l:tw")
1659  call s:NetrwRestoreSetting(a:vt."netrw_wigkeep","&l:wig")
1660  call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep","&l:wrap")
1661  call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write")
1662  call s:NetrwRestoreSetting("s:yykeep","@@")
1663  " Problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1664  call s:NetrwRestoreSetting(a:vt."netrw_tskeep","&l:ts")
1665
1666  if exists("{a:vt}netrw_swfkeep")
1667   if &directory == ""
1668    " user hasn't specified a swapfile directory;
1669    " netrw will temporarily set the swapfile directory
1670    " to the current directory as returned by getcwd().
1671    let &l:directory= getcwd()
1672    sil! let &l:swf = {a:vt}netrw_swfkeep
1673    setl directory=
1674    unlet {a:vt}netrw_swfkeep
1675   elseif &l:swf != {a:vt}netrw_swfkeep
1676    if !g:netrw_use_noswf
1677     " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1678     sil! let &l:swf= {a:vt}netrw_swfkeep
1679    endif
1680    unlet {a:vt}netrw_swfkeep
1681   endif
1682  endif
1683  if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
1684   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1685   if exists("{a:vt}netrw_dirkeep")
1686    call s:NetrwLcd(dirkeep)
1687    unlet {a:vt}netrw_dirkeep
1688   endif
1689  endif
1690  if has("clipboard")
1691   call s:NetrwRestoreSetting(a:vt."netrw_starkeep","@*")
1692   call s:NetrwRestoreSetting(a:vt."netrw_pluskeep","@+")
1693  endif
1694  call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/")
1695
1696"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1697"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
1698"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1699"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
1700"  call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
1701  " Moved the filetype detect here from NetrwGetFile() because remote files
1702  " were having their filetype detect-generated settings overwritten by
1703  " NetrwOptionRestore.
1704  if &ft != "netrw"
1705"   call Decho("filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1706   filetype detect
1707  endif
1708"  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>"))
1709"  call Dret("s:NetrwOptionRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
1710endfun
1711
1712" ---------------------------------------------------------------------
1713" s:NetrwOptionSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1714"             Options get restored by s:NetrwOptionRestore()
1715"  06/08/07 : removed call to NetrwSafeOptions(), either placed
1716"             immediately after NetrwOptionSave() calls in NetRead
1717"             and NetWrite, or after the s:NetrwEnew() call in
1718"             NetrwBrowse.
1719"             vt: normally its "w:" or "s:" (a variable type)
1720fun! s:NetrwOptionSave(vt)
1721"  call Dfunc("s:NetrwOptionSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1722"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1723"  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>"))
1724
1725  if !exists("{a:vt}netrw_optionsave")
1726   let {a:vt}netrw_optionsave= 1
1727  else
1728"   call Dret("s:NetrwOptionSave : options already saved")
1729   return
1730  endif
1731"  call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
1732
1733  " Save current settings and current directory
1734"  call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
1735  let s:yykeep          = @@
1736  if exists("&l:acd")|let {a:vt}netrw_acdkeep  = &l:acd|endif
1737  let {a:vt}netrw_aikeep    = &l:ai
1738  let {a:vt}netrw_awkeep    = &l:aw
1739  let {a:vt}netrw_bhkeep    = &l:bh
1740  let {a:vt}netrw_blkeep    = &l:bl
1741  let {a:vt}netrw_btkeep    = &l:bt
1742  let {a:vt}netrw_bombkeep  = &l:bomb
1743  let {a:vt}netrw_cedit     = &cedit
1744  let {a:vt}netrw_cikeep    = &l:ci
1745  let {a:vt}netrw_cinkeep   = &l:cin
1746  let {a:vt}netrw_cinokeep  = &l:cino
1747  let {a:vt}netrw_comkeep   = &l:com
1748  let {a:vt}netrw_cpokeep   = &l:cpo
1749  let {a:vt}netrw_diffkeep  = &l:diff
1750  let {a:vt}netrw_fenkeep   = &l:fen
1751  if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
1752   let {a:vt}netrw_ffkeep    = &l:ff
1753  endif
1754  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
1755  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
1756  let {a:vt}netrw_hidkeep   = &l:hidden
1757  let {a:vt}netrw_imkeep    = &l:im
1758  let {a:vt}netrw_iskkeep   = &l:isk
1759  let {a:vt}netrw_lskeep    = &l:ls
1760  let {a:vt}netrw_makeep    = &l:ma
1761  let {a:vt}netrw_magickeep = &l:magic
1762  let {a:vt}netrw_modkeep   = &l:mod
1763  let {a:vt}netrw_nukeep    = &l:nu
1764  let {a:vt}netrw_rnukeep   = &l:rnu
1765  let {a:vt}netrw_repkeep   = &l:report
1766  let {a:vt}netrw_rokeep    = &l:ro
1767  let {a:vt}netrw_selkeep   = &l:sel
1768  let {a:vt}netrw_spellkeep = &l:spell
1769  if !g:netrw_use_noswf
1770   let {a:vt}netrw_swfkeep  = &l:swf
1771  endif
1772  let {a:vt}netrw_tskeep    = &l:ts
1773  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
1774  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
1775  let {a:vt}netrw_wrapkeep  = &l:wrap
1776  let {a:vt}netrw_writekeep = &l:write
1777
1778  " save a few selected netrw-related variables
1779"  call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
1780  if g:netrw_keepdir
1781   let {a:vt}netrw_dirkeep  = getcwd()
1782  endif
1783  if has("clipboard")
1784   sil! let {a:vt}netrw_starkeep = @*
1785   sil! let {a:vt}netrw_pluskeep = @+
1786  endif
1787  sil! let {a:vt}netrw_slashkeep= @/
1788
1789"  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>"))
1790"  call Dret("s:NetrwOptionSave : tab#".tabpagenr()." win#".winnr())
1791endfun
1792
1793" ------------------------------------------------------------------------
1794" s:NetrwRestoreSetting: restores specified setting using associated keepvar, {{{2
1795"                        but only if the setting value differs from the associated keepvar.
1796"                        Doing this means that netrw will not come up as having changed a
1797"                        setting last when it really didn't actually change it.
1798"                        Used by s:NetrwOptionRestore() to restore each netrw-senstive setting
1799"                        and  by s:NetrwSafeOptions()
1800fun! s:NetrwRestoreSetting(keepvar,setting)
1801"  call Dfunc("s:NetrwRestoreSetting(keepvar<".a:keepvar."> setting<".a:setting.">)")
1802
1803  if a:keepvar =~ '^&'
1804   exe "let keepvarval= ".a:keepvar
1805   if keepvarval != a:setting
1806    if type(a:setting) == 0
1807     exe "let ".a:keepvar."=".a:setting
1808    elseif type(a:setting) == 1
1809     exe "let ".a:keepvar."= '".a:setting."'"
1810    else
1811     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105)
1812    endif
1813   endif
1814
1815  elseif exists(a:keepvar)
1816   exe "let keepvarval= '".a:keepvar."'"
1817   if keepvarval != a:setting
1818    if type(a:setting) == 0
1819     exe "let ".a:keepvar."= ".a:setting
1820    elseif type(a:setting) == 1
1821     exe "let ".a:keepvar."= '".a:setting."'"
1822    else
1823     call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105)
1824    endif
1825   endif
1826   exe "unlet ".a:keepvar
1827  endif
1828"  call Dret("s:NetrwRestoreSetting")
1829endfun
1830
1831" ---------------------------------------------------------------------
1832" s:NetrwSafeOptions: sets options to help netrw do its job {{{2
1833"                     Use  s:NetrwSaveOptions() to save user settings
1834"                     Use  s:NetrwOptionRestore() to restore user settings
1835fun! s:NetrwSafeOptions()
1836"  call Dfunc("s:NetrwSafeOptions() win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1837"  call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1838"  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>"))
1839  if exists("+acd") | call s:NetrwRestoreSetting("&l:acd",0)|endif
1840  call s:NetrwRestoreSetting("&l:ai",0)
1841  call s:NetrwRestoreSetting("&l:aw",0)
1842  call s:NetrwRestoreSetting("&l:bl",0)
1843  call s:NetrwRestoreSetting("&l:bomb",0)
1844  call s:NetrwRestoreSetting("&l:bt","nofile")
1845  call s:NetrwRestoreSetting("&l:ci",0)
1846  call s:NetrwRestoreSetting("&l:cin",0)
1847  call s:NetrwRestoreSetting("&l:bh","hide")
1848  call s:NetrwRestoreSetting("&l:cino","")
1849  call s:NetrwRestoreSetting("&l:com","")
1850  if &cpo =~ 'a' | call s:NetrwRestoreSetting("&cpo",substitute(&cpo,'a','','g')) | endif
1851  if &cpo =~ 'A' | call s:NetrwRestoreSetting("&cpo",substitute(&cpo,'A','','g')) | endif
1852  setl fo=nroql2
1853  call s:NetrwRestoreSetting("&l:hid",0)
1854  call s:NetrwRestoreSetting("&l:im",0)
1855  setl isk+=@ isk+=* isk+=/
1856  call s:NetrwRestoreSetting("&l:magic",1)
1857  if g:netrw_use_noswf
1858   call s:NetrwRestoreSetting("swf",0)
1859  endif
1860  call s:NetrwRestoreSetting("&l:report",10000)
1861  call s:NetrwRestoreSetting("&l:sel","inclusive")
1862  call s:NetrwRestoreSetting("&l:spell",0)
1863  call s:NetrwRestoreSetting("&l:tw",0)
1864  call s:NetrwRestoreSetting("&l:wig","")
1865  setl cedit&
1866  call s:NetrwCursor()
1867
1868  " allow the user to override safe options
1869"  call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
1870  if &ft == "netrw"
1871"   call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1872   keepalt NetrwKeepj doau FileType netrw
1873  endif
1874
1875"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1876"  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>"))
1877"  call Dret("s:NetrwSafeOptions")
1878endfun
1879
1880" ---------------------------------------------------------------------
1881" NetrwStatusLine: {{{2
1882fun! NetrwStatusLine()
1883
1884" vvv NetrwStatusLine() debugging vvv
1885"  let g:stlmsg=""
1886"  if !exists("w:netrw_explore_bufnr")
1887"   let g:stlmsg="!X<explore_bufnr>"
1888"  elseif w:netrw_explore_bufnr != bufnr("%")
1889"   let g:stlmsg="explore_bufnr!=".bufnr("%")
1890"  endif
1891"  if !exists("w:netrw_explore_line")
1892"   let g:stlmsg=" !X<explore_line>"
1893"  elseif w:netrw_explore_line != line(".")
1894"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1895"  endif
1896"  if !exists("w:netrw_explore_list")
1897"   let g:stlmsg=" !X<explore_list>"
1898"  endif
1899" ^^^ NetrwStatusLine() debugging ^^^
1900
1901  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")
1902   " restore user's status line
1903   let &stl        = s:netrw_users_stl
1904   let &laststatus = s:netrw_users_ls
1905   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1906   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1907   return ""
1908  else
1909   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
1910  endif
1911endfun
1912
1913" ===============================
1914"  Netrw Transfer Functions: {{{1
1915" ===============================
1916
1917" ------------------------------------------------------------------------
1918" netrw#NetRead: responsible for reading a file over the net {{{2
1919"   mode: =0 read remote file and insert before current line
1920"         =1 read remote file and insert after current line
1921"         =2 replace with remote file
1922"         =3 obtain file, but leave in temporary format
1923fun! netrw#NetRead(mode,...)
1924"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
1925
1926  " NetRead: save options {{{3
1927  call s:NetrwOptionSave("w:")
1928  call s:NetrwSafeOptions()
1929  call s:RestoreCursorline()
1930  " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
1931  " However, this setting is not wanted for a remote editing session.  The buffer should be "nofile", still.
1932  setl bl
1933"  call Decho("(netrw#NetRead) buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
1934
1935  " NetRead: interpret mode into a readcmd {{{3
1936  if     a:mode == 0 " read remote file before current line
1937   let readcmd = "0r"
1938  elseif a:mode == 1 " read file after current line
1939   let readcmd = "r"
1940  elseif a:mode == 2 " replace with remote file
1941   let readcmd = "%r"
1942  elseif a:mode == 3 " skip read of file (leave as temporary)
1943   let readcmd = "t"
1944  else
1945   exe a:mode
1946   let readcmd = "r"
1947  endif
1948  let ichoice = (a:0 == 0)? 0 : 1
1949"  call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
1950
1951  " NetRead: get temporary filename {{{3
1952  let tmpfile= s:GetTempfile("")
1953  if tmpfile == ""
1954"   call Dret("netrw#NetRead : unable to get a tempfile!")
1955   return
1956  endif
1957
1958  while ichoice <= a:0
1959
1960   " attempt to repeat with previous host-file-etc
1961   if exists("b:netrw_lastfile") && a:0 == 0
1962"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
1963    let choice = b:netrw_lastfile
1964    let ichoice= ichoice + 1
1965
1966   else
1967    exe "let choice= a:" . ichoice
1968"    call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
1969
1970    if match(choice,"?") == 0
1971     " give help
1972     echomsg 'NetRead Usage:'
1973     echomsg ':Nread machine:path                         uses rcp'
1974     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
1975     echomsg ':Nread "machine id password path"           uses ftp'
1976     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
1977     echomsg ':Nread fetch://machine/path                 uses fetch'
1978     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
1979     echomsg ':Nread http://[user@]machine/path           uses http  wget'
1980     echomsg ':Nread file:///path           		  uses elinks'
1981     echomsg ':Nread https://[user@]machine/path          uses http  wget'
1982     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
1983     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
1984     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
1985     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
1986     sleep 4
1987     break
1988
1989    elseif match(choice,'^"') != -1
1990     " Reconstruct Choice if choice starts with '"'
1991"     call Decho("reconstructing choice",'~'.expand("<slnum>"))
1992     if match(choice,'"$') != -1
1993      " case "..."
1994      let choice= strpart(choice,1,strlen(choice)-2)
1995     else
1996       "  case "... ... ..."
1997      let choice      = strpart(choice,1,strlen(choice)-1)
1998      let wholechoice = ""
1999
2000      while match(choice,'"$') == -1
2001       let wholechoice = wholechoice . " " . choice
2002       let ichoice     = ichoice + 1
2003       if ichoice > a:0
2004       	if !exists("g:netrw_quiet")
2005	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
2006	endif
2007"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
2008        return
2009       endif
2010       let choice= a:{ichoice}
2011      endwhile
2012      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2013     endif
2014    endif
2015   endif
2016
2017"   call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
2018   let ichoice= ichoice + 1
2019
2020   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
2021   call s:NetrwMethod(choice)
2022   if !exists("b:netrw_method") || b:netrw_method < 0
2023"    call Dret("netrw#NetRead : unsupported method")
2024    return
2025   endif
2026   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
2027
2028   " Check whether or not NetrwBrowse() should be handling this request
2029"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
2030   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
2031"    call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
2032    NetrwKeepj call s:NetrwBrowse(0,choice)
2033"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
2034    return
2035   endif
2036
2037   " ============
2038   " NetRead: Perform Protocol-Based Read {{{3
2039   " ===========================
2040   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2041    echo "(netrw) Processing your read request..."
2042   endif
2043
2044   ".........................................
2045   " NetRead: (rcp)  NetRead Method #1 {{{3
2046   if  b:netrw_method == 1 " read with rcp
2047"    call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
2048   " ER: nothing done with g:netrw_uid yet?
2049   " ER: on Win2K" rcp machine[.user]:file tmpfile
2050   " ER: when machine contains '.' adding .user is required (use $USERNAME)
2051   " ER: the tmpfile is full path: rcp sees C:\... as host C
2052   if s:netrw_has_nt_rcp == 1
2053    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2054     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2055    else
2056     " Any way needed it machine contains a '.'
2057     let uid_machine = g:netrw_machine .'.'. $USERNAME
2058    endif
2059   else
2060    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
2061     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2062    else
2063     let uid_machine = g:netrw_machine
2064    endif
2065   endif
2066   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))
2067   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2068   let b:netrw_lastfile = choice
2069
2070   ".........................................
2071   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
2072   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
2073"     call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2074     let netrw_fname= b:netrw_fname
2075     NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2076     let filtbuf= bufnr("%")
2077     setl ff=unix
2078     NetrwKeepj put =g:netrw_ftpmode
2079"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2080     if exists("g:netrw_ftpextracmd")
2081      NetrwKeepj put =g:netrw_ftpextracmd
2082"      call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2083     endif
2084     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2085"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2086     if exists("g:netrw_port") && g:netrw_port != ""
2087      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2088     else
2089      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2090     endif
2091     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2092     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2093      let debugkeep = &debug
2094      setl debug=msg
2095      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2096      let &debug    = debugkeep
2097     endif
2098     call s:SaveBufVars()
2099     keepj bd!
2100     if bufname("%") == "" && getline("$") == "" && line('$') == 1
2101      " needed when one sources a file in a nolbl setting window via ftp
2102      q!
2103     endif
2104     call s:RestoreBufVars()
2105     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2106     let b:netrw_lastfile = choice
2107
2108   ".........................................
2109   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
2110   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
2111    " Construct execution string (four lines) which will be passed through filter
2112"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2113    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2114    NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2115    let filtbuf= bufnr("%")
2116    setl ff=unix
2117    if exists("g:netrw_port") && g:netrw_port != ""
2118     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2119"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2120    else
2121     NetrwKeepj put ='open '.g:netrw_machine
2122"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2123    endif
2124
2125    if exists("g:netrw_uid") && g:netrw_uid != ""
2126     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2127      NetrwKeepj put =g:netrw_uid
2128"       call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2129      if exists("s:netrw_passwd")
2130       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2131      endif
2132"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2133     elseif exists("s:netrw_passwd")
2134      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2135"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2136     endif
2137    endif
2138
2139    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2140     NetrwKeepj put =g:netrw_ftpmode
2141"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2142    endif
2143    if exists("g:netrw_ftpextracmd")
2144     NetrwKeepj put =g:netrw_ftpextracmd
2145"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2146    endif
2147    NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2148"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2149
2150    " perform ftp:
2151    " -i       : turns off interactive prompting from ftp
2152    " -n  unix : DON'T use <.netrc>, even though it exists
2153    " -n  win32: quit being obnoxious about password
2154    NetrwKeepj norm! 1Gdd
2155    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2156    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2157    if getline(1) !~ "^$"
2158"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2159     if !exists("g:netrw_quiet")
2160      call netrw#ErrorMsg(s:ERROR,getline(1),5)
2161     endif
2162    endif
2163    call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2164    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2165    let b:netrw_lastfile = choice
2166
2167   ".........................................
2168   " NetRead: (scp) NetRead Method #4 {{{3
2169   elseif     b:netrw_method  == 4	" read with scp
2170"    call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2171    if exists("g:netrw_port") && g:netrw_port != ""
2172     let useport= " ".g:netrw_scpport." ".g:netrw_port
2173    else
2174     let useport= ""
2175    endif
2176    " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2177    " This is workaround to avoid mis-handle windows local-path:
2178    if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
2179      let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2180    else
2181      let tmpfile_get = tmpfile
2182    endif
2183    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".escape(s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1),' ')." ".s:ShellEscape(tmpfile_get,1))
2184    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2185    let b:netrw_lastfile = choice
2186
2187   ".........................................
2188   " NetRead: (http) NetRead Method #5 (wget) {{{3
2189   elseif     b:netrw_method  == 5
2190"    call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2191    if g:netrw_http_cmd == ""
2192     if !exists("g:netrw_quiet")
2193      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2194     endif
2195"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2196     return
2197    endif
2198
2199    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2200     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2201"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2202     if exists("g:netrw_http_xcmd")
2203      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))
2204     else
2205      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))
2206     endif
2207     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2208
2209    else
2210     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2211"     call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2212     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2213     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2214"     call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2215"     call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2216     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))
2217     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2218"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2219     exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2220    endif
2221    let b:netrw_lastfile = choice
2222"    call Decho("setl ro",'~'.expand("<slnum>"))
2223    setl ro nomod
2224
2225   ".........................................
2226   " NetRead: (dav) NetRead Method #6 {{{3
2227   elseif     b:netrw_method  == 6
2228"    call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2229
2230    if !executable(g:netrw_dav_cmd)
2231     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2232"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2233     return
2234    endif
2235    if g:netrw_dav_cmd =~ "curl"
2236     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2237    else
2238     " Construct execution string (four lines) which will be passed through filter
2239     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2240     new
2241     setl ff=unix
2242     if exists("g:netrw_port") && g:netrw_port != ""
2243      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2244     else
2245      NetrwKeepj put ='open '.g:netrw_machine
2246     endif
2247     if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2248      NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2249     endif
2250     NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2251     NetrwKeepj put ='quit'
2252
2253     " perform cadaver operation:
2254     NetrwKeepj norm! 1Gdd
2255     call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2256     keepj bd!
2257    endif
2258    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2259    let b:netrw_lastfile = choice
2260
2261   ".........................................
2262   " NetRead: (rsync) NetRead Method #7 {{{3
2263   elseif     b:netrw_method  == 7
2264"    call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2265    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(g:netrw_machine.g:netrw_rsync_sep.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2266    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2267    let b:netrw_lastfile = choice
2268
2269   ".........................................
2270   " NetRead: (fetch) NetRead Method #8 {{{3
2271   "    fetch://[user@]host[:http]/path
2272   elseif     b:netrw_method  == 8
2273"    call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2274    if g:netrw_fetch_cmd == ""
2275     if !exists("g:netrw_quiet")
2276      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2277     endif
2278"     call Dret("NetRead")
2279     return
2280    endif
2281    if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2282     let netrw_option= "http"
2283    else
2284     let netrw_option= "ftp"
2285    endif
2286"    call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2287
2288    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2289     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))
2290    else
2291     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))
2292    endif
2293
2294    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2295    let b:netrw_lastfile = choice
2296"    call Decho("setl ro",'~'.expand("<slnum>"))
2297    setl ro nomod
2298
2299   ".........................................
2300   " NetRead: (sftp) NetRead Method #9 {{{3
2301   elseif     b:netrw_method  == 9
2302"    call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2303    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2304    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2305    let b:netrw_lastfile = choice
2306
2307   ".........................................
2308   " NetRead: (file) NetRead Method #10 {{{3
2309  elseif      b:netrw_method == 10 && exists("g:netrw_file_cmd")
2310"   "    call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2311   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2312   let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2313   let b:netrw_lastfile = choice
2314
2315   ".........................................
2316   " NetRead: Complain {{{3
2317   else
2318    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
2319   endif
2320  endwhile
2321
2322  " NetRead: cleanup {{{3
2323  if exists("b:netrw_method")
2324"   call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2325   unlet b:netrw_method
2326   unlet b:netrw_fname
2327  endif
2328  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
2329"   call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2330   NetrwKeepj call s:NetrwDelete(tmpfile)
2331  endif
2332  NetrwKeepj call s:NetrwOptionRestore("w:")
2333
2334"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
2335endfun
2336
2337" ------------------------------------------------------------------------
2338" netrw#NetWrite: responsible for writing a file over the net {{{2
2339fun! netrw#NetWrite(...) range
2340"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
2341
2342  " NetWrite: option handling {{{3
2343  let mod= 0
2344  call s:NetrwOptionSave("w:")
2345  call s:NetrwSafeOptions()
2346
2347  " NetWrite: Get Temporary Filename {{{3
2348  let tmpfile= s:GetTempfile("")
2349  if tmpfile == ""
2350"   call Dret("netrw#NetWrite : unable to get a tempfile!")
2351   return
2352  endif
2353
2354  if a:0 == 0
2355   let ichoice = 0
2356  else
2357   let ichoice = 1
2358  endif
2359
2360  let curbufname= expand("%")
2361"  call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
2362  if &binary
2363   " For binary writes, always write entire file.
2364   " (line numbers don't really make sense for that).
2365   " Also supports the writing of tar and zip files.
2366"   call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2367   exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2368  elseif g:netrw_cygwin
2369   " write (selected portion of) file to temporary
2370   let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2371"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2372   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
2373  else
2374   " write (selected portion of) file to temporary
2375"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2376   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2377  endif
2378
2379  if curbufname == ""
2380   " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2381   " on the temporary file's name.  Deletion of the temporary file during
2382   " cleanup then causes an error message.
2383   0file!
2384  endif
2385
2386  " NetWrite: while choice loop: {{{3
2387  while ichoice <= a:0
2388
2389   " Process arguments: {{{4
2390   " attempt to repeat with previous host-file-etc
2391   if exists("b:netrw_lastfile") && a:0 == 0
2392"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2393    let choice = b:netrw_lastfile
2394    let ichoice= ichoice + 1
2395   else
2396    exe "let choice= a:" . ichoice
2397
2398    " Reconstruct Choice when choice starts with '"'
2399    if match(choice,"?") == 0
2400     echomsg 'NetWrite Usage:"'
2401     echomsg ':Nwrite machine:path                        uses rcp'
2402     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
2403     echomsg ':Nwrite "machine id password path"          uses ftp'
2404     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
2405     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
2406     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
2407     echomsg ':Nwrite rcp://machine/path                  uses rcp'
2408     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
2409     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2410     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
2411     sleep 4
2412     break
2413
2414    elseif match(choice,"^\"") != -1
2415     if match(choice,"\"$") != -1
2416       " case "..."
2417      let choice=strpart(choice,1,strlen(choice)-2)
2418     else
2419      "  case "... ... ..."
2420      let choice      = strpart(choice,1,strlen(choice)-1)
2421      let wholechoice = ""
2422
2423      while match(choice,"\"$") == -1
2424       let wholechoice= wholechoice . " " . choice
2425       let ichoice    = ichoice + 1
2426       if choice > a:0
2427       	if !exists("g:netrw_quiet")
2428	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2429	endif
2430"        call Dret("netrw#NetWrite")
2431        return
2432       endif
2433       let choice= a:{ichoice}
2434      endwhile
2435      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2436     endif
2437    endif
2438   endif
2439   let ichoice= ichoice + 1
2440"   call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
2441
2442   " Determine method of write (ftp, rcp, etc) {{{4
2443   NetrwKeepj call s:NetrwMethod(choice)
2444   if !exists("b:netrw_method") || b:netrw_method < 0
2445"    call Dfunc("netrw#NetWrite : unsupported method")
2446    return
2447   endif
2448
2449   " =============
2450   " NetWrite: Perform Protocol-Based Write {{{3
2451   " ============================
2452   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2453    echo "(netrw) Processing your write request..."
2454"    call Decho("(netrw) Processing your write request...",'~'.expand("<slnum>"))
2455   endif
2456
2457   ".........................................
2458   " NetWrite: (rcp) NetWrite Method #1 {{{3
2459   if  b:netrw_method == 1
2460"    call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2461    if s:netrw_has_nt_rcp == 1
2462     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2463      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2464     else
2465      let uid_machine = g:netrw_machine .'.'. $USERNAME
2466     endif
2467    else
2468     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2469      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2470     else
2471      let uid_machine = g:netrw_machine
2472     endif
2473    endif
2474    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))
2475    let b:netrw_lastfile = choice
2476
2477   ".........................................
2478   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2479   elseif b:netrw_method == 2
2480"    call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2481    let netrw_fname = b:netrw_fname
2482
2483    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2484    let bhkeep      = &l:bh
2485    let curbuf      = bufnr("%")
2486    setl bh=hide
2487    keepj keepalt enew
2488
2489"    call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2490    setl ff=unix
2491    NetrwKeepj put =g:netrw_ftpmode
2492"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2493    if exists("g:netrw_ftpextracmd")
2494     NetrwKeepj put =g:netrw_ftpextracmd
2495"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2496    endif
2497    NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2498"    call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2499    if exists("g:netrw_port") && g:netrw_port != ""
2500     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2501    else
2502"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2503     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2504    endif
2505    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2506    if getline(1) !~ "^$"
2507     if !exists("g:netrw_quiet")
2508      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2509     endif
2510     let mod=1
2511    endif
2512
2513    " remove enew buffer (quietly)
2514    let filtbuf= bufnr("%")
2515    exe curbuf."b!"
2516    let &l:bh            = bhkeep
2517    exe filtbuf."bw!"
2518
2519    let b:netrw_lastfile = choice
2520
2521   ".........................................
2522   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2523   elseif b:netrw_method == 3
2524    " Construct execution string (three or more lines) which will be passed through filter
2525"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2526    let netrw_fname = b:netrw_fname
2527    let bhkeep      = &l:bh
2528
2529    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2530    let curbuf      = bufnr("%")
2531    setl bh=hide
2532    keepj keepalt enew
2533    setl ff=unix
2534
2535    if exists("g:netrw_port") && g:netrw_port != ""
2536     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2537"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2538    else
2539     NetrwKeepj put ='open '.g:netrw_machine
2540"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2541    endif
2542    if exists("g:netrw_uid") && g:netrw_uid != ""
2543     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2544      NetrwKeepj put =g:netrw_uid
2545"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2546      if exists("s:netrw_passwd") && s:netrw_passwd != ""
2547       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2548      endif
2549"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2550     elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2551      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2552"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2553     endif
2554    endif
2555    NetrwKeepj put =g:netrw_ftpmode
2556"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2557    if exists("g:netrw_ftpextracmd")
2558     NetrwKeepj put =g:netrw_ftpextracmd
2559"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2560    endif
2561    NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2562"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2563    " save choice/id/password for future use
2564    let b:netrw_lastfile = choice
2565
2566    " perform ftp:
2567    " -i       : turns off interactive prompting from ftp
2568    " -n  unix : DON'T use <.netrc>, even though it exists
2569    " -n  win32: quit being obnoxious about password
2570    NetrwKeepj norm! 1Gdd
2571    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2572    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2573    if getline(1) !~ "^$"
2574     if  !exists("g:netrw_quiet")
2575      call netrw#ErrorMsg(s:ERROR,getline(1),15)
2576     endif
2577     let mod=1
2578    endif
2579
2580    " remove enew buffer (quietly)
2581    let filtbuf= bufnr("%")
2582    exe curbuf."b!"
2583    let &l:bh= bhkeep
2584    exe filtbuf."bw!"
2585
2586   ".........................................
2587   " NetWrite: (scp) NetWrite Method #4 {{{3
2588   elseif     b:netrw_method == 4
2589"    call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2590    if exists("g:netrw_port") && g:netrw_port != ""
2591     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2592    else
2593     let useport= ""
2594    endif
2595    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2596    let b:netrw_lastfile = choice
2597
2598   ".........................................
2599   " NetWrite: (http) NetWrite Method #5 {{{3
2600   elseif     b:netrw_method == 5
2601"    call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2602    let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2603    if executable(curl)
2604     let url= g:netrw_choice
2605     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2606    elseif !exists("g:netrw_quiet")
2607     call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd.">".",16)
2608    endif
2609
2610   ".........................................
2611   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2612   elseif     b:netrw_method == 6
2613"    call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2614
2615    " Construct execution string (four lines) which will be passed through filter
2616    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2617    let bhkeep      = &l:bh
2618
2619    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2620    let curbuf      = bufnr("%")
2621    setl bh=hide
2622    keepj keepalt enew
2623
2624    setl ff=unix
2625    if exists("g:netrw_port") && g:netrw_port != ""
2626     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2627    else
2628     NetrwKeepj put ='open '.g:netrw_machine
2629    endif
2630    if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2631     NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2632    endif
2633    NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2634
2635    " perform cadaver operation:
2636    NetrwKeepj norm! 1Gdd
2637    call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2638
2639    " remove enew buffer (quietly)
2640    let filtbuf= bufnr("%")
2641    exe curbuf."b!"
2642    let &l:bh            = bhkeep
2643    exe filtbuf."bw!"
2644
2645    let b:netrw_lastfile = choice
2646
2647   ".........................................
2648   " NetWrite: (rsync) NetWrite Method #7 {{{3
2649   elseif     b:netrw_method == 7
2650"    call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2651    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.g:netrw_rsync_sep.b:netrw_fname,1))
2652    let b:netrw_lastfile = choice
2653
2654   ".........................................
2655   " NetWrite: (sftp) NetWrite Method #9 {{{3
2656   elseif     b:netrw_method == 9
2657"    call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2658    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2659    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2660     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2661    else
2662     let uid_machine = g:netrw_machine
2663    endif
2664
2665    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2666    let bhkeep = &l:bh
2667    let curbuf = bufnr("%")
2668    setl bh=hide
2669    keepj keepalt enew
2670
2671    setl ff=unix
2672    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2673"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2674    let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2675    call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2676    let filtbuf= bufnr("%")
2677    exe curbuf."b!"
2678    let &l:bh            = bhkeep
2679    exe filtbuf."bw!"
2680    let b:netrw_lastfile = choice
2681
2682   ".........................................
2683   " NetWrite: Complain {{{3
2684   else
2685    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2686    let leavemod= 1
2687   endif
2688  endwhile
2689
2690  " NetWrite: Cleanup: {{{3
2691"  call Decho("cleanup",'~'.expand("<slnum>"))
2692  if s:FileReadable(tmpfile)
2693"   call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2694   call s:NetrwDelete(tmpfile)
2695  endif
2696  call s:NetrwOptionRestore("w:")
2697
2698  if a:firstline == 1 && a:lastline == line("$")
2699   " restore modifiability; usually equivalent to set nomod
2700   let &mod= mod
2701"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2702  elseif !exists("leavemod")
2703   " indicate that the buffer has not been modified since last written
2704"   call Decho("set nomod",'~'.expand("<slnum>"))
2705   setl nomod
2706"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2707  endif
2708
2709"  call Dret("netrw#NetWrite")
2710endfun
2711
2712" ---------------------------------------------------------------------
2713" netrw#NetSource: source a remotely hosted vim script {{{2
2714" uses NetRead to get a copy of the file into a temporarily file,
2715"              then sources that file,
2716"              then removes that file.
2717fun! netrw#NetSource(...)
2718"  call Dfunc("netrw#NetSource() a:0=".a:0)
2719  if a:0 > 0 && a:1 == '?'
2720   " give help
2721   echomsg 'NetSource Usage:'
2722   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
2723   echomsg ':Nsource fetch://machine/path                 uses fetch'
2724   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2725   echomsg ':Nsource http[s]://[user@]machine/path        uses http  wget'
2726   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
2727   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
2728   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
2729   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2730   sleep 4
2731  else
2732   let i= 1
2733   while i <= a:0
2734    call netrw#NetRead(3,a:{i})
2735"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2736    if s:FileReadable(s:netrw_tmpfile)
2737"     call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2738     exe "so ".fnameescape(s:netrw_tmpfile)
2739"     call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2740     if delete(s:netrw_tmpfile)
2741      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2742     endif
2743     unlet s:netrw_tmpfile
2744    else
2745     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2746    endif
2747    let i= i + 1
2748   endwhile
2749  endif
2750"  call Dret("netrw#NetSource")
2751endfun
2752
2753" ---------------------------------------------------------------------
2754" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2755"                   (implements the :Ntree command)
2756fun! netrw#SetTreetop(iscmd,...)
2757"  call Dfunc("netrw#SetTreetop(iscmd=".a:iscmd." ".((a:0 > 0)? a:1 : "").") a:0=".a:0)
2758"  call Decho("w:netrw_treetop<".w:netrw_treetop.">")
2759
2760  " iscmd==0: netrw#SetTreetop called using gn mapping
2761  " iscmd==1: netrw#SetTreetop called using :Ntree from the command line
2762"  call Decho("(iscmd=".a:iscmd.": called using :Ntree from command line",'~'.expand("<slnum>"))
2763  " clear out the current tree
2764  if exists("w:netrw_treetop")
2765"   call Decho("clearing out current tree",'~'.expand("<slnum>"))
2766   let inittreetop= w:netrw_treetop
2767   unlet w:netrw_treetop
2768  endif
2769  if exists("w:netrw_treedict")
2770"   call Decho("freeing w:netrw_treedict",'~'.expand("<slnum>"))
2771   unlet w:netrw_treedict
2772  endif
2773"  call Decho("inittreetop<".(exists("inittreetop")? inittreetop : "n/a").">")
2774
2775  if (a:iscmd == 0 || a:1 == "") && exists("inittreetop")
2776   let treedir= s:NetrwTreePath(inittreetop)
2777"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2778  else
2779   if isdirectory(s:NetrwFile(a:1))
2780"    call Decho("a:1<".a:1."> is a directory",'~'.expand("<slnum>"))
2781    let treedir= a:1
2782   elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2783    let treedir= b:netrw_curdir."/".a:1
2784"    call Decho("a:1<".a:1."> is NOT a directory, using treedir<".treedir.">",'~'.expand("<slnum>"))
2785   else
2786    " normally the cursor is left in the message window.
2787    " However, here this results in the directory being listed in the message window, which is not wanted.
2788    let netrwbuf= bufnr("%")
2789    call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2790    exe bufwinnr(netrwbuf)."wincmd w"
2791    let treedir= "."
2792   endif
2793  endif
2794"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2795
2796  " determine if treedir is remote or local
2797  let islocal= expand("%") !~ '^\a\{3,}://'
2798"  call Decho("islocal=".islocal,'~'.expand("<slnum>"))
2799
2800  " browse the resulting directory
2801  if islocal
2802   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir))
2803  else
2804   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir))
2805  endif
2806
2807"  call Dret("netrw#SetTreetop")
2808endfun
2809
2810" ===========================================
2811" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
2812"    readcmd == %r : replace buffer with newly read file
2813"            == 0r : read file at top of buffer
2814"            == r  : read file after current line
2815"            == t  : leave file in temporary form (ie. don't read into buffer)
2816fun! s:NetrwGetFile(readcmd, tfile, method)
2817"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
2818
2819  " readcmd=='t': simply do nothing
2820  if a:readcmd == 't'
2821"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2822"   call Dret("NetrwGetFile : skip read of <".a:tfile.">")
2823   return
2824  endif
2825
2826  " get name of remote filename (ie. url and all)
2827  let rfile= bufname("%")
2828"  call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
2829
2830  if exists("*NetReadFixup")
2831   " for the use of NetReadFixup (not otherwise used internally)
2832   let line2= line("$")
2833  endif
2834
2835  if a:readcmd[0] == '%'
2836  " get file into buffer
2837"   call Decho("get file into buffer",'~'.expand("<slnum>"))
2838
2839   " rename the current buffer to the temp file (ie. tfile)
2840   if g:netrw_cygwin
2841    let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2842   else
2843    let tfile= a:tfile
2844   endif
2845   call s:NetrwBufRename(tfile)
2846
2847   " edit temporary file (ie. read the temporary file in)
2848   if     rfile =~ '\.zip$'
2849"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2850    call zip#Browse(tfile)
2851   elseif rfile =~ '\.tar$'
2852"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2853    call tar#Browse(tfile)
2854   elseif rfile =~ '\.tar\.gz$'
2855"    call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2856    call tar#Browse(tfile)
2857   elseif rfile =~ '\.tar\.bz2$'
2858"    call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2859    call tar#Browse(tfile)
2860   elseif rfile =~ '\.tar\.xz$'
2861"    call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2862    call tar#Browse(tfile)
2863   elseif rfile =~ '\.txz$'
2864"    call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2865    call tar#Browse(tfile)
2866   else
2867"    call Decho("edit temporary file",'~'.expand("<slnum>"))
2868    NetrwKeepj e!
2869   endif
2870
2871   " rename buffer back to remote filename
2872   call s:NetrwBufRename(rfile)
2873
2874   " Detect filetype of local version of remote file.
2875   " Note that isk must not include a "/" for scripts.vim
2876   " to process this detection correctly.
2877"   call Decho("detect filetype of local version of remote file",'~'.expand("<slnum>"))
2878   let iskkeep= &l:isk
2879   setl isk-=/
2880   let &l:isk= iskkeep
2881"   call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
2882   let line1 = 1
2883   let line2 = line("$")
2884
2885  elseif !&ma
2886   " attempting to read a file after the current line in the file, but the buffer is not modifiable
2887   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2888"   call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2889   return
2890
2891  elseif s:FileReadable(a:tfile)
2892   " read file after current line
2893"   call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2894   let curline = line(".")
2895   let lastline= line("$")
2896"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline,'~'.expand("<slnum>"))
2897   exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2898   let line1= curline + 1
2899   let line2= line("$") - lastline + 1
2900
2901  else
2902   " not readable
2903"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2904"   call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2905   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2906"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2907   return
2908  endif
2909
2910  " User-provided (ie. optional) fix-it-up command
2911  if exists("*NetReadFixup")
2912"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2913   NetrwKeepj call NetReadFixup(a:method, line1, line2)
2914"  else " Decho
2915"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2916  endif
2917
2918  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
2919   " update the Buffers menu
2920   NetrwKeepj call s:UpdateBuffersMenu()
2921  endif
2922
2923"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
2924
2925 " make sure file is being displayed
2926"  redraw!
2927
2928"  call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2929"  call Dret("NetrwGetFile")
2930endfun
2931
2932" ------------------------------------------------------------------------
2933" s:NetrwMethod:  determine method of transfer {{{2
2934" Input:
2935"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
2936" Output:
2937"  b:netrw_method= 1: rcp
2938"                  2: ftp + <.netrc>
2939"	           3: ftp + machine, id, password, and [path]filename
2940"	           4: scp
2941"	           5: http[s] (wget)
2942"	           6: dav
2943"	           7: rsync
2944"	           8: fetch
2945"	           9: sftp
2946"	          10: file
2947"  g:netrw_machine= hostname
2948"  b:netrw_fname  = filename
2949"  g:netrw_port   = optional port number (for ftp)
2950"  g:netrw_choice = copy of input url (choice)
2951fun! s:NetrwMethod(choice)
2952"   call Dfunc("s:NetrwMethod(a:choice<".a:choice.">)")
2953
2954   " sanity check: choice should have at least three slashes in it
2955   if strlen(substitute(a:choice,'[^/]','','g')) < 3
2956    call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
2957    let b:netrw_method = -1
2958"    call Dret("s:NetrwMethod : incorrect url format<".a:choice.">")
2959    return
2960   endif
2961
2962   " record current g:netrw_machine, if any
2963   " curmachine used if protocol == ftp and no .netrc
2964   if exists("g:netrw_machine")
2965    let curmachine= g:netrw_machine
2966"    call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
2967   else
2968    let curmachine= "N O T A HOST"
2969   endif
2970   if exists("g:netrw_port")
2971    let netrw_port= g:netrw_port
2972   endif
2973
2974   " insure that netrw_ftp_cmd starts off every method determination
2975   " with the current g:netrw_ftp_cmd
2976   let s:netrw_ftp_cmd= g:netrw_ftp_cmd
2977
2978  " initialization
2979  let b:netrw_method  = 0
2980  let g:netrw_machine = ""
2981  let b:netrw_fname   = ""
2982  let g:netrw_port    = ""
2983  let g:netrw_choice  = a:choice
2984
2985  " Patterns:
2986  " mipf     : a:machine a:id password filename	     Use ftp
2987  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
2988  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
2989  " rcpurm   : rcp://[user@]host/filename	     Use rcp
2990  " rcphf    : [user@]host:filename		     Use rcp
2991  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
2992  " httpurm  : http[s]://[user@]host/filename	     Use wget
2993  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
2994  " rsyncurm : rsync://host[:port]/path              Use rsync
2995  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
2996  " sftpurm  : sftp://[user@]host/filename  Use scp
2997  " fileurm  : file://[user@]host/filename	     Use elinks or links
2998  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
2999  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
3000  let ftpurm   = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
3001  let rcpurm   = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
3002  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
3003  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
3004  let httpurm  = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
3005  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
3006  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
3007  let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
3008  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
3009  let fileurm  = '^file\=://\(.*\)$'
3010
3011"  call Decho("determine method:",'~'.expand("<slnum>"))
3012  " Determine Method
3013  " Method#1: rcp://user@hostname/...path-to-file {{{3
3014  if match(a:choice,rcpurm) == 0
3015"   call Decho("rcp://...",'~'.expand("<slnum>"))
3016   let b:netrw_method  = 1
3017   let userid          = substitute(a:choice,rcpurm,'\1',"")
3018   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
3019   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
3020   if userid != ""
3021    let g:netrw_uid= userid
3022   endif
3023
3024  " Method#4: scp://user@hostname/...path-to-file {{{3
3025  elseif match(a:choice,scpurm) == 0
3026"   call Decho("scp://...",'~'.expand("<slnum>"))
3027   let b:netrw_method  = 4
3028   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
3029   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
3030   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
3031
3032  " Method#5: http[s]://user@hostname/...path-to-file {{{3
3033  elseif match(a:choice,httpurm) == 0
3034"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3035   let b:netrw_method = 5
3036   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
3037   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
3038   let b:netrw_http   = (a:choice =~ '^https:')? "https" : "http"
3039
3040  " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
3041  elseif match(a:choice,davurm) == 0
3042"   call Decho("dav://...",'~'.expand("<slnum>"))
3043   let b:netrw_method= 6
3044   if a:choice =~ 'davs:'
3045    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
3046   else
3047    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
3048   endif
3049   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
3050
3051   " Method#7: rsync://user@hostname/...path-to-file {{{3
3052  elseif match(a:choice,rsyncurm) == 0
3053"   call Decho("rsync://...",'~'.expand("<slnum>"))
3054   let b:netrw_method = 7
3055   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
3056   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
3057
3058   " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
3059  elseif match(a:choice,ftpurm) == 0
3060"   call Decho("ftp://...",'~'.expand("<slnum>"))
3061   let userid	      = substitute(a:choice,ftpurm,'\2',"")
3062   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
3063   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
3064   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
3065"   call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3066   if userid != ""
3067    let g:netrw_uid= userid
3068   endif
3069
3070   if curmachine != g:netrw_machine
3071    if exists("s:netrw_hup[".g:netrw_machine."]")
3072     call NetUserPass("ftp:".g:netrw_machine)
3073    elseif exists("s:netrw_passwd")
3074     " if there's a change in hostname, require password re-entry
3075     unlet s:netrw_passwd
3076    endif
3077    if exists("netrw_port")
3078     unlet netrw_port
3079    endif
3080   endif
3081
3082   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3083    let b:netrw_method = 3
3084   else
3085    let host= substitute(g:netrw_machine,'\..*$','','')
3086    if exists("s:netrw_hup[host]")
3087     call NetUserPass("ftp:".host)
3088
3089    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~# '-[sS]:'
3090"     call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3091"     call Decho("          g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3092     if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
3093      let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3094"      call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3095     endif
3096     let b:netrw_method= 2
3097    elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3098"     call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3099     let b:netrw_method= 2
3100    else
3101     if !exists("g:netrw_uid") || g:netrw_uid == ""
3102      call NetUserPass()
3103     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3104      call NetUserPass(g:netrw_uid)
3105    " else just use current g:netrw_uid and s:netrw_passwd
3106     endif
3107     let b:netrw_method= 3
3108    endif
3109   endif
3110
3111  " Method#8: fetch {{{3
3112  elseif match(a:choice,fetchurm) == 0
3113"   call Decho("fetch://...",'~'.expand("<slnum>"))
3114   let b:netrw_method = 8
3115   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3116   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3117   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3118   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
3119
3120   " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
3121  elseif match(a:choice,mipf) == 0
3122"   call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
3123   let b:netrw_method  = 3
3124   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3125   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
3126   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
3127   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
3128   call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
3129
3130  " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3131  elseif match(a:choice,mf) == 0
3132"   call Decho("(ftp) host file",'~'.expand("<slnum>"))
3133   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3134    let b:netrw_method  = 3
3135    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3136    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3137
3138   elseif s:FileReadable(expand("$HOME/.netrc"))
3139    let b:netrw_method  = 2
3140    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3141    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3142   endif
3143
3144  " Method#9: sftp://user@hostname/...path-to-file {{{3
3145  elseif match(a:choice,sftpurm) == 0
3146"   call Decho("sftp://...",'~'.expand("<slnum>"))
3147   let b:netrw_method = 9
3148   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3149   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
3150
3151  " Method#1: Issue an rcp: hostname:filename"  (this one should be last) {{{3
3152  elseif match(a:choice,rcphf) == 0
3153"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3154   let b:netrw_method  = 1
3155   let userid          = substitute(a:choice,rcphf,'\2',"")
3156   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3157   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
3158"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3159"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3160"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3161"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3162   if userid != ""
3163    let g:netrw_uid= userid
3164   endif
3165
3166   " Method#10: file://user@hostname/...path-to-file {{{3
3167  elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
3168"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3169   let b:netrw_method = 10
3170   let b:netrw_fname  = substitute(a:choice,fileurm,'\1',"")
3171"   call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
3172
3173  " Cannot Determine Method {{{3
3174  else
3175   if !exists("g:netrw_quiet")
3176    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3177   endif
3178   let b:netrw_method  = -1
3179  endif
3180  "}}}3
3181
3182  if g:netrw_port != ""
3183   " remove any leading [:#] from port number
3184   let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
3185  elseif exists("netrw_port")
3186   " retain port number as implicit for subsequent ftp operations
3187   let g:netrw_port= netrw_port
3188  endif
3189
3190"  call Decho("a:choice       <".a:choice.">",'~'.expand("<slnum>"))
3191"  call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3192"  call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3193"  call Decho("g:netrw_port   <".g:netrw_port.">",'~'.expand("<slnum>"))
3194"  if exists("g:netrw_uid")		"Decho
3195"   call Decho("g:netrw_uid    <".g:netrw_uid.">",'~'.expand("<slnum>"))
3196"  endif					"Decho
3197"  if exists("s:netrw_passwd")		"Decho
3198"   call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3199"  endif					"Decho
3200"  call Decho("b:netrw_fname  <".b:netrw_fname.">",'~'.expand("<slnum>"))
3201"  call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
3202endfun
3203
3204" ------------------------------------------------------------------------
3205" NetReadFixup: this sort of function is typically written by the user {{{2
3206"               to handle extra junk that their system's ftp dumps
3207"               into the transfer.  This function is provided as an
3208"               example and as a fix for a Windows 95 problem: in my
3209"               experience, win95's ftp always dumped four blank lines
3210"               at the end of the transfer.
3211if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
3212 fun! NetReadFixup(method, line1, line2)
3213"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
3214
3215   " sanity checks -- attempt to convert inputs to integers
3216   let method = a:method + 0
3217   let line1  = a:line1 + 0
3218   let line2  = a:line2 + 0
3219   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
3220"    call Dret("NetReadFixup")
3221    return
3222   endif
3223
3224   if method == 3   " ftp (no <.netrc>)
3225    let fourblanklines= line2 - 3
3226    if fourblanklines >= line1
3227     exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
3228     call histdel("/",-1)
3229    endif
3230   endif
3231
3232"   call Dret("NetReadFixup")
3233 endfun
3234endif
3235
3236" ---------------------------------------------------------------------
3237" NetUserPass: set username and password for subsequent ftp transfer {{{2
3238"   Usage:  :call NetUserPass()		               -- will prompt for userid and password
3239"	    :call NetUserPass("uid")	               -- will prompt for password
3240"	    :call NetUserPass("uid","password")        -- sets global userid and password
3241"	    :call NetUserPass("ftp:host")              -- looks up userid and password using hup dictionary
3242"	    :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
3243fun! NetUserPass(...)
3244
3245" call Dfunc("NetUserPass() a:0=".a:0)
3246
3247 if !exists('s:netrw_hup')
3248  let s:netrw_hup= {}
3249 endif
3250
3251 if a:0 == 0
3252  " case: no input arguments
3253
3254  " change host and username if not previously entered; get new password
3255  if !exists("g:netrw_machine")
3256   let g:netrw_machine= input('Enter hostname: ')
3257  endif
3258  if !exists("g:netrw_uid") || g:netrw_uid == ""
3259   " get username (user-id) via prompt
3260   let g:netrw_uid= input('Enter username: ')
3261  endif
3262  " get password via prompting
3263  let s:netrw_passwd= inputsecret("Enter Password: ")
3264
3265  " set up hup database
3266  let host = substitute(g:netrw_machine,'\..*$','','')
3267  if !exists('s:netrw_hup[host]')
3268   let s:netrw_hup[host]= {}
3269  endif
3270  let s:netrw_hup[host].uid    = g:netrw_uid
3271  let s:netrw_hup[host].passwd = s:netrw_passwd
3272
3273 elseif a:0 == 1
3274  " case: one input argument
3275
3276  if a:1 =~ '^ftp:'
3277   " get host from ftp:... url
3278   " access userid and password from hup (host-user-passwd) dictionary
3279"   call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3280   let host = substitute(a:1,'^ftp:','','')
3281   let host = substitute(host,'\..*','','')
3282   if exists("s:netrw_hup[host]")
3283    let g:netrw_uid    = s:netrw_hup[host].uid
3284    let s:netrw_passwd = s:netrw_hup[host].passwd
3285"    call Decho("get s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3286"    call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3287   else
3288    let g:netrw_uid    = input("Enter UserId: ")
3289    let s:netrw_passwd = inputsecret("Enter Password: ")
3290   endif
3291
3292  else
3293   " case: one input argument, not an url.  Using it as a new user-id.
3294"   call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3295   if exists("g:netrw_machine")
3296    if g:netrw_machine =~ '[0-9.]\+'
3297     let host= g:netrw_machine
3298    else
3299     let host= substitute(g:netrw_machine,'\..*$','','')
3300    endif
3301   else
3302    let g:netrw_machine= input('Enter hostname: ')
3303   endif
3304   let g:netrw_uid = a:1
3305"   call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3306   if exists("g:netrw_passwd")
3307    " ask for password if one not previously entered
3308    let s:netrw_passwd= g:netrw_passwd
3309   else
3310    let s:netrw_passwd = inputsecret("Enter Password: ")
3311   endif
3312  endif
3313
3314"  call Decho("host<".host.">",'~'.expand("<slnum>"))
3315  if exists("host")
3316   if !exists('s:netrw_hup[host]')
3317    let s:netrw_hup[host]= {}
3318   endif
3319   let s:netrw_hup[host].uid    = g:netrw_uid
3320   let s:netrw_hup[host].passwd = s:netrw_passwd
3321  endif
3322
3323 elseif a:0 == 2
3324  let g:netrw_uid    = a:1
3325  let s:netrw_passwd = a:2
3326
3327 elseif a:0 == 3
3328  " enter hostname, user-id, and password into the hup dictionary
3329  let host = substitute(a:1,'^\a\+:','','')
3330  let host = substitute(host,'\..*$','','')
3331  if !exists('s:netrw_hup[host]')
3332   let s:netrw_hup[host]= {}
3333  endif
3334  let s:netrw_hup[host].uid    = a:2
3335  let s:netrw_hup[host].passwd = a:3
3336  let g:netrw_uid              = s:netrw_hup[host].uid
3337  let s:netrw_passwd           = s:netrw_hup[host].passwd
3338"  call Decho("set s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3339"  call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3340 endif
3341
3342" call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
3343endfun
3344
3345" =================================
3346"  Shared Browsing Support:    {{{1
3347" =================================
3348
3349" ---------------------------------------------------------------------
3350" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3351fun! s:ExplorePatHls(pattern)
3352"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
3353  let repat= substitute(a:pattern,'^**/\{1,2}','','')
3354"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3355  let repat= escape(repat,'][.\')
3356"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3357  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
3358"  call Dret("s:ExplorePatHls repat<".repat.">")
3359  return repat
3360endfun
3361
3362" ---------------------------------------------------------------------
3363"  s:NetrwBookHistHandler: {{{2
3364"    0: (user: <mb>)   bookmark current directory
3365"    1: (user: <gb>)   change to the bookmarked directory
3366"    2: (user: <qb>)   list bookmarks
3367"    3: (browsing)     records current directory history
3368"    4: (user: <u>)    go up   (previous) directory, using history
3369"    5: (user: <U>)    go down (next)     directory, using history
3370"    6: (user: <mB>)   delete bookmark
3371fun! s:NetrwBookHistHandler(chg,curdir)
3372"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhist_cnt." histmax=".g:netrw_dirhistmax)
3373  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3374"   "  call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3375   return
3376  endif
3377
3378  let ykeep    = @@
3379  let curbufnr = bufnr("%")
3380
3381  if a:chg == 0
3382   " bookmark the current directory
3383"   call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3384   if exists("s:netrwmarkfilelist_{curbufnr}")
3385    call s:NetrwBookmark(0)
3386    echo "bookmarked marked files"
3387   else
3388    call s:MakeBookmark(a:curdir)
3389    echo "bookmarked the current directory"
3390   endif
3391
3392  elseif a:chg == 1
3393   " change to the bookmarked directory
3394"   call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3395   if exists("g:netrw_bookmarklist[v:count-1]")
3396"    call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3397    exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3398   else
3399    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3400   endif
3401
3402  elseif a:chg == 2
3403"   redraw!
3404   let didwork= 0
3405   " list user's bookmarks
3406"   call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3407   if exists("g:netrw_bookmarklist")
3408"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3409    let cnt= 1
3410    for bmd in g:netrw_bookmarklist
3411"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3412     echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3413     let didwork = 1
3414     let cnt     = cnt + 1
3415    endfor
3416   endif
3417
3418   " list directory history
3419   let cnt     = g:netrw_dirhist_cnt
3420   let first   = 1
3421   let histcnt = 0
3422   if g:netrw_dirhistmax > 0
3423    while ( first || cnt != g:netrw_dirhist_cnt )
3424"    call Decho("first=".first." cnt=".cnt." dirhist_cnt=".g:netrw_dirhist_cnt,'~'.expand("<slnum>"))
3425     if exists("g:netrw_dirhist_{cnt}")
3426"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3427      echo printf("Netrw  History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3428      let didwork= 1
3429     endif
3430     let histcnt = histcnt + 1
3431     let first   = 0
3432     let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3433     if cnt < 0
3434      let cnt= cnt + g:netrw_dirhistmax
3435     endif
3436    endwhile
3437   else
3438    let g:netrw_dirhist_cnt= 0
3439   endif
3440   if didwork
3441    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3442   endif
3443
3444  elseif a:chg == 3
3445   " saves most recently visited directories (when they differ)
3446"   call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3447   if !exists("g:netrw_dirhist_cnt") || !exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") || g:netrw_dirhist_{g:netrw_dirhist_cnt} != a:curdir
3448    if g:netrw_dirhistmax > 0
3449     let g:netrw_dirhist_cnt                   = ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
3450     let g:netrw_dirhist_{g:netrw_dirhist_cnt} = a:curdir
3451    endif
3452"    call Decho("save dirhist#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3453   endif
3454
3455  elseif a:chg == 4
3456   " u: change to the previous directory stored on the history list
3457"   call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
3458   if g:netrw_dirhistmax > 0
3459    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - v:count1 ) % g:netrw_dirhistmax
3460    if g:netrw_dirhist_cnt < 0
3461     let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
3462    endif
3463   else
3464    let g:netrw_dirhist_cnt= 0
3465   endif
3466   if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
3467"    call Decho("changedir u#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3468    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3469     setl ma noro
3470"     call Decho("setl ma noro",'~'.expand("<slnum>"))
3471     sil! NetrwKeepj %d _
3472     setl nomod
3473"     call Decho("setl nomod",'~'.expand("<slnum>"))
3474"     call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3475    endif
3476"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("<slnum>"))
3477    exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
3478   else
3479    if g:netrw_dirhistmax > 0
3480     let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + v:count1 ) % g:netrw_dirhistmax
3481    else
3482     let g:netrw_dirhist_cnt= 0
3483    endif
3484    echo "Sorry, no predecessor directory exists yet"
3485   endif
3486
3487  elseif a:chg == 5
3488   " U: change to the subsequent directory stored on the history list
3489"   call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3490   if g:netrw_dirhistmax > 0
3491    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
3492    if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
3493"    call Decho("changedir U#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3494     if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3495"      call Decho("setl ma noro",'~'.expand("<slnum>"))
3496      setl ma noro
3497      sil! NetrwKeepj %d _
3498"      call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3499"      call Decho("setl nomod",'~'.expand("<slnum>"))
3500      setl nomod
3501"      call Decho("(set nomod)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3502     endif
3503"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("<slnum>"))
3504     exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
3505    else
3506     let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax
3507     if g:netrw_dirhist_cnt < 0
3508      let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
3509     endif
3510     echo "Sorry, no successor directory exists yet"
3511    endif
3512   else
3513    let g:netrw_dirhist_cnt= 0
3514    echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
3515   endif
3516
3517  elseif a:chg == 6
3518"   call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3519   if exists("s:netrwmarkfilelist_{curbufnr}")
3520    call s:NetrwBookmark(1)
3521    echo "removed marked files from bookmarks"
3522   else
3523    " delete the v:count'th bookmark
3524    let iremove = v:count
3525    let dremove = g:netrw_bookmarklist[iremove - 1]
3526"    call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3527    call s:MergeBookmarks()
3528"    call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3529    NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3530    echo "removed ".dremove." from g:netrw_bookmarklist"
3531"    call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3532   endif
3533"   call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3534  endif
3535  call s:NetrwBookmarkMenu()
3536  call s:NetrwTgtMenu()
3537  let @@= ykeep
3538"  call Dret("s:NetrwBookHistHandler")
3539endfun
3540
3541" ---------------------------------------------------------------------
3542" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
3543"  Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
3544"                      Sister function: s:NetrwBookHistSave()
3545fun! s:NetrwBookHistRead()
3546"  call Dfunc("s:NetrwBookHistRead()")
3547  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3548"   "  call Dret("s:NetrwBookHistRead - suppressed due to g:netrw_dirhistmax")
3549   return
3550  endif
3551  let ykeep= @@
3552  if !exists("s:netrw_initbookhist")
3553   let home    = s:NetrwHome()
3554   let savefile= home."/.netrwbook"
3555   if filereadable(s:NetrwFile(savefile))
3556"    call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3557    exe "keepalt NetrwKeepj so ".savefile
3558   endif
3559   if g:netrw_dirhistmax > 0
3560    let savefile= home."/.netrwhist"
3561    if filereadable(s:NetrwFile(savefile))
3562"    call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3563     exe "keepalt NetrwKeepj so ".savefile
3564    endif
3565    let s:netrw_initbookhist= 1
3566    au VimLeave * call s:NetrwBookHistSave()
3567   endif
3568  endif
3569  let @@= ykeep
3570"  call Dret("s:NetrwBookHistRead")
3571endfun
3572
3573" ---------------------------------------------------------------------
3574" s:NetrwBookHistSave: this function saves bookmarks and history {{{2
3575"                      Sister function: s:NetrwBookHistRead()
3576"                      I used to do this via viminfo but that appears to
3577"                      be unreliable for long-term storage
3578"                      If g:netrw_dirhistmax is <= 0, no history or bookmarks
3579"                      will be saved.
3580fun! s:NetrwBookHistSave()
3581"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax)
3582  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3583"   call Dret("s:NetrwBookHistSave : dirhistmax=".g:netrw_dirhistmax)
3584   return
3585  endif
3586
3587  let savefile= s:NetrwHome()."/.netrwhist"
3588  1split
3589  call s:NetrwEnew()
3590  if g:netrw_use_noswf
3591   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
3592  else
3593   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
3594  endif
3595  setl nocin noai noci magic nospell nohid wig= noaw
3596  setl ma noro write
3597  if exists("+acd") | setl noacd | endif
3598  sil! NetrwKeepj keepalt %d _
3599
3600  " save .netrwhist -- no attempt to merge
3601  sil! keepalt file .netrwhist
3602  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
3603  call setline(2,"let g:netrw_dirhist_cnt =".g:netrw_dirhist_cnt)
3604  let lastline = line("$")
3605  let cnt      = 1
3606  while cnt <= g:netrw_dirhist_cnt
3607   call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3608   let cnt= cnt + 1
3609  endwhile
3610  exe "sil! w! ".savefile
3611
3612  sil NetrwKeepj %d _
3613  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
3614   " merge and write .netrwbook
3615   let savefile= s:NetrwHome()."/.netrwbook"
3616
3617   if filereadable(s:NetrwFile(savefile))
3618    let booklist= deepcopy(g:netrw_bookmarklist)
3619    exe "sil NetrwKeepj keepalt so ".savefile
3620    for bdm in booklist
3621     if index(g:netrw_bookmarklist,bdm) == -1
3622      call add(g:netrw_bookmarklist,bdm)
3623     endif
3624    endfor
3625    call sort(g:netrw_bookmarklist)
3626   endif
3627
3628   " construct and save .netrwbook
3629   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3630   exe "sil! w! ".savefile
3631  endif
3632  let bgone= bufnr("%")
3633  q!
3634  exe "keepalt ".bgone."bwipe!"
3635
3636"  call Dret("s:NetrwBookHistSave")
3637endfun
3638
3639" ---------------------------------------------------------------------
3640" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3641"  list of the contents of a local or remote directory.  It is assumed that the
3642"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3643"  with the requested remote hostname first.
3644"    Often called via:  Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
3645fun! s:NetrwBrowse(islocal,dirname)
3646  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
3647"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
3648"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
3649"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3650"  call Dredir("ls!","s:NetrwBrowse")
3651
3652  " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3653  " This is useful when one edits a local file, then :e ., then :Rex
3654  if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
3655   let w:netrw_rexfile= bufname("#")
3656"   call Decho("setting w:netrw_rexfile<".w:netrw_rexfile."> win#".winnr(),'~'.expand("<slnum>"))
3657  endif
3658
3659  " s:NetrwBrowse : initialize history {{{3
3660  if !exists("s:netrw_initbookhist")
3661   NetrwKeepj call s:NetrwBookHistRead()
3662  endif
3663
3664  " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
3665  if a:dirname !~ '^\a\{3,}://'
3666   let dirname= simplify(a:dirname)
3667  else
3668   let dirname= a:dirname
3669  endif
3670
3671  " repoint t:netrw_lexbufnr if appropriate
3672  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
3673"   call Decho("set repointlexbufnr to true!")
3674   let repointlexbufnr= 1
3675  endif
3676
3677  if exists("s:netrw_skipbrowse")
3678   unlet s:netrw_skipbrowse
3679"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("<slnum>"))
3680"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed")
3681   return
3682  endif
3683
3684  " s:NetrwBrowse : sanity checks: {{{3
3685  if !exists("*shellescape")
3686   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3687"   call Dret("s:NetrwBrowse : missing shellescape()")
3688   return
3689  endif
3690  if !exists("*fnameescape")
3691   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3692"   call Dret("s:NetrwBrowse : missing fnameescape()")
3693   return
3694  endif
3695
3696  " s:NetrwBrowse : save options: {{{3
3697  call s:NetrwOptionSave("w:")
3698
3699  " s:NetrwBrowse : re-instate any marked files {{{3
3700  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3701   if exists("s:netrwmarkfilelist_{bufnr('%')}")
3702"    call Decho("clearing marked files",'~'.expand("<slnum>"))
3703    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3704   endif
3705  endif
3706
3707  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
3708   " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3709"   call Decho("handle w:netrw_acdkeep:",'~'.expand("<slnum>"))
3710"   call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("<slnum>"))
3711   if s:NetrwLcd(dirname)
3712"    call Dret("s:NetrwBrowse : lcd failure")
3713    return
3714   endif
3715   "   call s:NetrwSafeOptions() " tst953 failed with this enabled.
3716"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
3717
3718  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
3719   " s:NetrwBrowse :  remote regular file handler {{{3
3720"   call Decho("handle remote regular file: dirname<".dirname.">",'~'.expand("<slnum>"))
3721   if bufname(dirname) != ""
3722"    call Decho("edit buf#".bufname(dirname)." in win#".winnr(),'~'.expand("<slnum>"))
3723    exe "NetrwKeepj b ".bufname(dirname)
3724   else
3725    " attempt transfer of remote regular file
3726"    call Decho("attempt transfer as regular file<".dirname.">",'~'.expand("<slnum>"))
3727
3728    " remove any filetype indicator from end of dirname, except for the
3729    " "this is a directory" indicator (/).
3730    " There shouldn't be one of those here, anyway.
3731    let path= substitute(dirname,'[*=@|]\r\=$','','e')
3732"    call Decho("new path<".path.">",'~'.expand("<slnum>"))
3733    call s:RemotePathAnalysis(dirname)
3734
3735    " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3736    call s:NetrwEnew(dirname)
3737    call s:NetrwSafeOptions()
3738    setl ma noro
3739"    call Decho("setl ma noro",'~'.expand("<slnum>"))
3740    let b:netrw_curdir = dirname
3741    let url            = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3742    call s:NetrwBufRename(url)
3743    exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3744    sil call netrw#NetRead(2,url)
3745    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3746"    call Decho("url<".url.">",'~'.expand("<slnum>"))
3747"    call Decho("s:path<".s:path.">",'~'.expand("<slnum>"))
3748"    call Decho("s:fname<".s:fname.">",'~'.expand("<slnum>"))
3749    if s:path =~ '.bz2'
3750     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3751    elseif s:path =~ '.gz'
3752     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3753    elseif s:path =~ '.gz'
3754     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3755    else
3756     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3757    endif
3758   endif
3759
3760   " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3761   call s:SetBufWinVars()
3762   call s:NetrwOptionRestore("w:")
3763"   call Decho("setl ma nomod",'~'.expand("<slnum>"))
3764   setl ma nomod noro
3765"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3766
3767"   call Dret("s:NetrwBrowse : file<".s:fname.">")
3768   return
3769  endif
3770
3771  " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
3772  call s:UseBufWinVars()
3773
3774  " set up some variables {{{3
3775  let b:netrw_browser_active = 1
3776  let dirname                = dirname
3777  let s:last_sort_by         = g:netrw_sort_by
3778
3779  " set up menu {{{3
3780  NetrwKeepj call s:NetrwMenu(1)
3781
3782  " get/set-up buffer {{{3
3783"  call Decho("saving position across a buffer refresh",'~'.expand("<slnum>"))
3784  let svpos  = winsaveview()
3785"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3786  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
3787
3788  " maintain markfile highlighting
3789  if has("syntax") && exists("g:syntax_on") && g:syntax_on
3790   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3791" "   call Decho("bufnr(%)=".bufnr('%'),'~'.expand("<slnum>"))
3792" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
3793    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3794   else
3795" "   call Decho("2match none",'~'.expand("<slnum>"))
3796    2match none
3797   endif
3798  endif
3799  if reusing && line("$") > 1
3800   call s:NetrwOptionRestore("w:")
3801"   call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3802   setl noma nomod nowrap
3803"   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>"))
3804"   call Dret("s:NetrwBrowse : re-using not-cleared buffer")
3805   return
3806  endif
3807
3808  " set b:netrw_curdir to the new directory name {{{3
3809"  call Decho("set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")",'~'.expand("<slnum>"))
3810  let b:netrw_curdir= dirname
3811  if b:netrw_curdir =~ '[/\\]$'
3812   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
3813  endif
3814  if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
3815   let b:netrw_curdir= b:netrw_curdir."/"
3816  endif
3817  if b:netrw_curdir == ''
3818   if has("amiga")
3819    " On the Amiga, the empty string connotes the current directory
3820    let b:netrw_curdir= getcwd()
3821   else
3822    " under unix, when the root directory is encountered, the result
3823    " from the preceding substitute is an empty string.
3824    let b:netrw_curdir= '/'
3825   endif
3826  endif
3827  if !a:islocal && b:netrw_curdir !~ '/$'
3828   let b:netrw_curdir= b:netrw_curdir.'/'
3829  endif
3830"  call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
3831
3832  " ------------
3833  " (local only) {{{3
3834  " ------------
3835  if a:islocal
3836"   call Decho("local only:",'~'.expand("<slnum>"))
3837
3838   " Set up ShellCmdPost handling.  Append current buffer to browselist
3839   call s:LocalFastBrowser()
3840
3841  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3842   if !g:netrw_keepdir
3843"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
3844"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("<slnum>"))
3845    if !exists("&l:acd") || !&l:acd
3846     if s:NetrwLcd(b:netrw_curdir)
3847"      call Dret("s:NetrwBrowse : lcd failure")
3848      return
3849     endif
3850    endif
3851   endif
3852
3853  " --------------------------------
3854  " remote handling: {{{3
3855  " --------------------------------
3856  else
3857"   call Decho("remote only:",'~'.expand("<slnum>"))
3858
3859   " analyze dirname and g:netrw_list_cmd {{{3
3860"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>"))
3861   if dirname =~# "^NetrwTreeListing\>"
3862    let dirname= b:netrw_curdir
3863"    call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>"))
3864   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3865    let dirname= substitute(b:netrw_curdir,'\\','/','g')
3866    if dirname !~ '/$'
3867     let dirname= dirname.'/'
3868    endif
3869    let b:netrw_curdir = dirname
3870"    call Decho("(liststyle is TREELIST) dirname<".dirname.">",'~'.expand("<slnum>"))
3871   else
3872    let dirname = substitute(dirname,'\\','/','g')
3873"    call Decho("(normal) dirname<".dirname.">",'~'.expand("<slnum>"))
3874   endif
3875
3876   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3877   if dirname !~ dirpat
3878    if !exists("g:netrw_quiet")
3879     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3880    endif
3881    NetrwKeepj call s:NetrwOptionRestore("w:")
3882"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3883    setl noma nomod nowrap
3884"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3885"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
3886    return
3887   endif
3888   let b:netrw_curdir= dirname
3889"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("<slnum>"))
3890  endif  " (additional remote handling)
3891
3892  " -----------------------
3893  " Directory Listing: {{{3
3894  " -----------------------
3895  NetrwKeepj call s:NetrwMaps(a:islocal)
3896  NetrwKeepj call s:NetrwCommands(a:islocal)
3897  NetrwKeepj call s:PerformListing(a:islocal)
3898
3899  " restore option(s)
3900  call s:NetrwOptionRestore("w:")
3901"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3902
3903  " If there is a rexposn: restore position with rexposn
3904  " Otherwise            : set rexposn
3905  if exists("s:rexposn_".bufnr("%"))
3906"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
3907   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
3908   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
3909    NetrwKeepj exe w:netrw_bannercnt
3910   endif
3911  else
3912   NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
3913  endif
3914  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
3915   let &l:bexpr= "netrw#BalloonHelp()"
3916"   call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>"))
3917   setl beval
3918  endif
3919
3920  " repoint t:netrw_lexbufnr if appropriate
3921  if exists("repointlexbufnr")
3922   let t:netrw_lexbufnr= bufnr("%")
3923"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
3924  endif
3925
3926  " restore position
3927  if reusing
3928"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3929   call winrestview(svpos)
3930  endif
3931
3932  " The s:LocalBrowseRefresh() function is called by an autocmd
3933  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow, medium speed).
3934  " However, s:NetrwBrowse() causes the FocusGained event to fire the firstt time.
3935"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3936"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3937"  call Dret("s:NetrwBrowse : did PerformListing  ft<".&ft.">")
3938  return
3939endfun
3940
3941" ---------------------------------------------------------------------
3942" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
3943" may not apply correctly; ie. netrw's idea of the current directory may
3944" differ from vim's.  This function insures that netrw's idea of the current
3945" directory is used.
3946fun! s:NetrwFile(fname)
3947"  call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
3948"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
3949"  call Decho("g:netrw_cygwin   =".(exists("g:netrw_cygwin")?    g:netrw_cygwin    : 'n/a'),'~'.expand("<slnum>"))
3950"  call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
3951"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
3952
3953  " clean up any leading treedepthstring
3954  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
3955   let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
3956"   call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>"))
3957  else
3958   let fname= a:fname
3959  endif
3960
3961  if g:netrw_keepdir
3962   " vim's idea of the current directory possibly may differ from netrw's
3963   if !exists("b:netrw_curdir")
3964    let b:netrw_curdir= getcwd()
3965   endif
3966
3967   if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
3968    if fname =~ '^\' || fname =~ '^\a:\'
3969     " windows, but full path given
3970     let ret= fname
3971"     call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3972    else
3973     " windows, relative path given
3974     let ret= s:ComposePath(b:netrw_curdir,fname)
3975"     call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3976    endif
3977
3978   elseif fname =~ '^/'
3979    " not windows, full path given
3980    let ret= fname
3981"    call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3982   else
3983    " not windows, relative path given
3984    let ret= s:ComposePath(b:netrw_curdir,fname)
3985"    call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3986   endif
3987  else
3988   " vim and netrw agree on the current directory
3989   let ret= fname
3990"   call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
3991"   call Decho("vim   directory: ".getcwd(),'~'.expand("<slnum>"))
3992"   call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>"))
3993  endif
3994
3995"  call Dret("s:NetrwFile ".ret)
3996  return ret
3997endfun
3998
3999" ---------------------------------------------------------------------
4000" s:NetrwFileInfo: supports qf (query for file information) {{{2
4001fun! s:NetrwFileInfo(islocal,fname)
4002"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
4003  let ykeep= @@
4004  if a:islocal
4005   let lsopt= "-lsad"
4006   if g:netrw_sizestyle =~# 'H'
4007    let lsopt= "-lsadh"
4008   elseif g:netrw_sizestyle =~# 'h'
4009    let lsopt= "-lsadh --si"
4010   endif
4011   if (has("unix") || has("macunix")) && executable("/bin/ls")
4012
4013    if getline(".") == "../"
4014     echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
4015"     call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
4016
4017    elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
4018     echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
4019"     call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
4020
4021    elseif exists("b:netrw_curdir")
4022      echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
4023"      call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
4024
4025    else
4026"     call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
4027     echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
4028"     call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
4029    endif
4030   else
4031    " use vim functions to return information about file below cursor
4032"    call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
4033    if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
4034     let fname= substitute(a:fname,".$","","")
4035    else
4036     let fname= a:fname
4037    endif
4038    let t  = getftime(s:NetrwFile(fname))
4039    let sz = getfsize(s:NetrwFile(fname))
4040    if g:netrw_sizestyle =~# "[hH]"
4041     let sz= s:NetrwHumanReadable(sz)
4042    endif
4043    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
4044"    call Decho("fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
4045   endif
4046  else
4047   echo "sorry, \"qf\" not supported yet for remote files"
4048  endif
4049  let @@= ykeep
4050"  call Dret("s:NetrwFileInfo")
4051endfun
4052
4053" ---------------------------------------------------------------------
4054" s:NetrwFullPath: returns the full path to a directory and/or file {{{2
4055fun! s:NetrwFullPath(filename)
4056"  " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)")
4057  let filename= a:filename
4058  if filename !~ '^/'
4059   let filename= resolve(getcwd().'/'.filename)
4060  endif
4061  if filename != "/" && filename =~ '/$'
4062   let filename= substitute(filename,'/$','','')
4063  endif
4064"  " call Dret("s:NetrwFullPath <".filename.">")
4065  return filename
4066endfun
4067
4068" ---------------------------------------------------------------------
4069" s:NetrwGetBuffer: [get a new|find an old netrw] buffer for a netrw listing {{{2
4070"   returns 0=cleared buffer
4071"           1=re-used buffer (buffer not cleared)
4072fun! s:NetrwGetBuffer(islocal,dirname)
4073"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
4074"  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>"))
4075"  call Decho("netrwbuf dictionary=".(exists("s:netrwbuf")? string(s:netrwbuf) : 'n/a'),'~'.expand("<slnum>"))
4076  let dirname= a:dirname
4077
4078  " re-use buffer if possible {{{3
4079"  call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
4080  if !exists("s:netrwbuf")
4081"   call Decho("  s:netrwbuf initialized to {}",'~'.expand("<slnum>"))
4082   let s:netrwbuf= {}
4083  endif
4084"  call Decho("  s:netrwbuf         =".string(s:netrwbuf),'~'.expand("<slnum>"))
4085"  call Decho("  w:netrw_liststyle  =".(exists("w:netrw_liststyle")? w:netrw_liststyle : "n/a"),'~'.expand("<slnum>"))
4086
4087  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4088   let bufnum = -1
4089
4090   if !empty(s:netrwbuf) && has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4091    if has_key(s:netrwbuf,"NetrwTreeListing")
4092     let bufnum= s:netrwbuf["NetrwTreeListing"]
4093    else
4094     let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4095    endif
4096"    call Decho("  NetrwTreeListing: bufnum#".bufnum,'~'.expand("<slnum>"))
4097    if !bufexists(bufnum)
4098     call remove(s:netrwbuf,"NetrwTreeListing"])
4099     let bufnum= -1
4100    endif
4101   elseif bufnr("NetrwTreeListing") != -1
4102    let bufnum= bufnr("NetrwTreeListing")
4103"    call Decho("  NetrwTreeListing".": bufnum#".bufnum,'~'.expand("<slnum>"))
4104   else
4105"    call Decho("  did not find a NetrwTreeListing buffer",'~'.expand("<slnum>"))
4106     let bufnum= -1
4107   endif
4108
4109  elseif has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4110   let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4111"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum,'~'.expand("<slnum>"))
4112   if !bufexists(bufnum)
4113    call remove(s:netrwbuf,s:NetrwFullPath(dirname))
4114    let bufnum= -1
4115   endif
4116
4117  else
4118"   call Decho("  lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key",'~'.expand("<slnum>"))
4119   let bufnum= -1
4120  endif
4121"  call Decho("  bufnum#".bufnum,'~'.expand("<slnum>"))
4122
4123  " get enew buffer and name it -or- re-use buffer {{{3
4124  if bufnum < 0      " get enew buffer and name it
4125"   call Decho("--get enew buffer and name it  (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4126   call s:NetrwEnew(dirname)
4127"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4128   " name the buffer
4129   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4130    " Got enew buffer; transform into a NetrwTreeListing
4131"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4132    let w:netrw_treebufnr = bufnr("%")
4133    call s:NetrwBufRename("NetrwTreeListing")
4134    if g:netrw_use_noswf
4135     setl nobl bt=nofile noswf
4136    else
4137     setl nobl bt=nofile
4138    endif
4139    nnoremap <silent> <buffer> [[       :sil call <SID>TreeListMove('[[')<cr>
4140    nnoremap <silent> <buffer> ]]       :sil call <SID>TreeListMove(']]')<cr>
4141    nnoremap <silent> <buffer> []       :sil call <SID>TreeListMove('[]')<cr>
4142    nnoremap <silent> <buffer> ][       :sil call <SID>TreeListMove('][')<cr>
4143"    call Decho("  tree listing bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
4144   else
4145    call s:NetrwBufRename(dirname)
4146    " enter the new buffer into the s:netrwbuf dictionary
4147    let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%")
4148"    call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>"))
4149"    call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
4150   endif
4151"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4152
4153  else " Re-use the buffer
4154"   call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4155   let eikeep= &ei
4156   setl ei=all
4157   if getline(2) =~# '^" Netrw Directory Listing'
4158"    call Decho("  getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>"))
4159    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4160   else
4161"    call Decho("  getline(2)<".getline(2).'> does not match "Netrw Directory Listing" : using b '.bufnum,'~'.expand("<slnum>"))
4162    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4163   endif
4164"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
4165   if bufname("%") == '.'
4166    call s:NetrwBufRename(getcwd())
4167   endif
4168   let &ei= eikeep
4169
4170   if line("$") <= 1 && getline(1) == ""
4171    " empty buffer
4172    NetrwKeepj call s:NetrwListSettings(a:islocal)
4173"    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>"))
4174"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4175"    call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4176    return 0
4177
4178   elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4179"    call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4180    NetrwKeepj call s:NetrwListSettings(a:islocal)
4181    sil NetrwKeepj %d _
4182"    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>"))
4183"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4184"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4185    return 0
4186
4187   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4188"    call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4189"    call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4190    setl ma
4191    sil NetrwKeepj %d _
4192    NetrwKeepj call s:NetrwListSettings(a:islocal)
4193"    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>"))
4194"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4195"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4196    return 0
4197
4198   else
4199"    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>"))
4200"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4201"    call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4202    return 1
4203   endif
4204  endif
4205
4206  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4207  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
4208  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
4209  "  med    1         D      H
4210  "  fast   2         H      H
4211"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
4212  let fname= expand("%")
4213  NetrwKeepj call s:NetrwListSettings(a:islocal)
4214  call s:NetrwBufRename(fname)
4215
4216  " delete all lines from buffer {{{3
4217"  call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4218"  call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4219  sil! keepalt NetrwKeepj %d _
4220
4221"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4222"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4223"  call Dret("s:NetrwGetBuffer 0<cleared buffer>")
4224  return 0
4225endfun
4226
4227" ---------------------------------------------------------------------
4228" s:NetrwGetcwd: get the current directory. {{{2
4229"   Change backslashes to forward slashes, if any.
4230"   If doesc is true, escape certain troublesome characters
4231fun! s:NetrwGetcwd(doesc)
4232"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
4233  let curdir= substitute(getcwd(),'\\','/','ge')
4234  if curdir !~ '[\/]$'
4235   let curdir= curdir.'/'
4236  endif
4237  if a:doesc
4238   let curdir= fnameescape(curdir)
4239  endif
4240"  call Dret("NetrwGetcwd <".curdir.">")
4241  return curdir
4242endfun
4243
4244" ---------------------------------------------------------------------
4245"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4246fun! s:NetrwGetWord()
4247"  call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4248"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4249  let keepsol= &l:sol
4250  setl nosol
4251
4252  call s:UseBufWinVars()
4253
4254  " insure that w:netrw_liststyle is set up
4255  if !exists("w:netrw_liststyle")
4256   if exists("g:netrw_liststyle")
4257    let w:netrw_liststyle= g:netrw_liststyle
4258   else
4259    let w:netrw_liststyle= s:THINLIST
4260   endif
4261"   call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
4262  endif
4263
4264  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4265   " Active Banner support
4266"   call Decho("active banner handling",'~'.expand("<slnum>"))
4267   NetrwKeepj norm! 0
4268   let dirname= "./"
4269   let curline= getline('.')
4270
4271   if curline =~# '"\s*Sorted by\s'
4272    NetrwKeepj norm s
4273    let s:netrw_skipbrowse= 1
4274    echo 'Pressing "s" also works'
4275
4276   elseif curline =~# '"\s*Sort sequence:'
4277    let s:netrw_skipbrowse= 1
4278    echo 'Press "S" to edit sorting sequence'
4279
4280   elseif curline =~# '"\s*Quick Help:'
4281    NetrwKeepj norm ?
4282    let s:netrw_skipbrowse= 1
4283
4284   elseif curline =~# '"\s*\%(Hiding\|Showing\):'
4285    NetrwKeepj norm a
4286    let s:netrw_skipbrowse= 1
4287    echo 'Pressing "a" also works'
4288
4289   elseif line("$") > w:netrw_bannercnt
4290    exe 'sil NetrwKeepj '.w:netrw_bannercnt
4291   endif
4292
4293  elseif w:netrw_liststyle == s:THINLIST
4294"   call Decho("thin column handling",'~'.expand("<slnum>"))
4295   NetrwKeepj norm! 0
4296   let dirname= substitute(getline('.'),'\t -->.*$','','')
4297
4298  elseif w:netrw_liststyle == s:LONGLIST
4299"   call Decho("long column handling",'~'.expand("<slnum>"))
4300   NetrwKeepj norm! 0
4301   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
4302
4303  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4304"   call Decho("treelist handling",'~'.expand("<slnum>"))
4305   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4306   let dirname= substitute(dirname,'\t -->.*$','','')
4307
4308  else
4309"   call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4310   let dirname= getline('.')
4311
4312   if !exists("b:netrw_cpf")
4313    let b:netrw_cpf= 0
4314    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
4315    call histdel("/",-1)
4316"   "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4317   endif
4318
4319"   call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4320   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4321"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4322"   call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4323   if filestart == 0
4324    NetrwKeepj norm! 0ma
4325   else
4326    call cursor(line("."),filestart+1)
4327    NetrwKeepj norm! ma
4328   endif
4329   let rega= @a
4330   let eofname= filestart + b:netrw_cpf + 1
4331   if eofname <= col("$")
4332    call cursor(line("."),filestart+b:netrw_cpf+1)
4333    NetrwKeepj norm! "ay`a
4334   else
4335    NetrwKeepj norm! "ay$
4336   endif
4337   let dirname = @a
4338   let @a      = rega
4339"   call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4340   let dirname= substitute(dirname,'\s\+$','','e')
4341"   call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4342  endif
4343
4344  " symlinks are indicated by a trailing "@".  Remove it before further processing.
4345  let dirname= substitute(dirname,"@$","","")
4346
4347  " executables are indicated by a trailing "*".  Remove it before further processing.
4348  let dirname= substitute(dirname,"\*$","","")
4349
4350  let &l:sol= keepsol
4351
4352"  call Dret("s:NetrwGetWord <".dirname.">")
4353  return dirname
4354endfun
4355
4356" ---------------------------------------------------------------------
4357" s:NetrwListSettings: make standard settings for making a netrw listing {{{2
4358"                      g:netrw_bufsettings will be used after the listing is produced.
4359"                      Called by s:NetrwGetBuffer()
4360fun! s:NetrwListSettings(islocal)
4361"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4362"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4363  let fname= bufname("%")
4364"  "  call Decho("(NetrwListSettings) setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
4365  "              nobl noma nomod nonu noma nowrap ro   nornu  (std g:netrw_bufsettings)
4366  setl bt=nofile nobl ma         nonu      nowrap noro nornu
4367  call s:NetrwBufRename(fname)
4368  if g:netrw_use_noswf
4369   setl noswf
4370  endif
4371"  call Dredir("ls!","s:NetrwListSettings")
4372"  call Decho("(NetrwListSettings) exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
4373  exe "setl ts=".(g:netrw_maxfilenamelen+1)
4374  setl isk+=.,~,-
4375  if g:netrw_fastbrowse > a:islocal
4376   setl bh=hide
4377  else
4378   setl bh=delete
4379  endif
4380"  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>"))
4381"  call Dret("s:NetrwListSettings")
4382endfun
4383
4384" ---------------------------------------------------------------------
4385"  s:NetrwListStyle: change list style (thin - long - wide - tree) {{{2
4386"  islocal=0: remote browsing
4387"         =1: local browsing
4388fun! s:NetrwListStyle(islocal)
4389"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
4390
4391  let ykeep             = @@
4392  let fname             = s:NetrwGetWord()
4393  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
4394  let svpos            = winsaveview()
4395"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4396  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
4397"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
4398"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>"))
4399"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
4400
4401  " repoint t:netrw_lexbufnr if appropriate
4402  if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
4403"   call Decho("set repointlexbufnr to true!")
4404   let repointlexbufnr= 1
4405  endif
4406
4407  if w:netrw_liststyle == s:THINLIST
4408   " use one column listing
4409"   call Decho("use one column list",'~'.expand("<slnum>"))
4410   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4411
4412  elseif w:netrw_liststyle == s:LONGLIST
4413   " use long list
4414"   call Decho("use long list",'~'.expand("<slnum>"))
4415   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
4416
4417  elseif w:netrw_liststyle == s:WIDELIST
4418   " give wide list
4419"   call Decho("use wide list",'~'.expand("<slnum>"))
4420   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4421
4422  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4423"   call Decho("use tree list",'~'.expand("<slnum>"))
4424   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4425
4426  else
4427   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4428   let g:netrw_liststyle = s:THINLIST
4429   let w:netrw_liststyle = g:netrw_liststyle
4430   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
4431  endif
4432  setl ma noro
4433"  call Decho("setl ma noro",'~'.expand("<slnum>"))
4434
4435  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
4436"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4437  sil! NetrwKeepj %d _
4438  " following prevents tree listing buffer from being marked "modified"
4439"  call Decho("setl nomod",'~'.expand("<slnum>"))
4440  setl nomod
4441"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4442
4443  " refresh the listing
4444"  call Decho("refresh the listing",'~'.expand("<slnum>"))
4445  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4446  NetrwKeepj call s:NetrwCursor()
4447
4448  " repoint t:netrw_lexbufnr if appropriate
4449  if exists("repointlexbufnr")
4450   let t:netrw_lexbufnr= bufnr("%")
4451"   call Decho("repoint t:netrw_lexbufnr to #".t:netrw_lexbufnr)
4452  endif
4453
4454  " restore position; keep cursor on the filename
4455"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4456  NetrwKeepj call winrestview(svpos)
4457  let @@= ykeep
4458
4459"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
4460endfun
4461
4462" ---------------------------------------------------------------------
4463" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4464fun! s:NetrwBannerCtrl(islocal)
4465"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
4466
4467  let ykeep= @@
4468  " toggle the banner (enable/suppress)
4469  let g:netrw_banner= !g:netrw_banner
4470
4471  " refresh the listing
4472  let svpos= winsaveview()
4473"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4474  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4475
4476  " keep cursor on the filename
4477  if g:netrw_banner && exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt
4478   let fname= s:NetrwGetWord()
4479   sil NetrwKeepj $
4480   let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4481" "  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4482   if result <= 0 && exists("w:netrw_bannercnt")
4483    exe "NetrwKeepj ".w:netrw_bannercnt
4484   endif
4485  endif
4486  let @@= ykeep
4487"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
4488endfun
4489
4490" ---------------------------------------------------------------------
4491" s:NetrwBookmark: supports :NetrwMB[!] [file]s                 {{{2
4492"
4493"  No bang: enters files/directories into Netrw's bookmark system
4494"   No argument and in netrw buffer:
4495"     if there are marked files: bookmark marked files
4496"     otherwise                : bookmark file/directory under cursor
4497"   No argument and not in netrw buffer: bookmarks current open file
4498"   Has arguments: globs them individually and bookmarks them
4499"
4500"  With bang: deletes files/directories from Netrw's bookmark system
4501fun! s:NetrwBookmark(del,...)
4502"  call Dfunc("s:NetrwBookmark(del=".a:del.",...) a:0=".a:0)
4503  if a:0 == 0
4504   if &ft == "netrw"
4505    let curbufnr = bufnr("%")
4506
4507    if exists("s:netrwmarkfilelist_{curbufnr}")
4508     " for every filename in the marked list
4509"     call Decho("bookmark every filename in marked list",'~'.expand("<slnum>"))
4510     let svpos  = winsaveview()
4511"     call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4512     let islocal= expand("%") !~ '^\a\{3,}://'
4513     for fname in s:netrwmarkfilelist_{curbufnr}
4514      if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4515     endfor
4516     let curdir  = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4517     call s:NetrwUnmarkList(curbufnr,curdir)
4518     NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./'))
4519"     call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4520     NetrwKeepj call winrestview(svpos)
4521    else
4522     let fname= s:NetrwGetWord()
4523     if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4524    endif
4525
4526   else
4527    " bookmark currently open file
4528"    call Decho("bookmark currently open file",'~'.expand("<slnum>"))
4529    let fname= expand("%")
4530    if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4531   endif
4532
4533  else
4534   " bookmark specified files
4535   "  attempts to infer if working remote or local
4536   "  by deciding if the current file begins with an url
4537   "  Globbing cannot be done remotely.
4538   let islocal= expand("%") !~ '^\a\{3,}://'
4539"   call Decho("bookmark specified file".((a:0>1)? "s" : ""),'~'.expand("<slnum>"))
4540   let i = 1
4541   while i <= a:0
4542    if islocal
4543     if v:version > 704 || (v:version == 704 && has("patch656"))
4544      let mbfiles= glob(fnameescape(a:{i}),0,1,1)
4545     else
4546      let mbfiles= glob(fnameescape(a:{i}),0,1)
4547     endif
4548    else
4549     let mbfiles= [a:{i}]
4550    endif
4551"    call Decho("mbfiles".string(mbfiles),'~'.expand("<slnum>"))
4552    for mbfile in mbfiles
4553"     call Decho("mbfile<".mbfile.">",'~'.expand("<slnum>"))
4554     if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4555    endfor
4556    let i= i + 1
4557   endwhile
4558  endif
4559
4560  " update the menu
4561  call s:NetrwBookmarkMenu()
4562
4563"  call Dret("s:NetrwBookmark")
4564endfun
4565
4566" ---------------------------------------------------------------------
4567" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4568"                      .2.[cnt] for bookmarks, and
4569"                      .3.[cnt] for history
4570"                      (see s:NetrwMenu())
4571fun! s:NetrwBookmarkMenu()
4572  if !exists("s:netrw_menucnt")
4573   return
4574  endif
4575"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhist_cnt." menucnt=".s:netrw_menucnt)
4576
4577  " the following test assures that gvim is running, has menus available, and has menus enabled.
4578  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
4579   if exists("g:NetrwTopLvlMenu")
4580"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4581    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4582    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4583   endif
4584   if !exists("s:netrw_initbookhist")
4585    call s:NetrwBookHistRead()
4586   endif
4587
4588   " show bookmarked places
4589   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4590    let cnt= 1
4591    for bmd in g:netrw_bookmarklist
4592"     call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd,'~'.expand("<slnum>"))
4593     let bmd= escape(bmd,g:netrw_menu_escape)
4594
4595     " show bookmarks for goto menu
4596     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
4597
4598     " show bookmarks for deletion menu
4599     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
4600     let cnt= cnt + 1
4601    endfor
4602
4603   endif
4604
4605   " show directory browsing history
4606   if g:netrw_dirhistmax > 0
4607    let cnt     = g:netrw_dirhist_cnt
4608    let first   = 1
4609    let histcnt = 0
4610    while ( first || cnt != g:netrw_dirhist_cnt )
4611     let histcnt  = histcnt + 1
4612     let priority = g:netrw_dirhist_cnt + histcnt
4613     if exists("g:netrw_dirhist_{cnt}")
4614      let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4615"     call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir,'~'.expand("<slnum>"))
4616      exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
4617     endif
4618     let first = 0
4619     let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
4620     if cnt < 0
4621      let cnt= cnt + g:netrw_dirhistmax
4622     endif
4623    endwhile
4624   endif
4625
4626  endif
4627"  call Dret("NetrwBookmarkMenu")
4628endfun
4629
4630" ---------------------------------------------------------------------
4631"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4632"                       directory and a new directory name.  Also, if the
4633"                       "new directory name" is actually a file,
4634"                       NetrwBrowseChgDir() edits the file.
4635fun! s:NetrwBrowseChgDir(islocal,newdir,...)
4636"  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 : "").">")
4637"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4638
4639  let ykeep= @@
4640  if !exists("b:netrw_curdir")
4641   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4642   " and the current window is the NetrwMessage window.
4643   let @@= ykeep
4644"   call Decho("b:netrw_curdir doesn't exist!",'~'.expand("<slnum>"))
4645"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
4646"   call Dredir("ls!","s:NetrwBrowseChgDir")
4647"   call Dret("s:NetrwBrowseChgDir")
4648   return
4649  endif
4650"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
4651
4652  " NetrwBrowseChgDir: save options and initialize {{{3
4653"  call Decho("saving options",'~'.expand("<slnum>"))
4654  call s:SavePosn(s:netrw_posn)
4655  NetrwKeepj call s:NetrwOptionSave("s:")
4656  NetrwKeepj call s:NetrwSafeOptions()
4657  if (has("win32") || has("win95") || has("win64") || has("win16"))
4658   let dirname = substitute(b:netrw_curdir,'\\','/','ge')
4659  else
4660   let dirname = b:netrw_curdir
4661  endif
4662  let newdir    = a:newdir
4663  let dolockout = 0
4664  let dorestore = 1
4665"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
4666
4667  " ignore <cr>s when done in the banner
4668"  call Decho('ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("<slnum>"))
4669  if g:netrw_banner
4670"   call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>"))
4671   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4672    if getline(".") =~# 'Quick Help'
4673"     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>"))
4674     let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4675"     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>"))
4676     setl ma noro nowrap
4677     NetrwKeepj call setline(line('.'),'"   Quick Help: <F1>:help  '.s:QuickHelp[g:netrw_quickhelp])
4678     setl noma nomod nowrap
4679     NetrwKeepj call s:NetrwOptionRestore("s:")
4680"     call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4681    endif
4682   endif
4683"  else " Decho
4684"   call Decho("(s:NetrwBrowseChgdir) g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("<slnum>"))
4685  endif
4686
4687  " set up o/s-dependent directory recognition pattern
4688  if has("amiga")
4689   let dirpat= '[\/:]$'
4690  else
4691   let dirpat= '[\/]$'
4692  endif
4693"  call Decho("set up o/s-dependent directory recognition pattern: dirname<".dirname.">  dirpat<".dirpat.">",'~'.expand("<slnum>"))
4694
4695  if dirname !~ dirpat
4696   " apparently vim is "recognizing" that it is in a directory and
4697   " is removing the trailing "/".  Bad idea, so let's put it back.
4698   let dirname= dirname.'/'
4699"   call Decho("adjusting dirname<".dirname.'>  (put trailing "/" back)','~'.expand("<slnum>"))
4700  endif
4701
4702"  call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>"))
4703  if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
4704   " ------------------------------
4705   " NetrwBrowseChgDir: edit a file {{{3
4706   " ------------------------------
4707"   call Decho('edit-a-file: case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>"))
4708
4709   " save position for benefit of Rexplore
4710   let s:rexposn_{bufnr("%")}= winsaveview()
4711"   call Decho("edit-a-file: saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
4712"   call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
4713"   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>"))
4714
4715   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4716"    call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("<slnum>"))
4717"    call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("<slnum>"))
4718    let dirname= s:NetrwTreeDir(a:islocal)
4719    if dirname =~ '/$'
4720     let dirname= dirname.newdir
4721    else
4722     let dirname= dirname."/".newdir
4723    endif
4724"    call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>"))
4725"    call Decho("edit-a-file: tree listing",'~'.expand("<slnum>"))
4726   elseif newdir =~ '^\(/\|\a:\)'
4727"    call Decho("edit-a-file: handle an url or path starting with /: <".newdir.">",'~'.expand("<slnum>"))
4728    let dirname= newdir
4729   else
4730    let dirname= s:ComposePath(dirname,newdir)
4731   endif
4732"   call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>"))
4733   " this lets netrw#BrowseX avoid the edit
4734   if a:0 < 1
4735"    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>"))
4736    NetrwKeepj call s:NetrwOptionRestore("s:")
4737    let curdir= b:netrw_curdir
4738    if !exists("s:didsplit")
4739"     call Decho("edit-a-file: s:didsplit does not exist; g:netrw_browse_split=".string(g:netrw_browse_split)." win#".winnr(),'~'.expand("<slnum>"))
4740     if type(g:netrw_browse_split) == 3
4741      " open file in server
4742      " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4743"      call Decho("edit-a-file: open file in server",'~'.expand("<slnum>"))
4744      call s:NetrwServerEdit(a:islocal,dirname)
4745"      call Dret("s:NetrwBrowseChgDir")
4746      return
4747     elseif g:netrw_browse_split == 1
4748      " horizontally splitting the window first
4749"      call Decho("edit-a-file: horizontally splitting window prior to edit",'~'.expand("<slnum>"))
4750      keepalt new
4751      if !&ea
4752       keepalt wincmd _
4753      endif
4754      call s:SetRexDir(a:islocal,curdir)
4755     elseif g:netrw_browse_split == 2
4756      " vertically splitting the window first
4757"      call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>"))
4758      keepalt rightb vert new
4759      if !&ea
4760       keepalt wincmd |
4761      endif
4762      call s:SetRexDir(a:islocal,curdir)
4763     elseif g:netrw_browse_split == 3
4764      " open file in new tab
4765"      call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>"))
4766      keepalt tabnew
4767      if !exists("b:netrw_curdir")
4768       let b:netrw_curdir= getcwd()
4769      endif
4770      call s:SetRexDir(a:islocal,curdir)
4771     elseif g:netrw_browse_split == 4
4772      " act like "P" (ie. open previous window)
4773"      call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>"))
4774      if s:NetrwPrevWinOpen(2) == 3
4775       let @@= ykeep
4776"       call Dret("s:NetrwBrowseChgDir")
4777       return
4778      endif
4779      call s:SetRexDir(a:islocal,curdir)
4780     else
4781      " handling a file, didn't split, so remove menu
4782"      call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>"))
4783      call s:NetrwMenu(0)
4784      " optional change to window
4785      if g:netrw_chgwin >= 1
4786"       call Decho("edit-a-file: changing window to #".g:netrw_chgwin,'~'.expand("<slnum>"))
4787       if winnr("$")+1 == g:netrw_chgwin
4788	" if g:netrw_chgwin is set to one more than the last window, then
4789	" vertically split the last window to make that window available.
4790	let curwin= winnr()
4791	exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4792	vs
4793	exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4794       endif
4795       exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4796      endif
4797      call s:SetRexDir(a:islocal,curdir)
4798     endif
4799    endif
4800
4801    " the point where netrw actually edits the (local) file
4802    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4803    " no keepalt to support  :e #  to return to a directory listing
4804    if a:islocal
4805"     call Decho("edit-a-file: edit local file: exe e! ".fnameescape(dirname),'~'.expand("<slnum>"))
4806     " some like c-^ to return to the last edited file
4807     " others like c-^ to return to the netrw buffer
4808     if exists("g:netrw_altfile") && g:netrw_altfile
4809      exe "NetrwKeepj keepalt e! ".fnameescape(dirname)
4810     else
4811      exe "NetrwKeepj e! ".fnameescape(dirname)
4812     endif
4813"     call Decho("edit-a-file: after e! ".dirname.": hidden=".&hidden." bufhidden<".&bufhidden."> mod=".&mod,'~'.expand("<slnum>"))
4814     call s:NetrwCursor()
4815     if &hidden || &bufhidden == "hide"
4816      " file came from vim's hidden storage.  Don't "restore" options with it.
4817      let dorestore= 0
4818     endif
4819    else
4820"     call Decho("edit-a-file: remote file: NetrwBrowse will edit it",'~'.expand("<slnum>"))
4821    endif
4822    let dolockout= 1
4823
4824    " handle g:Netrw_funcref -- call external-to-netrw functions
4825    "   This code will handle g:Netrw_funcref as an individual function reference
4826    "   or as a list of function references.  It will ignore anything that's not
4827    "   a function reference.  See  :help Funcref  for information about function references.
4828    if exists("g:Netrw_funcref")
4829"     call Decho("edit-a-file: handle optional Funcrefs",'~'.expand("<slnum>"))
4830     if type(g:Netrw_funcref) == 2
4831"      call Decho("edit-a-file: handling a g:Netrw_funcref",'~'.expand("<slnum>"))
4832      NetrwKeepj call g:Netrw_funcref()
4833     elseif type(g:Netrw_funcref) == 3
4834"      call Decho("edit-a-file: handling a list of g:Netrw_funcrefs",'~'.expand("<slnum>"))
4835      for Fncref in g:Netrw_funcref
4836       if type(FncRef) == 2
4837        NetrwKeepj call FncRef()
4838       endif
4839      endfor
4840     endif
4841    endif
4842   endif
4843
4844  elseif newdir =~ '^/'
4845   " ----------------------------------------------------
4846   " NetrwBrowseChgDir: just go to the new directory spec {{{3
4847   " ----------------------------------------------------
4848"   call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("<slnum>"))
4849   let dirname = newdir
4850   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4851   NetrwKeepj call s:NetrwOptionRestore("s:")
4852   norm! m`
4853
4854  elseif newdir == './'
4855   " ---------------------------------------------
4856   " NetrwBrowseChgDir: refresh the directory list {{{3
4857   " ---------------------------------------------
4858"   call Decho('refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("<slnum>"))
4859   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4860   norm! m`
4861
4862  elseif newdir == '../'
4863   " --------------------------------------
4864   " NetrwBrowseChgDir: go up one directory {{{3
4865   " --------------------------------------
4866"   call Decho('go-up: case "go up one directory": newdir == "../"','~'.expand("<slnum>"))
4867
4868   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4869    " force a refresh
4870"    call Decho("go-up: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4871"    call Decho("go-up: setl noro ma",'~'.expand("<slnum>"))
4872    setl noro ma
4873    NetrwKeepj %d _
4874   endif
4875
4876   if has("amiga")
4877    " amiga
4878"    call Decho('go-up: case "go up one directory": newdir == "../" and amiga','~'.expand("<slnum>"))
4879    if a:islocal
4880     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
4881     let dirname= substitute(dirname,'/$','','')
4882    else
4883     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
4884    endif
4885"    call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4886
4887   elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
4888    " windows
4889    if a:islocal
4890     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4891     if dirname == ""
4892      let dirname= '/'
4893     endif
4894    else
4895     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4896    endif
4897    if dirname =~ '^\a:$'
4898     let dirname= dirname.'/'
4899    endif
4900"    call Decho("go-up: windows: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4901
4902   else
4903    " unix or cygwin
4904"    call Decho('go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("<slnum>"))
4905    if a:islocal
4906     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4907     if dirname == ""
4908      let dirname= '/'
4909     endif
4910    else
4911     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4912    endif
4913"    call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4914   endif
4915   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4916   norm m`
4917
4918  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4919   " --------------------------------------
4920   " NetrwBrowseChgDir: Handle Tree Listing {{{3
4921   " --------------------------------------
4922"   call Decho('tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("<slnum>"))
4923   " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
4924"   call Decho("tree-list: setl noro ma",'~'.expand("<slnum>"))
4925   setl noro ma
4926   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
4927"    call Decho("tree-list: clear buffer<".expand("%")."> with :%d  (force refresh)",'~'.expand("<slnum>"))
4928    NetrwKeepj %d _
4929   endif
4930   let treedir      = s:NetrwTreeDir(a:islocal)
4931"   call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>"))
4932   let s:treecurpos = winsaveview()
4933   let haskey       = 0
4934"   call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
4935
4936   " search treedict for tree dir as-is
4937"   call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("<slnum>"))
4938   if has_key(w:netrw_treedict,treedir)
4939"    call Decho('tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>"))
4940    let haskey= 1
4941   else
4942"    call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
4943   endif
4944
4945   " search treedict for treedir with a [/@] appended
4946"   call Decho("tree-list: search treedict for treedir with a [/@] appended",'~'.expand("<slnum>"))
4947   if !haskey && treedir !~ '[/@]$'
4948    if has_key(w:netrw_treedict,treedir."/")
4949     let treedir= treedir."/"
4950"     call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
4951     let haskey = 1
4952    else
4953"     call Decho('tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("<slnum>"))
4954    endif
4955   endif
4956
4957   " search treedict for treedir with any trailing / elided
4958"   call Decho("tree-list: search treedict for treedir with any trailing / elided",'~'.expand("<slnum>"))
4959   if !haskey && treedir =~ '/$'
4960    let treedir= substitute(treedir,'/$','','')
4961    if has_key(w:netrw_treedict,treedir)
4962"     call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
4963     let haskey = 1
4964    else
4965"     call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
4966    endif
4967   endif
4968
4969"   call Decho("haskey=".haskey,'~'.expand("<slnum>"))
4970   if haskey
4971    " close tree listing for selected subdirectory
4972"    call Decho("tree-list: closing selected subdirectory<".dirname.">",'~'.expand("<slnum>"))
4973    call remove(w:netrw_treedict,treedir)
4974"    call Decho("tree-list: removed     entry<".treedir."> from treedict",'~'.expand("<slnum>"))
4975"    call Decho("tree-list: yielding treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
4976    let dirname= w:netrw_treetop
4977   else
4978    " go down one directory
4979    let dirname= substitute(treedir,'/*$','/','')
4980"    call Decho("tree-list: go down one dir: treedir<".treedir.">",'~'.expand("<slnum>"))
4981"    call Decho("tree-list: ...            : dirname<".dirname.">",'~'.expand("<slnum>"))
4982   endif
4983   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4984"   call Decho("setting s:treeforceredraw to true",'~'.expand("<slnum>"))
4985   let s:treeforceredraw = 1
4986
4987  else
4988   " ----------------------------------------
4989   " NetrwBrowseChgDir: Go down one directory {{{3
4990   " ----------------------------------------
4991   let dirname    = s:ComposePath(dirname,newdir)
4992"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("<slnum>"))
4993   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4994   norm m`
4995  endif
4996
4997 " --------------------------------------
4998 " NetrwBrowseChgDir: Restore and Cleanup {{{3
4999 " --------------------------------------
5000  if dorestore
5001   " dorestore is zero'd when a local file was hidden or bufhidden;
5002   " in such a case, we want to keep whatever settings it may have.
5003"   call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("<slnum>"))
5004   NetrwKeepj call s:NetrwOptionRestore("s:")
5005"  else " Decho
5006"   call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>"))
5007  endif
5008  if dolockout && dorestore
5009"   call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>"))
5010   if filewritable(dirname)
5011"    call Decho("restore: doing modification lockout settings: ma nomod noro",'~'.expand("<slnum>"))
5012"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5013    setl ma noro nomod
5014"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5015   else
5016"    call Decho("restore: doing modification lockout settings: ma nomod ro",'~'.expand("<slnum>"))
5017"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
5018    setl ma ro nomod
5019"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
5020   endif
5021  endif
5022  call s:RestorePosn(s:netrw_posn)
5023  let @@= ykeep
5024
5025"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
5026  return dirname
5027endfun
5028
5029" ---------------------------------------------------------------------
5030" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
5031"    for thin, long, and wide: cursor placed just after banner
5032"    for tree, keeps cursor on current filename
5033fun! s:NetrwBrowseUpDir(islocal)
5034"  call Dfunc("s:NetrwBrowseUpDir(islocal=".a:islocal.")")
5035  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
5036   " this test needed because occasionally this function seems to be incorrectly called
5037   " when multiple leftmouse clicks are taken when atop the one line help in the banner.
5038   " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
5039   " directories.
5040"   call Dret("s:NetrwBrowseUpDir : cursor not in file area")
5041   return
5042  endif
5043
5044  norm! 0
5045  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5046"   call Decho("case: treestyle",'~'.expand("<slnum>"))
5047   let curline= getline(".")
5048   let swwline= winline() - 1
5049   if exists("w:netrw_treetop")
5050    let b:netrw_curdir= w:netrw_treetop
5051   elseif exists("b:netrw_curdir")
5052    let w:netrw_treetop= b:netrw_curdir
5053   else
5054    let w:netrw_treetop= getcwd()
5055    let b:netrw_curdir = w:netrw_treetop
5056   endif
5057   let curfile = getline(".")
5058   let curpath = s:NetrwTreePath(w:netrw_treetop)
5059   if a:islocal
5060    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5061   else
5062    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5063   endif
5064"   call Decho("looking for curfile<^".s:treedepthstring.curfile.">",'~'.expand("<slnum>"))
5065"   call Decho("having      curpath<".curpath.">",'~'.expand("<slnum>"))
5066   if w:netrw_treetop == '/'
5067     keepj call search('^\M'.curfile,"w")
5068   elseif curfile == '../'
5069     keepj call search('^\M'.curfile,"wb")
5070   else
5071"    call Decho("search(^\\M".s:treedepthstring.curfile.") backwards"))
5072    while 1
5073     keepj call search('^\M'.s:treedepthstring.curfile,"wb")
5074     let treepath= s:NetrwTreePath(w:netrw_treetop)
5075"     call Decho("..current treepath<".treepath.">",'~'.expand("<slnum>"))
5076     if treepath == curpath
5077      break
5078     endif
5079    endwhile
5080   endif
5081
5082  else
5083"   call Decho("case: not treestyle",'~'.expand("<slnum>"))
5084   call s:SavePosn(s:netrw_posn)
5085   if exists("b:netrw_curdir")
5086    let curdir= b:netrw_curdir
5087   else
5088    let curdir= expand(getcwd())
5089   endif
5090   if a:islocal
5091    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
5092   else
5093    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
5094   endif
5095   call s:RestorePosn(s:netrw_posn)
5096   let curdir= substitute(curdir,'^.*[\/]','','')
5097   call search('\<'.curdir.'/','wc')
5098  endif
5099"  call Dret("s:NetrwBrowseUpDir")
5100endfun
5101
5102" ---------------------------------------------------------------------
5103" netrw#BrowseX:  (implements "x") executes a special "viewer" script or program for the {{{2
5104"              given filename; typically this means given their extension.
5105"              0=local, 1=remote
5106fun! netrw#BrowseX(fname,remote)
5107"  call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")")
5108
5109  " if its really just a local directory, then do a "gf" instead
5110  if (a:remote == 0 && isdirectory(a:fname)) || (a:remote == 1 && a:fname =~ '/$' && a:fname !~ '^https\=:')
5111   norm! gf
5112"   call Dret("(netrw#BrowseX) did gf instead")
5113  endif
5114
5115  let ykeep      = @@
5116  let screenposn = winsaveview()
5117"  call Decho("(netrw#BrowseX) saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5118
5119  " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
5120  let awkeep     = &aw
5121  set noaw
5122
5123  " special core dump handler
5124  if a:fname =~ '/core\(\.\d\+\)\=$'
5125   if exists("g:Netrw_corehandler")
5126    if type(g:Netrw_corehandler) == 2
5127     " g:Netrw_corehandler is a function reference (see :help Funcref)
5128"     call Decho("(netrw#BrowseX) g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
5129     call g:Netrw_corehandler(s:NetrwFile(a:fname))
5130    elseif type(g:Netrw_corehandler) == 3
5131     " g:Netrw_corehandler is a List of function references (see :help Funcref)
5132"     call Decho("(netrw#BrowseX) g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
5133     for Fncref in g:Netrw_corehandler
5134      if type(FncRef) == 2
5135       call FncRef(a:fname)
5136      endif
5137     endfor
5138    endif
5139"    call Decho("(netrw#BrowseX) restoring posn: screenposn<".string(screenposn).">,'~'.expand("<slnum>"))"
5140    call winrestview(screenposn)
5141    let @@= ykeep
5142    let &aw= awkeep
5143"    call Dret("netrw#BrowseX : coredump handler invoked")
5144    return
5145   endif
5146  endif
5147
5148  " set up the filename
5149  " (lower case the extension, make a local copy of a remote file)
5150  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5151  if has("win32") || has("win95") || has("win64") || has("win16")
5152   let exten= substitute(exten,'^.*$','\L&\E','')
5153  endif
5154  if exten =~ "[\\/]"
5155   let exten= ""
5156  endif
5157"  call Decho("(netrw#BrowseX) exten<".exten.">",'~'.expand("<slnum>"))
5158
5159  if a:remote == 1
5160   " create a local copy
5161"   call Decho("(netrw#BrowseX) remote: a:remote=".a:remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
5162   setl bh=delete
5163   call netrw#NetRead(3,a:fname)
5164   " attempt to rename tempfile
5165   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5166   let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5167"   call Decho("(netrw#BrowseX) basename<".basename.">",'~'.expand("<slnum>"))
5168"   call Decho("(netrw#BrowseX) newname <".newname.">",'~'.expand("<slnum>"))
5169   if s:netrw_tmpfile != newname && newname != ""
5170    if rename(s:netrw_tmpfile,newname) == 0
5171     " renaming succeeded
5172"     call Decho("(netrw#BrowseX) renaming succeeded (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5173     let fname= newname
5174    else
5175     " renaming failed
5176"     call Decho("(netrw#BrowseX) renaming failed (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
5177     let fname= s:netrw_tmpfile
5178    endif
5179   else
5180    let fname= s:netrw_tmpfile
5181   endif
5182  else
5183"   call Decho("(netrw#BrowseX) local: a:remote=".a:remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
5184   let fname= a:fname
5185   " special ~ handler for local
5186   if fname =~ '^\~' && expand("$HOME") != ""
5187"    call Decho('invoking special ~ handler','~'.expand("<slnum>"))
5188    let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5189   endif
5190  endif
5191"  call Decho("(netrw#BrowseX) fname<".fname.">",'~'.expand("<slnum>"))
5192"  call Decho("(netrw#BrowseX) exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
5193
5194  " set up redirection (avoids browser messages)
5195  " by default, g:netrw_suppress_gx_mesg is true
5196  if g:netrw_suppress_gx_mesg
5197   if &srr =~ "%s"
5198    if (has("win32") || has("win95") || has("win64") || has("win16"))
5199     let redir= substitute(&srr,"%s","nul","")
5200    else
5201     let redir= substitute(&srr,"%s","/dev/null","")
5202    endif
5203   elseif (has("win32") || has("win95") || has("win64") || has("win16"))
5204    let redir= &srr . "nul"
5205   else
5206    let redir= &srr . "/dev/null"
5207   endif
5208  endif
5209"  call Decho("(netrw#BrowseX) set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
5210
5211  " extract any viewing options.  Assumes that they're set apart by quotes.
5212"  call Decho("(netrw#BrowseX) extract any viewing options",'~'.expand("<slnum>"))
5213  if exists("g:netrw_browsex_viewer")
5214"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5215   if g:netrw_browsex_viewer =~ '\s'
5216    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5217    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5218    let oviewer = ''
5219    let cnt     = 1
5220    while !executable(viewer) && viewer != oviewer
5221     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5222     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5223     let cnt     = cnt + 1
5224     let oviewer = viewer
5225"     call Decho("(netrw#BrowseX) !exe: viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5226    endwhile
5227   else
5228    let viewer  = g:netrw_browsex_viewer
5229    let viewopt = ""
5230   endif
5231"   call Decho("(netrw#BrowseX) viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5232  endif
5233
5234  " execute the file handler
5235"  call Decho("(netrw#BrowseX) execute the file handler (if any)",'~'.expand("<slnum>"))
5236  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
5237"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5238   let ret= netrwFileHandlers#Invoke(exten,fname)
5239
5240  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
5241"   call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5242   call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
5243   let ret= v:shell_error
5244
5245  elseif has("win32") || has("win64")
5246"   call Decho("(netrw#BrowseX) win".(has("win32")? "32" : "64")",'~'.expand("<slnum>"))
5247   if executable("start")
5248    call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5249   elseif executable("rundll32")
5250    call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5251   else
5252    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5253   endif
5254   " call inputsave()|call input("Press <cr> to continue")|call inputrestore()
5255   let ret= v:shell_error
5256
5257  elseif has("win32unix")
5258   let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
5259"   call Decho("(netrw#BrowseX) cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
5260   if executable("start")
5261    call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5262   elseif executable("rundll32")
5263    call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5264   elseif executable("cygstart")
5265    call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
5266   else
5267    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5268   endif
5269   " call inputsave()|call input("Press <cr> to continue")|call inputrestore()
5270   let ret= v:shell_error
5271
5272  elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
5273"   call Decho("(netrw#BrowseX) unix and kfmclient",'~'.expand("<slnum>"))
5274   call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
5275   let ret= v:shell_error
5276
5277  elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
5278"   call Decho("(netrw#BrowseX) unix, exo-open, xdg-open",'~'.expand("<slnum>"))
5279   call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir)
5280   let ret= v:shell_error
5281
5282  elseif has("unix") && $DESKTOP_SESSION == "mate" && executable("atril")
5283"   call Decho("(netrw#BrowseX) unix and atril",'~'.expand("<slnum>"))
5284   call s:NetrwExe("sil !atril ".s:ShellEscape(fname,1).redir)
5285   let ret= v:shell_error
5286
5287  elseif has("unix") && executable("xdg-open")
5288"   call Decho("(netrw#BrowseX) unix and xdg-open",'~'.expand("<slnum>"))
5289   call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir)
5290   let ret= v:shell_error
5291
5292  elseif has("macunix") && executable("open")
5293"   call Decho("(netrw#BrowseX) macunix and open",'~'.expand("<slnum>"))
5294   call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
5295   let ret= v:shell_error
5296
5297  else
5298   " netrwFileHandlers#Invoke() always returns 0
5299   let ret= netrwFileHandlers#Invoke(exten,fname)
5300  endif
5301
5302  " if unsuccessful, attempt netrwFileHandlers#Invoke()
5303  if ret
5304   let ret= netrwFileHandlers#Invoke(exten,fname)
5305  endif
5306
5307  " restoring redraw! after external file handlers
5308  redraw!
5309
5310  " cleanup: remove temporary file,
5311  "          delete current buffer if success with handler,
5312  "          return to prior buffer (directory listing)
5313  "          Feb 12, 2008: had to de-activiate removal of
5314  "          temporary file because it wasn't getting seen.
5315"  if a:remote == 1 && fname != a:fname
5316""   call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
5317"   call s:NetrwDelete(fname)
5318"  endif
5319
5320  if a:remote == 1
5321   setl bh=delete bt=nofile
5322   if g:netrw_use_noswf
5323    setl noswf
5324   endif
5325   exe "sil! NetrwKeepj norm! \<c-o>"
5326"   redraw!
5327  endif
5328"  call Decho("(netrw#BrowseX) restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5329  call winrestview(screenposn)
5330  let @@ = ykeep
5331  let &aw= awkeep
5332
5333"  call Dret("netrw#BrowseX")
5334endfun
5335
5336" ---------------------------------------------------------------------
5337" netrw#GX: gets word under cursor for gx support {{{2
5338"           See also: netrw#BrowseXVis
5339"                     netrw#BrowseX
5340fun! netrw#GX()
5341"  call Dfunc("netrw#GX()")
5342  if &ft == "netrw"
5343   let fname= s:NetrwGetWord()
5344  else
5345   let fname= expand((exists("g:netrw_gx")? g:netrw_gx : '<cfile>'))
5346  endif
5347"  call Dret("netrw#GX <".fname.">")
5348  return fname
5349endfun
5350
5351" ---------------------------------------------------------------------
5352" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5353fun! netrw#BrowseXVis()
5354"  call Dfunc("netrw#BrowseXVis()")
5355  let atkeep = @@
5356  norm! gvy
5357"  call Decho("@@<".@@.">",'~'.expand("<slnum>"))
5358  call netrw#BrowseX(@@,netrw#CheckIfRemote(@@))
5359  let @@     = atkeep
5360"  call Dret("netrw#BrowseXVis")
5361endfun
5362
5363" ---------------------------------------------------------------------
5364" s:NetrwBufRename: renames a buffer without the side effect of retaining an unlisted buffer having the old name {{{2
5365"                   Using the file command on a "[No Name]" buffer does not seem to cause the old "[No Name]" buffer
5366"                   to become an unlisted buffer, so in that case don't bwipe it.
5367fun! s:NetrwBufRename(newname)
5368"  call Dfunc("s:NetrwBufRename(newname<".a:newname.">) buf(%)#".bufnr("%")."<".bufname(bufnr("%")).">")
5369"  call Dredir("ls!","s:NetrwBufRename (before rename)")
5370  let oldbufname= bufname(bufnr("%"))
5371"  call Decho("buf#".bufnr("%").": oldbufname<".oldbufname.">",'~'.expand("<slnum>"))
5372  if oldbufname != a:newname
5373"   call Decho("do renaming (oldbufname != a:newname)",'~'.expand("<slnum>"))
5374   exe 'sil! keepj keepalt file '.fnameescape(a:newname)
5375   let oldbufnr= bufnr(oldbufname)
5376   if oldbufname != "" && oldbufnr != -1
5377    exe "bwipe! ".oldbufnr
5378   endif
5379  endif
5380"  call Dredir("ls!","s:NetrwBufRename (after rename)")
5381"  call Dret("s:NetrwBufRename : buf#".bufnr("%").": oldname<".oldbufname."> newname<".a:newname."> expand(%)<".expand("%").">")
5382endfun
5383
5384" ---------------------------------------------------------------------
5385" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5386fun! netrw#CheckIfRemote(...)
5387"  call Dfunc("netrw#CheckIfRemote() a:0=".a:0)
5388  if a:0 > 0
5389   let curfile= a:1
5390  else
5391   let curfile= expand("%")
5392  endif
5393"  call Decho("curfile<".curfile.">")
5394  if curfile =~ '^\a\{3,}://'
5395"   call Dret("netrw#CheckIfRemote 1")
5396   return 1
5397  else
5398"   call Dret("netrw#CheckIfRemote 0")
5399   return 0
5400  endif
5401endfun
5402
5403" ---------------------------------------------------------------------
5404" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5405fun! s:NetrwChgPerm(islocal,curdir)
5406"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
5407  let ykeep  = @@
5408  call inputsave()
5409  let newperm= input("Enter new permission: ")
5410  call inputrestore()
5411  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5412  let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5413"  call Decho("chgperm<".chgperm.">",'~'.expand("<slnum>"))
5414  call system(chgperm)
5415  if v:shell_error != 0
5416   NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5417  endif
5418  if a:islocal
5419   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5420  endif
5421  let @@= ykeep
5422"  call Dret("s:NetrwChgPerm")
5423endfun
5424
5425" ---------------------------------------------------------------------
5426" s:CheckIfKde: checks if kdeinit is running {{{2
5427"    Returns 0: kdeinit not running
5428"            1: kdeinit is  running
5429fun! s:CheckIfKde()
5430"  call Dfunc("s:CheckIfKde()")
5431  " seems kde systems often have gnome-open due to dependencies, even though
5432  " gnome-open's subsidiary display tools are largely absent.  Kde systems
5433  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
5434  if !exists("s:haskdeinit")
5435   if has("unix") && executable("ps") && !has("win32unix")
5436    let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5437    if v:shell_error
5438     let s:haskdeinit = 0
5439    endif
5440   else
5441    let s:haskdeinit= 0
5442   endif
5443"   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5444  endif
5445
5446"  call Dret("s:CheckIfKde ".s:haskdeinit)
5447  return s:haskdeinit
5448endfun
5449
5450" ---------------------------------------------------------------------
5451" s:NetrwClearExplore: clear explore variables (if any) {{{2
5452fun! s:NetrwClearExplore()
5453"  call Dfunc("s:NetrwClearExplore()")
5454  2match none
5455  if exists("s:explore_match")        |unlet s:explore_match        |endif
5456  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
5457  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5458  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
5459  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
5460  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
5461  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5462  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
5463  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
5464"   redraw!
5465  echo " "
5466  echo " "
5467"  call Dret("s:NetrwClearExplore")
5468endfun
5469
5470" ---------------------------------------------------------------------
5471" s:NetrwExploreListUniq: {{{2
5472fun! s:NetrwExploreListUniq(explist)
5473"  call Dfunc("s:NetrwExploreListUniq(explist<".string(a:explist).">)")
5474
5475  " this assumes that the list is already sorted
5476  let newexplist= []
5477  for member in a:explist
5478   if !exists("uniqmember") || member != uniqmember
5479    let uniqmember = member
5480    let newexplist = newexplist + [ member ]
5481   endif
5482  endfor
5483
5484"  call Dret("s:NetrwExploreListUniq newexplist<".string(newexplist).">")
5485  return newexplist
5486endfun
5487
5488" ---------------------------------------------------------------------
5489" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5490fun! s:NetrwForceChgDir(islocal,newdir)
5491"  call Dfunc("s:NetrwForceChgDir(islocal=".a:islocal." newdir<".a:newdir.">)")
5492  let ykeep= @@
5493  if a:newdir !~ '/$'
5494   " ok, looks like force is needed to get directory-style treatment
5495   if a:newdir =~ '@$'
5496    let newdir= substitute(a:newdir,'@$','/','')
5497   elseif a:newdir =~ '[*=|\\]$'
5498    let newdir= substitute(a:newdir,'.$','/','')
5499   else
5500    let newdir= a:newdir.'/'
5501   endif
5502"   call Decho("adjusting newdir<".newdir."> due to gd",'~'.expand("<slnum>"))
5503  else
5504   " should already be getting treatment as a directory
5505   let newdir= a:newdir
5506  endif
5507  let newdir= s:NetrwBrowseChgDir(a:islocal,newdir)
5508  call s:NetrwBrowse(a:islocal,newdir)
5509  let @@= ykeep
5510"  call Dret("s:NetrwForceChgDir")
5511endfun
5512
5513" ---------------------------------------------------------------------
5514" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5515"     direntry: this is the name of the directory.  Will be fnameescape'd to prevent wildcard handling by glob()
5516"     expr    : this is the expression to follow the directory.  Will use s:ComposePath()
5517"     pare    =1: remove the current directory from the resulting glob() filelist
5518"             =0: leave  the current directory   in the resulting glob() filelist
5519fun! s:NetrwGlob(direntry,expr,pare)
5520"  call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")")
5521  if netrw#CheckIfRemote()
5522   keepalt 1sp
5523   keepalt enew
5524   let keep_liststyle    = w:netrw_liststyle
5525   let w:netrw_liststyle = s:THINLIST
5526   if s:NetrwRemoteListing() == 0
5527    keepj keepalt %s@/@@
5528    let filelist= getline(1,$)
5529    q!
5530   else
5531    " remote listing error -- leave treedict unchanged
5532    let filelist= w:netrw_treedict[a:direntry]
5533   endif
5534   let w:netrw_liststyle= keep_liststyle
5535  elseif v:version > 704 || (v:version == 704 && has("patch656"))
5536   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1)
5537   if a:pare
5538    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5539   endif
5540  else
5541   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1)
5542   if a:pare
5543    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5544   endif
5545  endif
5546"  call Dret("s:NetrwGlob ".string(filelist))
5547  return filelist
5548endfun
5549
5550" ---------------------------------------------------------------------
5551" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5552fun! s:NetrwForceFile(islocal,newfile)
5553"  call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)")
5554  if a:newfile =~ '[/@*=|\\]$'
5555   let newfile= substitute(a:newfile,'.$','','')
5556  else
5557   let newfile= a:newfile
5558  endif
5559  if a:islocal
5560   call s:NetrwBrowseChgDir(a:islocal,newfile)
5561  else
5562   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile))
5563  endif
5564"  call Dret("s:NetrwForceFile")
5565endfun
5566
5567" ---------------------------------------------------------------------
5568" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5569"          and switches the hiding mode.  The actual hiding is done by
5570"          s:NetrwListHide().
5571"             g:netrw_hide= 0: show all
5572"                           1: show not-hidden files
5573"                           2: show hidden files only
5574fun! s:NetrwHide(islocal)
5575"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
5576  let ykeep= @@
5577  let svpos= winsaveview()
5578"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5579
5580  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5581"   call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>"))
5582"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5583
5584   " hide the files in the markfile list
5585   for fname in s:netrwmarkfilelist_{bufnr("%")}
5586"    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>"))
5587    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5588     " remove fname from hiding list
5589     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5590     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5591     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5592"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5593    else
5594     " append fname to hiding list
5595     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5596      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5597     else
5598      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5599     endif
5600"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5601    endif
5602   endfor
5603   NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5604   let g:netrw_hide= 1
5605
5606  else
5607
5608   " switch between show-all/show-not-hidden/show-hidden
5609   let g:netrw_hide=(g:netrw_hide+1)%3
5610   exe "NetrwKeepj norm! 0"
5611   if g:netrw_hide && g:netrw_list_hide == ""
5612    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5613    let @@= ykeep
5614"    call Dret("NetrwHide")
5615    return
5616   endif
5617  endif
5618
5619  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5620"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5621  NetrwKeepj call winrestview(svpos)
5622  let @@= ykeep
5623"  call Dret("NetrwHide")
5624endfun
5625
5626" ---------------------------------------------------------------------
5627" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5628fun! s:NetrwHideEdit(islocal)
5629"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
5630
5631  let ykeep= @@
5632  " save current cursor position
5633  let svpos= winsaveview()
5634"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5635
5636  " get new hiding list from user
5637  call inputsave()
5638  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5639  call inputrestore()
5640  let g:netrw_list_hide= newhide
5641"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5642
5643  " refresh the listing
5644  sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
5645
5646  " restore cursor position
5647"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5648  call winrestview(svpos)
5649  let @@= ykeep
5650
5651"  call Dret("NetrwHideEdit")
5652endfun
5653
5654" ---------------------------------------------------------------------
5655" s:NetrwHidden: invoked by "gh" {{{2
5656fun! s:NetrwHidden(islocal)
5657"  call Dfunc("s:NetrwHidden()")
5658  let ykeep= @@
5659  "  save current position
5660  let svpos  = winsaveview()
5661"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5662
5663  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5664   " remove .file pattern from hiding list
5665"   call Decho("remove .file pattern from hiding list",'~'.expand("<slnum>"))
5666   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5667  elseif s:Strlen(g:netrw_list_hide) >= 1
5668"   call Decho("add .file pattern from hiding list",'~'.expand("<slnum>"))
5669   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5670  else
5671"   call Decho("set .file pattern as hiding list",'~'.expand("<slnum>"))
5672   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5673  endif
5674  if g:netrw_list_hide =~ '^,'
5675   let g:netrw_list_hide= strpart(g:netrw_list_hide,1)
5676  endif
5677
5678  " refresh screen and return to saved position
5679  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5680"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5681  NetrwKeepj call winrestview(svpos)
5682  let @@= ykeep
5683"  call Dret("s:NetrwHidden")
5684endfun
5685
5686" ---------------------------------------------------------------------
5687"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5688fun! s:NetrwHome()
5689  if exists("g:netrw_home")
5690   let home= expand(g:netrw_home)
5691  else
5692   " go to vim plugin home
5693   for home in split(&rtp,',') + ['']
5694    if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5695     let basehome= substitute(home,'[/\\]\.vim$','','')
5696     if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5697     let home= basehome."/.vim"
5698     break
5699    endif
5700   endfor
5701   if home == ""
5702    " just pick the first directory
5703    let home= substitute(&rtp,',.*$','','')
5704   endif
5705   if (has("win32") || has("win95") || has("win64") || has("win16"))
5706    let home= substitute(home,'/','\\','g')
5707   endif
5708  endif
5709  " insure that the home directory exists
5710  if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5711"   call Decho("insure that the home<".home."> directory exists")
5712   if exists("g:netrw_mkdir")
5713"    call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")")
5714    call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5715   else
5716"    call Decho("mkdir(".home.")")
5717    call mkdir(home)
5718   endif
5719  endif
5720  let g:netrw_home= home
5721  return home
5722endfun
5723
5724" ---------------------------------------------------------------------
5725" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5726fun! s:NetrwLeftmouse(islocal)
5727  if exists("s:netrwdrag")
5728   return
5729  endif
5730  if &ft != "netrw"
5731   return
5732  endif
5733"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
5734
5735  let ykeep= @@
5736  " check if the status bar was clicked on instead of a file/directory name
5737  while getchar(0) != 0
5738   "clear the input stream
5739  endwhile
5740  call feedkeys("\<LeftMouse>")
5741  let c          = getchar()
5742  let mouse_lnum = v:mouse_lnum
5743  let wlastline  = line('w$')
5744  let lastline   = line('$')
5745"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr(),'~'.expand("<slnum>"))
5746"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0),'~'.expand("<slnum>"))
5747  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5748   " appears to be a status bar leftmouse click
5749   let @@= ykeep
5750"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
5751   return
5752  endif
5753   " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5754   " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5755   " without this test when its disabled.
5756   " May 26, 2014: edit file, :Lex, resize window -- causes refresh.  Reinstated a modified test.  See if problems develop.
5757"   call Decho("v:mouse_col=".v:mouse_col." col#".col('.')." virtcol#".virtcol('.')." col($)#".col("$")." virtcol($)#".virtcol("$"),'~'.expand("<slnum>"))
5758   if v:mouse_col > virtcol('.')
5759    let @@= ykeep
5760"    call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
5761    return
5762   endif
5763
5764  if a:islocal
5765   if exists("b:netrw_curdir")
5766    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
5767   endif
5768  else
5769   if exists("b:netrw_curdir")
5770    NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5771   endif
5772  endif
5773  let @@= ykeep
5774"  call Dret("s:NetrwLeftmouse")
5775endfun
5776
5777" ---------------------------------------------------------------------
5778" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5779fun! s:NetrwCLeftmouse(islocal)
5780  if &ft != "netrw"
5781   return
5782  endif
5783"  call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")")
5784  call s:NetrwMarkFileTgt(a:islocal)
5785"  call Dret("s:NetrwCLeftmouse")
5786endfun
5787
5788" ---------------------------------------------------------------------
5789" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER  (implements <c-r>){{{2
5790"   a:islocal=0 : <c-r> not used, remote
5791"   a:islocal=1 : <c-r> not used, local
5792"   a:islocal=2 : <c-r>     used, remote
5793"   a:islocal=3 : <c-r>     used, local
5794fun! s:NetrwServerEdit(islocal,fname)
5795"  call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5796  let islocal = a:islocal%2      " =0: remote           =1: local
5797  let ctrlr   = a:islocal >= 2   " =0: <c-r> not used   =1: <c-r> used
5798"  call Decho("islocal=".islocal." ctrlr=".ctrlr,'~'.expand("<slnum>"))
5799
5800  if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5801   " handle directories in the local window -- not in the remote vim server
5802   " user must have closed the NETRWSERVER window.  Treat as normal editing from netrw.
5803"   call Decho("handling directory in client window",'~'.expand("<slnum>"))
5804   let g:netrw_browse_split= 0
5805   if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
5806    let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5807    unlet s:netrw_browse_split_{winnr()}
5808   endif
5809   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5810"   call Dret("s:NetrwServerEdit")
5811   return
5812  endif
5813
5814"  call Decho("handling file in server window",'~'.expand("<slnum>"))
5815  if has("clientserver") && executable("gvim")
5816"   call Decho("has clientserver and gvim",'~'.expand("<slnum>"))
5817
5818    if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
5819"     call Decho("g:netrw_browse_split=".string(g:netrw_browse_split),'~'.expand("<slnum>"))
5820     let srvrname = g:netrw_browse_split[0]
5821     let tabnum   = g:netrw_browse_split[1]
5822     let winnum   = g:netrw_browse_split[2]
5823
5824     if serverlist() !~ '\<'.srvrname.'\>'
5825"      call Decho("server not available; ctrlr=".ctrlr,'~'.expand("<slnum>"))
5826
5827      if !ctrlr
5828       " user must have closed the server window and the user did not use <c-r>, but
5829       " used something like <cr>.
5830"       call Decho("user must have closed server AND did not use ctrl-r",'~'.expand("<slnum>"))
5831       if exists("g:netrw_browse_split")
5832	unlet g:netrw_browse_split
5833       endif
5834       let g:netrw_browse_split= 0
5835       if exists("s:netrw_browse_split_".winnr())
5836        let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5837       endif
5838       call s:NetrwBrowseChgDir(islocal,a:fname)
5839"       call Dret("s:NetrwServerEdit")
5840       return
5841
5842      elseif has("win32") && executable("start")
5843       " start up remote netrw server under windows
5844"       call Decho("starting up gvim server<".srvrname."> for windows",'~'.expand("<slnum>"))
5845       call system("start gvim --servername ".srvrname)
5846
5847      else
5848       " start up remote netrw server under linux
5849"       call Decho("starting up gvim server<".srvrname.">",'~'.expand("<slnum>"))
5850       call system("gvim --servername ".srvrname)
5851      endif
5852     endif
5853
5854"     call Decho("srvrname<".srvrname."> tabnum=".tabnum." winnum=".winnum." server-editing<".a:fname.">",'~'.expand("<slnum>"))
5855     call remote_send(srvrname,":tabn ".tabnum."\<cr>")
5856     call remote_send(srvrname,":".winnum."wincmd w\<cr>")
5857     call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5858
5859    else
5860
5861     if serverlist() !~ '\<'.g:netrw_servername.'\>'
5862
5863      if !ctrlr
5864"       call Decho("server<".g:netrw_servername."> not available and ctrl-r not used",'~'.expand("<slnum>"))
5865       if exists("g:netrw_browse_split")
5866	unlet g:netrw_browse_split
5867       endif
5868       let g:netrw_browse_split= 0
5869       call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5870"       call Dret("s:NetrwServerEdit")
5871       return
5872
5873      else
5874"       call Decho("server<".g:netrw_servername."> not available but ctrl-r used",'~'.expand("<slnum>"))
5875       if has("win32") && executable("start")
5876        " start up remote netrw server under windows
5877"        call Decho("starting up gvim server<".g:netrw_servername."> for windows",'~'.expand("<slnum>"))
5878        call system("start gvim --servername ".g:netrw_servername)
5879       else
5880        " start up remote netrw server under linux
5881"        call Decho("starting up gvim server<".g:netrw_servername.">",'~'.expand("<slnum>"))
5882        call system("gvim --servername ".g:netrw_servername)
5883       endif
5884      endif
5885     endif
5886
5887     while 1
5888      try
5889"       call Decho("remote-send: e ".a:fname,'~'.expand("<slnum>"))
5890       call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5891       break
5892      catch /^Vim\%((\a\+)\)\=:E241/
5893       sleep 200m
5894      endtry
5895     endwhile
5896
5897     if exists("g:netrw_browse_split")
5898      if type(g:netrw_browse_split) != 3
5899        let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
5900       endif
5901      unlet g:netrw_browse_split
5902     endif
5903     let g:netrw_browse_split= [g:netrw_servername,1,1]
5904    endif
5905
5906   else
5907    call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
5908   endif
5909
5910"  call Dret("s:NetrwServerEdit")
5911endfun
5912
5913" ---------------------------------------------------------------------
5914" s:NetrwSLeftmouse: marks the file under the cursor.  May be dragged to select additional files {{{2
5915fun! s:NetrwSLeftmouse(islocal)
5916  if &ft != "netrw"
5917   return
5918  endif
5919"  call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
5920
5921  let s:ngw= s:NetrwGetWord()
5922  call s:NetrwMarkFile(a:islocal,s:ngw)
5923
5924"  call Dret("s:NetrwSLeftmouse")
5925endfun
5926
5927" ---------------------------------------------------------------------
5928" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
5929"                   Used to mark multiple files.
5930fun! s:NetrwSLeftdrag(islocal)
5931"  call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
5932  if !exists("s:netrwdrag")
5933   let s:netrwdrag = winnr()
5934   if a:islocal
5935    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
5936   else
5937    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
5938   endif
5939  endif
5940  let ngw = s:NetrwGetWord()
5941  if !exists("s:ngw") || s:ngw != ngw
5942   call s:NetrwMarkFile(a:islocal,ngw)
5943  endif
5944  let s:ngw= ngw
5945"  call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5946endfun
5947
5948" ---------------------------------------------------------------------
5949" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
5950fun! s:NetrwSLeftrelease(islocal)
5951"  call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5952  if exists("s:netrwdrag")
5953   nunmap <s-leftrelease>
5954   let ngw = s:NetrwGetWord()
5955   if !exists("s:ngw") || s:ngw != ngw
5956    call s:NetrwMarkFile(a:islocal,ngw)
5957   endif
5958   if exists("s:ngw")
5959    unlet s:ngw
5960   endif
5961   unlet s:netrwdrag
5962  endif
5963"  call Dret("s:NetrwSLeftrelease")
5964endfun
5965
5966" ---------------------------------------------------------------------
5967" s:NetrwListHide: uses [range]g~...~d to delete files that match comma {{{2
5968" separated patterns given in g:netrw_list_hide
5969fun! s:NetrwListHide()
5970"  call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
5971"  call Decho("initial: ".string(getline(w:netrw_bannercnt,'$')))
5972  let ykeep= @@
5973
5974  " find a character not in the "hide" string to use as a separator for :g and :v commands
5975  " How-it-works: take the hiding command, convert it into a range.  Duplicate
5976  " characters don't matter.  Remove all such characters from the '/~...90'
5977  " string.  Use the first character left as a separator character.
5978  let listhide= g:netrw_list_hide
5979  let sep     = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
5980"  call Decho("sep=".sep,'~'.expand("<slnum>"))
5981
5982  while listhide != ""
5983   if listhide =~ ','
5984    let hide     = substitute(listhide,',.*$','','e')
5985    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
5986   else
5987    let hide     = listhide
5988    let listhide = ""
5989   endif
5990"   call Decho("hide<".hide."> listhide<".listhide.'>','~'.expand("<slnum>"))
5991
5992   " Prune the list by hiding any files which match
5993   if g:netrw_hide == 1
5994"    call Decho("..hiding<".hide.">",'~'.expand("<slnum>"))
5995    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
5996   elseif g:netrw_hide == 2
5997"    call Decho("..showing<".hide.">",'~'.expand("<slnum>"))
5998    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
5999   endif
6000"   call Decho("..result: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6001  endwhile
6002  if g:netrw_hide == 2
6003   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
6004"   call Decho("..v KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6005   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
6006"   call Decho("..g KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
6007  endif
6008
6009  " remove any blank lines that have somehow remained.
6010  " This seems to happen under Windows.
6011  exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
6012
6013  let @@= ykeep
6014"  call Dret("s:NetrwListHide")
6015endfun
6016
6017" ---------------------------------------------------------------------
6018" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
6019"                 implements the "d" mapping.
6020fun! s:NetrwMakeDir(usrhost)
6021"  call Dfunc("s:NetrwMakeDir(usrhost<".a:usrhost.">)")
6022
6023  let ykeep= @@
6024  " get name of new directory from user.  A bare <CR> will skip.
6025  " if its currently a directory, also request will be skipped, but with
6026  " a message.
6027  call inputsave()
6028  let newdirname= input("Please give directory name: ")
6029  call inputrestore()
6030"  call Decho("newdirname<".newdirname.">",'~'.expand("<slnum>"))
6031
6032  if newdirname == ""
6033   let @@= ykeep
6034"   call Dret("s:NetrwMakeDir : user aborted with bare <cr>")
6035   return
6036  endif
6037
6038  if a:usrhost == ""
6039"   call Decho("local mkdir",'~'.expand("<slnum>"))
6040
6041   " Local mkdir:
6042   " sanity checks
6043   let fullnewdir= b:netrw_curdir.'/'.newdirname
6044"   call Decho("fullnewdir<".fullnewdir.">",'~'.expand("<slnum>"))
6045   if isdirectory(s:NetrwFile(fullnewdir))
6046    if !exists("g:netrw_quiet")
6047     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
6048    endif
6049    let @@= ykeep
6050"    call Dret("s:NetrwMakeDir : directory<".newdirname."> exists previously")
6051    return
6052   endif
6053   if s:FileReadable(fullnewdir)
6054    if !exists("g:netrw_quiet")
6055     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
6056    endif
6057    let @@= ykeep
6058"    call Dret("s:NetrwMakeDir : file<".newdirname."> exists previously")
6059    return
6060   endif
6061
6062   " requested new local directory is neither a pre-existing file or
6063   " directory, so make it!
6064   if exists("*mkdir")
6065    if has("unix")
6066     call mkdir(fullnewdir,"p",xor(0777, system("umask")))
6067    else
6068     call mkdir(fullnewdir,"p")
6069    endif
6070   else
6071    let netrw_origdir= s:NetrwGetcwd(1)
6072    if s:NetrwLcd(b:netrw_curdir)
6073"    call Dret("s:NetrwMakeDir : lcd failure")
6074     return
6075    endif
6076"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("<slnum>"))
6077    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(newdirname,1))
6078    if v:shell_error != 0
6079     let @@= ykeep
6080     call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6081"     call Dret("s:NetrwMakeDir : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
6082     return
6083    endif
6084    if !g:netrw_keepdir
6085"     call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
6086     if s:NetrwLcd(netrw_origdir)
6087"     call Dret("s:NetrwBrowse : lcd failure")
6088      return
6089     endif
6090    endif
6091   endif
6092
6093   if v:shell_error == 0
6094    " refresh listing
6095"    call Decho("refresh listing",'~'.expand("<slnum>"))
6096    let svpos= winsaveview()
6097"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6098    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
6099"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6100    call winrestview(svpos)
6101   elseif !exists("g:netrw_quiet")
6102    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
6103   endif
6104"   redraw!
6105
6106  elseif !exists("b:netrw_method") || b:netrw_method == 4
6107   " Remote mkdir:  using ssh
6108"   call Decho("remote mkdir",'~'.expand("<slnum>"))
6109   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
6110   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
6111   call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
6112   if v:shell_error == 0
6113    " refresh listing
6114    let svpos= winsaveview()
6115"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6116    NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6117"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6118    NetrwKeepj call winrestview(svpos)
6119   elseif !exists("g:netrw_quiet")
6120    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
6121   endif
6122"   redraw!
6123
6124  elseif b:netrw_method == 2
6125   " Remote mkdir:  using ftp+.netrc
6126   let svpos= winsaveview()
6127"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6128"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6129   if exists("b:netrw_fname")
6130"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6131    let remotepath= b:netrw_fname
6132   else
6133    let remotepath= ""
6134   endif
6135   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6136   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6137"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6138   NetrwKeepj call winrestview(svpos)
6139
6140  elseif b:netrw_method == 3
6141   " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
6142   let svpos= winsaveview()
6143"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6144"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
6145   if exists("b:netrw_fname")
6146"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
6147    let remotepath= b:netrw_fname
6148   else
6149    let remotepath= ""
6150   endif
6151   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6152   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6153"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6154   NetrwKeepj call winrestview(svpos)
6155  endif
6156
6157  let @@= ykeep
6158"  call Dret("s:NetrwMakeDir")
6159endfun
6160
6161" ---------------------------------------------------------------------
6162" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
6163fun! s:TreeSqueezeDir(islocal)
6164"  call Dfunc("s:TreeSqueezeDir(islocal=".a:islocal.")")
6165  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6166   " its a tree-listing style
6167   let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
6168   let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
6169   let depth    = strchars(substitute(curdepth,' ','','g'))
6170   let srch     = -1
6171"   call Decho("curdepth<".curdepth.'>','~'.expand("<slnum>"))
6172"   call Decho("depth   =".depth,'~'.expand("<slnum>"))
6173"   call Decho("stopline#".stopline,'~'.expand("<slnum>"))
6174"   call Decho("curline#".line(".")."<".getline('.').'>','~'.expand("<slnum>"))
6175   if depth >= 2
6176    NetrwKeepj norm! 0
6177    let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
6178    let srch      = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
6179"    call Decho("curdepthm1<".curdepthm1.'>','~'.expand("<slnum>"))
6180"    call Decho("case depth>=2: srch<".srch.'>','~'.expand("<slnum>"))
6181   elseif depth == 1
6182    NetrwKeepj norm! 0
6183    let treedepthchr= substitute(s:treedepthstring,' ','','')
6184    let srch        = search('^[^'.treedepthchr.']','bW',stopline)
6185"    call Decho("case depth==1: srch<".srch.'>','~'.expand("<slnum>"))
6186   endif
6187   if srch > 0
6188"    call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
6189    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord()))
6190    exe srch
6191   endif
6192  endif
6193"  call Dret("s:TreeSqueezeDir")
6194endfun
6195
6196" ---------------------------------------------------------------------
6197" s:NetrwMaps: {{{2
6198fun! s:NetrwMaps(islocal)
6199"  call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6200
6201  " mouse <Plug> maps: {{{3
6202  if g:netrw_mousemaps && g:netrw_retmap
6203"   call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
6204   if !hasmapto("<Plug>NetrwReturn")
6205    if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
6206"     call Decho("making map for 2-leftmouse",'~'.expand("<slnum>"))
6207     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
6208    elseif maparg("<c-leftmouse>","n") == ""
6209"     call Decho("making map for c-leftmouse",'~'.expand("<slnum>"))
6210     nmap <unique> <silent> <c-leftmouse>	<Plug>NetrwReturn
6211    endif
6212   endif
6213   nno <silent> <Plug>NetrwReturn	:Rexplore<cr>
6214"   call Decho("made <Plug>NetrwReturn map",'~'.expand("<slnum>"))
6215  endif
6216
6217  " generate default <Plug> maps {{{3
6218  if !hasmapto('<Plug>NetrwHide')              |nmap <buffer> <silent> <nowait> a	<Plug>NetrwHide_a|endif
6219  if !hasmapto('<Plug>NetrwBrowseUpDir')       |nmap <buffer> <silent> <nowait> -	<Plug>NetrwBrowseUpDir |endif
6220  if !hasmapto('<Plug>NetrwOpenFile')          |nmap <buffer> <silent> <nowait> %	<Plug>NetrwOpenFile|endif
6221  if !hasmapto('<Plug>NetrwBadd_cb')           |nmap <buffer> <silent> <nowait> cb	<Plug>NetrwBadd_cb|endif
6222  if !hasmapto('<Plug>NetrwBadd_cB')           |nmap <buffer> <silent> <nowait> cB	<Plug>NetrwBadd_cB|endif
6223  if !hasmapto('<Plug>NetrwLcd')               |nmap <buffer> <silent> <nowait> cd	<Plug>NetrwLcd|endif
6224  if !hasmapto('<Plug>NetrwSetChgwin')         |nmap <buffer> <silent> <nowait> C	<Plug>NetrwSetChgwin|endif
6225  if !hasmapto('<Plug>NetrwRefresh')           |nmap <buffer> <silent> <nowait> <c-l>	<Plug>NetrwRefresh|endif
6226  if !hasmapto('<Plug>NetrwLocalBrowseCheck')  |nmap <buffer> <silent> <nowait> <cr>	<Plug>NetrwLocalBrowseCheck|endif
6227  if !hasmapto('<Plug>NetrwServerEdit')        |nmap <buffer> <silent> <nowait> <c-r>	<Plug>NetrwServerEdit|endif
6228  if !hasmapto('<Plug>NetrwMakeDir')           |nmap <buffer> <silent> <nowait> d	<Plug>NetrwMakeDir|endif
6229  if !hasmapto('<Plug>NetrwBookHistHandler_gb')|nmap <buffer> <silent> <nowait> gb	<Plug>NetrwBookHistHandler_gb|endif
6230" ---------------------------------------------------------------------
6231"  if !hasmapto('<Plug>NetrwForceChgDir')       |nmap <buffer> <silent> <nowait> gd	<Plug>NetrwForceChgDir|endif
6232"  if !hasmapto('<Plug>NetrwForceFile')         |nmap <buffer> <silent> <nowait> gf	<Plug>NetrwForceFile|endif
6233"  if !hasmapto('<Plug>NetrwHidden')            |nmap <buffer> <silent> <nowait> gh	<Plug>NetrwHidden|endif
6234"  if !hasmapto('<Plug>NetrwSetTreetop')        |nmap <buffer> <silent> <nowait> gn	<Plug>NetrwSetTreetop|endif
6235"  if !hasmapto('<Plug>NetrwChgPerm')           |nmap <buffer> <silent> <nowait> gp	<Plug>NetrwChgPerm|endif
6236"  if !hasmapto('<Plug>NetrwBannerCtrl')        |nmap <buffer> <silent> <nowait> I	<Plug>NetrwBannerCtrl|endif
6237"  if !hasmapto('<Plug>NetrwListStyle')         |nmap <buffer> <silent> <nowait> i	<Plug>NetrwListStyle|endif
6238"  if !hasmapto('<Plug>NetrwMarkMoveMF2Arglist')|nmap <buffer> <silent> <nowait> ma	<Plug>NetrwMarkMoveMF2Arglist|endif
6239"  if !hasmapto('<Plug>NetrwMarkMoveArglist2MF')|nmap <buffer> <silent> <nowait> mA	<Plug>NetrwMarkMoveArglist2MF|endif
6240"  if !hasmapto('<Plug>NetrwBookHistHandler_mA')|nmap <buffer> <silent> <nowait> mb	<Plug>NetrwBookHistHandler_mA|endif
6241"  if !hasmapto('<Plug>NetrwBookHistHandler_mB')|nmap <buffer> <silent> <nowait> mB	<Plug>NetrwBookHistHandler_mB|endif
6242"  if !hasmapto('<Plug>NetrwMarkFileCopy')      |nmap <buffer> <silent> <nowait> mc	<Plug>NetrwMarkFileCopy|endif
6243"  if !hasmapto('<Plug>NetrwMarkFileDiff')      |nmap <buffer> <silent> <nowait> md	<Plug>NetrwMarkFileDiff|endif
6244"  if !hasmapto('<Plug>NetrwMarkFileEdit')      |nmap <buffer> <silent> <nowait> me	<Plug>NetrwMarkFileEdit|endif
6245"  if !hasmapto('<Plug>NetrwMarkFile')          |nmap <buffer> <silent> <nowait> mf	<Plug>NetrwMarkFile|endif
6246"  if !hasmapto('<Plug>NetrwUnmarkList')        |nmap <buffer> <silent> <nowait> mF	<Plug>NetrwUnmarkList|endif
6247"  if !hasmapto('<Plug>NetrwMarkFileGrep')      |nmap <buffer> <silent> <nowait> mg	<Plug>NetrwMarkFileGrep|endif
6248"  if !hasmapto('<Plug>NetrwMarkHideSfx')       |nmap <buffer> <silent> <nowait> mh	<Plug>NetrwMarkHideSfx|endif
6249"  if !hasmapto('<Plug>NetrwMarkFileMove')      |nmap <buffer> <silent> <nowait> mm	<Plug>NetrwMarkFileMove|endif
6250"  if !hasmapto('<Plug>NetrwMarkFilePrint')     |nmap <buffer> <silent> <nowait> mp	<Plug>NetrwMarkFilePrint|endif
6251"  if !hasmapto('<Plug>NetrwMarkFileRegexp')    |nmap <buffer> <silent> <nowait> mr	<Plug>NetrwMarkFileRegexp|endif
6252"  if !hasmapto('<Plug>NetrwMarkFileSource')    |nmap <buffer> <silent> <nowait> ms	<Plug>NetrwMarkFileSource|endif
6253"  if !hasmapto('<Plug>NetrwMarkFileTag')       |nmap <buffer> <silent> <nowait> mT	<Plug>NetrwMarkFileTag|endif
6254"  if !hasmapto('<Plug>NetrwMarkFileTgt')       |nmap <buffer> <silent> <nowait> mt	<Plug>NetrwMarkFileTgt|endif
6255"  if !hasmapto('<Plug>NetrwUnMarkFile')        |nmap <buffer> <silent> <nowait> mu	<Plug>NetrwUnMarkFile|endif
6256"  if !hasmapto('<Plug>NetrwMarkFileVimCmd')    |nmap <buffer> <silent> <nowait> mv	<Plug>NetrwMarkFileVimCmd|endif
6257"  if !hasmapto('<Plug>NetrwMarkFileExe_mx')    |nmap <buffer> <silent> <nowait> mx	<Plug>NetrwMarkFileExe_mx|endif
6258"  if !hasmapto('<Plug>NetrwMarkFileExe_mX')    |nmap <buffer> <silent> <nowait> mX	<Plug>NetrwMarkFileExe_mX|endif
6259"  if !hasmapto('<Plug>NetrwMarkFileCompress')  |nmap <buffer> <silent> <nowait> mz	<Plug>NetrwMarkFileCompress|endif
6260"  if !hasmapto('<Plug>NetrwObtain')            |nmap <buffer> <silent> <nowait> O	<Plug>NetrwObtain|endif
6261"  if !hasmapto('<Plug>NetrwSplit_o')           |nmap <buffer> <silent> <nowait> o	<Plug>NetrwSplit_o|endif
6262"  if !hasmapto('<Plug>NetrwPreview')           |nmap <buffer> <silent> <nowait> p	<Plug>NetrwPreview|endif
6263"  if !hasmapto('<Plug>NetrwPrevWinOpen')       |nmap <buffer> <silent> <nowait> P	<Plug>NetrwPrevWinOpen|endif
6264"  if !hasmapto('<Plug>NetrwBookHistHandler_qb')|nmap <buffer> <silent> <nowait> qb	<Plug>NetrwBookHistHandler_qb|endif
6265"  if !hasmapto('<Plug>NetrwFileInfo')          |nmap <buffer> <silent> <nowait> qf	<Plug>NetrwFileInfo|endif
6266"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qF')   |nmap <buffer> <silent> <nowait> qF	<Plug>NetrwMarkFileQFEL_qF|endif
6267"  if !hasmapto('<Plug>NetrwMarkFileQFEL_qL')   |nmap <buffer> <silent> <nowait> qL	<Plug>NetrwMarkFileQFEL_qL|endif
6268"  if !hasmapto('<Plug>NetrwSortStyle')         |nmap <buffer> <silent> <nowait> s	<Plug>NetrwSortStyle|endif
6269"  if !hasmapto('<Plug>NetSortSequence')        |nmap <buffer> <silent> <nowait> S	<Plug>NetSortSequence|endif
6270"  if !hasmapto('<Plug>NetrwSetTgt_Tb')         |nmap <buffer> <silent> <nowait> Tb	<Plug>NetrwSetTgt_Tb|endif
6271"  if !hasmapto('<Plug>NetrwSetTgt_Th')         |nmap <buffer> <silent> <nowait> Th	<Plug>NetrwSetTgt_Th|endif
6272"  if !hasmapto('<Plug>NetrwSplit_t')           |nmap <buffer> <silent> <nowait> t	<Plug>NetrwSplit_t|endif
6273"  if !hasmapto('<Plug>NetrwBookHistHandler_u') |nmap <buffer> <silent> <nowait> u	<Plug>NetrwBookHistHandler_u|endif
6274"  if !hasmapto('<Plug>NetrwBookHistHandler_U') |nmap <buffer> <silent> <nowait> U	<Plug>NetrwBookHistHandler_U|endif
6275"  if !hasmapto('<Plug>NetrwSplit_v')           |nmap <buffer> <silent> <nowait> v	<Plug>NetrwSplit_v|endif
6276"  if !hasmapto('<Plug>NetrwBrowseX')           |nmap <buffer> <silent> <nowait> x	<Plug>NetrwBrowseX|endif
6277"  if !hasmapto('<Plug>NetrwLocalExecute')      |nmap <buffer> <silent> <nowait> X	<Plug>NetrwLocalExecute|endif
6278
6279  if a:islocal
6280"   call Decho("make local maps",'~'.expand("<slnum>"))
6281   " local normal-mode maps {{{3
6282   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(1)<cr>
6283   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6284   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(1)<cr>
6285   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(1,0)<cr>
6286   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(1,1)<cr>
6287   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6288   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6289   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6290   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6291   nnoremap <buffer> <silent> <Plug>NetrwMakeDir		:<c-u>call <SID>NetrwMakeDir("")<cr>
6292   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6293" ---------------------------------------------------------------------
6294   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6295   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6296   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
6297   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(0,<SID>NetrwGetWord())<cr>
6298   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6299   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6300   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(1)<cr>
6301   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6302   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6303   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6304   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6305   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6306   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6307   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6308   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6309   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6310   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6311   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6312   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6313   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6314   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6315   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6316   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6317   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6318   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6319   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6320   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6321   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6322   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6323   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(1)<cr>
6324   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(3)<cr>
6325   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6326   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6327   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6328   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6329   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6330   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6331   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(1)<cr>
6332   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(1)<cr>
6333   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6334   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(4)<cr>
6335   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6336   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6337   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6338   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(5)<cr>
6339   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6340   nnoremap <buffer> <silent> <nowait> X	:<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6341
6342   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>
6343   if !hasmapto('<Plug>NetrwHideEdit')
6344    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6345   endif
6346   nnoremap <buffer> <silent> <Plug>NetrwHideEdit		:call <SID>NetrwHideEdit(1)<cr>
6347   if !hasmapto('<Plug>NetrwRefresh')
6348    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6349   endif
6350   nnoremap <buffer> <silent> <Plug>NetrwRefresh		<c-l>:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr>
6351   if s:didstarstar || !mapcheck("<s-down>","n")
6352    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6353   endif
6354   if s:didstarstar || !mapcheck("<s-up>","n")
6355    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6356   endif
6357   if !hasmapto('<Plug>NetrwTreeSqueeze')
6358    nmap <buffer> <silent> <nowait> <s-cr>			<Plug>NetrwTreeSqueeze
6359   endif
6360   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze		:call <SID>TreeSqueezeDir(1)<cr>
6361   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6362   if g:netrw_mousemaps == 1
6363    nmap <buffer>			<leftmouse>   		<Plug>NetrwLeftmouse
6364    nmap <buffer>			<c-leftmouse>		<Plug>NetrwCLeftmouse
6365    nmap <buffer>			<middlemouse>		<Plug>NetrwMiddlemouse
6366    nmap <buffer>			<s-leftmouse>		<Plug>NetrwSLeftmouse
6367    nmap <buffer>			<s-leftdrag>		<Plug>NetrwSLeftdrag
6368    nmap <buffer>			<2-leftmouse>		<Plug>Netrw2Leftmouse
6369    imap <buffer>			<leftmouse>		<Plug>ILeftmouse
6370    imap <buffer>			<middlemouse>		<Plug>IMiddlemouse
6371    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
6372    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(1)<cr>
6373    nno  <buffer> <silent>		<Plug>NetrwMiddlemouse	<leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
6374    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(1)<cr>
6375    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(1)<cr>
6376    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6377    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6378    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6379   endif
6380   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6381   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6382   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6383   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("")<cr>'
6384   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6385   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6386   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6387   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6388
6389   " support user-specified maps
6390   call netrw#UserMaps(1)
6391
6392  else
6393   " remote normal-mode maps {{{3
6394"   call Decho("make remote maps",'~'.expand("<slnum>"))
6395   call s:RemotePathAnalysis(b:netrw_curdir)
6396   nnoremap <buffer> <silent> <Plug>NetrwHide_a			:<c-u>call <SID>NetrwHide(0)<cr>
6397   nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir		:<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6398   nnoremap <buffer> <silent> <Plug>NetrwOpenFile		:<c-u>call <SID>NetrwOpenFile(0)<cr>
6399   nnoremap <buffer> <silent> <Plug>NetrwBadd_cb		:<c-u>call <SID>NetrwBadd(0,0)<cr>
6400   nnoremap <buffer> <silent> <Plug>NetrwBadd_cB		:<c-u>call <SID>NetrwBadd(0,1)<cr>
6401   nnoremap <buffer> <silent> <Plug>NetrwLcd			:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6402   nnoremap <buffer> <silent> <Plug>NetrwSetChgwin		:<c-u>call <SID>NetrwSetChgwin()<cr>
6403   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6404   nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck	:<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6405   nnoremap <buffer> <silent> <Plug>NetrwServerEdit		:<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6406   nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6407" ---------------------------------------------------------------------
6408   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6409   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6410   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
6411   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6412   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6413   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(0)<cr>
6414   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6415   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6416   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6417   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6418   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6419   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6420   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6421   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6422   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6423   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6424   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6425   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6426   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6427   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6428   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6429   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6430   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6431   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6432   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6433   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6434   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6435   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6436   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(0)<cr>
6437   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(0)<cr>
6438   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6439   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6440   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6441   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6442   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6443   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6444   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>
6445   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(0)<cr>
6446   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(0)<cr>
6447   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6448   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(1)<cr>
6449   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6450   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6451   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6452   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(2)<cr>
6453   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6454   if !hasmapto('<Plug>NetrwHideEdit')
6455    nmap <buffer> <c-h> <Plug>NetrwHideEdit
6456   endif
6457   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
6458   if !hasmapto('<Plug>NetrwRefresh')
6459    nmap <buffer> <c-l> <Plug>NetrwRefresh
6460   endif
6461   if !hasmapto('<Plug>NetrwTreeSqueeze')
6462    nmap <buffer> <silent> <nowait> <s-cr>	<Plug>NetrwTreeSqueeze
6463   endif
6464   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze	:call <SID>TreeSqueezeDir(0)<cr>
6465
6466   let mapsafepath     = escape(s:path, s:netrw_map_escape)
6467   let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6468
6469   nnoremap <buffer> <silent> <Plug>NetrwRefresh	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6470   if g:netrw_mousemaps == 1
6471    nmap <buffer> <leftmouse>		<Plug>NetrwLeftmouse
6472    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
6473    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6474    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(0)<cr>
6475    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6476    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(0)<cr>
6477    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6478    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(0)<cr>
6479    nmap <middlemouse>			<Plug>NetrwMiddlemouse
6480    nno  <buffer> <silent>		<middlemouse>		<Plug>NetrwMiddlemouse <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
6481    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6482    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6483    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6484    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6485    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6486    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6487    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6488   endif
6489   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6490   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6491   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6492   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6493   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6494   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6495   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6496   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6497
6498   " support user-specified maps
6499   call netrw#UserMaps(0)
6500  endif " }}}3
6501
6502"  call Dret("s:NetrwMaps")
6503endfun
6504
6505" ---------------------------------------------------------------------
6506" s:NetrwCommands: set up commands 				{{{2
6507"  If -buffer, the command is only available from within netrw buffers
6508"  Otherwise, the command is available from any window, so long as netrw
6509"  has been used at least once in the session.
6510fun! s:NetrwCommands(islocal)
6511"  call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6512
6513  com! -nargs=* -complete=file -bang	NetrwMB	call s:NetrwBookmark(<bang>0,<f-args>)
6514  com! -nargs=*			    	NetrwC	call s:NetrwSetChgwin(<q-args>)
6515  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
6516  if a:islocal
6517   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(1,<f-args>)
6518  else
6519   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(0,<f-args>)
6520  endif
6521  com! -buffer -nargs=? -complete=file	MT	call s:NetrwMarkTarget(<q-args>)
6522
6523"  call Dret("s:NetrwCommands")
6524endfun
6525
6526" ---------------------------------------------------------------------
6527" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6528"                   glob()ing only works with local files
6529fun! s:NetrwMarkFiles(islocal,...)
6530"  call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6531  let curdir = s:NetrwGetCurdir(a:islocal)
6532  let i      = 1
6533  while i <= a:0
6534   if a:islocal
6535    if v:version > 704 || (v:version == 704 && has("patch656"))
6536     let mffiles= glob(fnameescape(a:{i}),0,1,1)
6537    else
6538     let mffiles= glob(fnameescape(a:{i}),0,1)
6539    endif
6540   else
6541    let mffiles= [a:{i}]
6542   endif
6543"   call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6544   for mffile in mffiles
6545"    call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6546    call s:NetrwMarkFile(a:islocal,mffile)
6547   endfor
6548   let i= i + 1
6549  endwhile
6550"  call Dret("s:NetrwMarkFiles")
6551endfun
6552
6553" ---------------------------------------------------------------------
6554" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6555fun! s:NetrwMarkTarget(...)
6556"  call Dfunc("s:NetrwMarkTarget() a:0=".a:0)
6557  if a:0 == 0 || (a:0 == 1 && a:1 == "")
6558   let curdir = s:NetrwGetCurdir(1)
6559   let tgt    = b:netrw_curdir
6560  else
6561   let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6562   let tgt    = a:1
6563  endif
6564"  call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
6565  let s:netrwmftgt         = tgt
6566  let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6567  let curislocal           = b:netrw_curdir !~ '^\a\{3,}://'
6568  let svpos                = winsaveview()
6569"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6570  call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./'))
6571"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6572  call winrestview(svpos)
6573"  call Dret("s:NetrwMarkTarget")
6574endfun
6575
6576" ---------------------------------------------------------------------
6577" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6578"                  mark and unmark files.  If a markfile list exists,
6579"                  then the rename and delete functions will use it instead
6580"                  of whatever may happen to be under the cursor at that
6581"                  moment.  When the mouse and gui are available,
6582"                  shift-leftmouse may also be used to mark files.
6583"
6584"  Creates two lists
6585"    s:netrwmarkfilelist    -- holds complete paths to all marked files
6586"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
6587"
6588"  Creates a marked file match string
6589"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
6590"
6591"  Creates a buffer version of islocal
6592"    b:netrw_islocal
6593fun! s:NetrwMarkFile(islocal,fname)
6594"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6595"  call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6596
6597  " sanity check
6598  if empty(a:fname)
6599"   call Dret("s:NetrwMarkFile : emtpy fname")
6600   return
6601  endif
6602  let curdir = s:NetrwGetCurdir(a:islocal)
6603
6604  let ykeep   = @@
6605  let curbufnr= bufnr("%")
6606  if a:fname =~ '^\a'
6607   let leader= '\<'
6608  else
6609   let leader= ''
6610  endif
6611  if a:fname =~ '\a$'
6612   let trailer = '\>[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6613  else
6614   let trailer = '[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6615  endif
6616
6617  if exists("s:netrwmarkfilelist_".curbufnr)
6618   " markfile list pre-exists
6619"   call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6620"   call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6621"   call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6622   let b:netrw_islocal= a:islocal
6623
6624   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6625    " append filename to buffer's markfilelist
6626"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6627    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6628    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6629
6630   else
6631    " remove filename from buffer's markfilelist
6632"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6633    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6634    if s:netrwmarkfilelist_{curbufnr} == []
6635     " local markfilelist is empty; remove it entirely
6636"     call Decho("markfile list now empty",'~'.expand("<slnum>"))
6637     call s:NetrwUnmarkList(curbufnr,curdir)
6638    else
6639     " rebuild match list to display markings correctly
6640"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6641     let s:netrwmarkfilemtch_{curbufnr}= ""
6642     let first                         = 1
6643     for fname in s:netrwmarkfilelist_{curbufnr}
6644      if first
6645       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6646      else
6647       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6648      endif
6649      let first= 0
6650     endfor
6651"     call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6652    endif
6653   endif
6654
6655  else
6656   " initialize new markfilelist
6657"   call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6658
6659"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6660   let s:netrwmarkfilelist_{curbufnr}= []
6661   call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6662"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6663
6664   " build initial markfile matching pattern
6665   if a:fname =~ '/$'
6666    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6667   else
6668    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6669   endif
6670"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6671  endif
6672
6673  " handle global markfilelist
6674  if exists("s:netrwmarkfilelist")
6675   let dname= s:ComposePath(b:netrw_curdir,a:fname)
6676   if index(s:netrwmarkfilelist,dname) == -1
6677    " append new filename to global markfilelist
6678    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6679"    call Decho("append filename<".a:fname."> to global markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6680   else
6681    " remove new filename from global markfilelist
6682"    call Decho("filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6683    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6684"    call Decho("ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6685    if s:netrwmarkfilelist == []
6686     unlet s:netrwmarkfilelist
6687    endif
6688   endif
6689  else
6690   " initialize new global-directory markfilelist
6691   let s:netrwmarkfilelist= []
6692   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6693"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6694  endif
6695
6696  " set up 2match'ing to netrwmarkfilemtch_# list
6697  if has("syntax") && exists("g:syntax_on") && g:syntax_on
6698   if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6699" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6700    if exists("g:did_drchip_netrwlist_syntax")
6701     exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6702    endif
6703   else
6704" "   call Decho("2match none",'~'.expand("<slnum>"))
6705    2match none
6706   endif
6707  endif
6708  let @@= ykeep
6709"  call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">")
6710endfun
6711
6712" ---------------------------------------------------------------------
6713" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6714"                         mA: move the argument list to marked file list     (tomflist=1)
6715"                            Uses the global marked file list
6716fun! s:NetrwMarkFileArgList(islocal,tomflist)
6717"  call Dfunc("s:NetrwMarkFileArgList(islocal=".a:islocal.",tomflist=".a:tomflist.")")
6718
6719  let svpos    = winsaveview()
6720"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6721  let curdir   = s:NetrwGetCurdir(a:islocal)
6722  let curbufnr = bufnr("%")
6723
6724  if a:tomflist
6725   " mA: move argument list to marked file list
6726   while argc()
6727    let fname= argv(0)
6728"    call Decho("exe argdel ".fname,'~'.expand("<slnum>"))
6729    exe "argdel ".fnameescape(fname)
6730    call s:NetrwMarkFile(a:islocal,fname)
6731   endwhile
6732
6733  else
6734   " ma: move marked file list to argument list
6735   if exists("s:netrwmarkfilelist")
6736
6737    " for every filename in the marked list
6738    for fname in s:netrwmarkfilelist
6739"     call Decho("exe argadd ".fname,'~'.expand("<slnum>"))
6740     exe "argadd ".fnameescape(fname)
6741    endfor	" for every file in the marked list
6742
6743    " unmark list and refresh
6744    call s:NetrwUnmarkList(curbufnr,curdir)
6745    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6746"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6747    NetrwKeepj call winrestview(svpos)
6748   endif
6749  endif
6750
6751"  call Dret("s:NetrwMarkFileArgList")
6752endfun
6753
6754" ---------------------------------------------------------------------
6755" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6756"                          compress/decompress files using the programs
6757"                          in g:netrw_compress and g:netrw_uncompress,
6758"                          using g:netrw_compress_suffix to know which to
6759"                          do.  By default:
6760"                            g:netrw_compress        = "gzip"
6761"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6762fun! s:NetrwMarkFileCompress(islocal)
6763"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
6764  let svpos    = winsaveview()
6765"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6766  let curdir   = s:NetrwGetCurdir(a:islocal)
6767  let curbufnr = bufnr("%")
6768
6769  " sanity check
6770  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6771   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6772"   call Dret("s:NetrwMarkFileCompress")
6773   return
6774  endif
6775"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6776
6777  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6778
6779   " for every filename in the marked list
6780   for fname in s:netrwmarkfilelist_{curbufnr}
6781    let sfx= substitute(fname,'^.\{-}\(\.\a\+\)$','\1','')
6782"    call Decho("extracted sfx<".sfx.">",'~'.expand("<slnum>"))
6783    if exists("g:netrw_decompress['".sfx."']")
6784     " fname has a suffix indicating that its compressed; apply associated decompression routine
6785     let exe= g:netrw_decompress[sfx]
6786"     call Decho("fname<".fname."> is compressed so decompress with <".exe.">",'~'.expand("<slnum>"))
6787     let exe= netrw#WinPath(exe)
6788     if a:islocal
6789      if g:netrw_keepdir
6790       let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6791      endif
6792      call system(exe." ".fname)
6793      if v:shell_error
6794       NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6795      endif
6796     else
6797      let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6798      NetrwKeepj call s:RemoteSystem(exe." ".fname)
6799     endif
6800
6801    endif
6802    unlet sfx
6803
6804    if exists("exe")
6805     unlet exe
6806    elseif a:islocal
6807     " fname not a compressed file, so compress it
6808     call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
6809     if v:shell_error
6810      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_compress<".g:netrw_compress."> to something that works",104)
6811     endif
6812    else
6813     " fname not a compressed file, so compress it
6814     NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
6815    endif
6816   endfor	" for every file in the marked list
6817
6818   call s:NetrwUnmarkList(curbufnr,curdir)
6819   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6820"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6821   NetrwKeepj call winrestview(svpos)
6822  endif
6823"  call Dret("s:NetrwMarkFileCompress")
6824endfun
6825
6826" ---------------------------------------------------------------------
6827" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
6828"                      If no marked files, then set up directory as the
6829"                      target.  Currently does not support copying entire
6830"                      directories.  Uses the local-buffer marked file list.
6831"                      Returns 1=success  (used by NetrwMarkFileMove())
6832"                              0=failure
6833fun! s:NetrwMarkFileCopy(islocal,...)
6834"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
6835
6836  let curdir   = s:NetrwGetCurdir(a:islocal)
6837  let curbufnr = bufnr("%")
6838  if b:netrw_curdir !~ '/$'
6839   if !exists("b:netrw_curdir")
6840    let b:netrw_curdir= curdir
6841   endif
6842   let b:netrw_curdir= b:netrw_curdir."/"
6843  endif
6844
6845  " sanity check
6846  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6847   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6848"   call Dret("s:NetrwMarkFileCopy")
6849   return
6850  endif
6851"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6852
6853  if !exists("s:netrwmftgt")
6854   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
6855"   call Dret("s:NetrwMarkFileCopy 0")
6856   return 0
6857  endif
6858"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
6859
6860  if a:islocal &&  s:netrwmftgt_islocal
6861   " Copy marked files, local directory to local directory
6862"   call Decho("copy from local to local",'~'.expand("<slnum>"))
6863   if !executable(g:netrw_localcopycmd)
6864    call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
6865"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
6866    return
6867   endif
6868
6869   " copy marked files while within the same directory (ie. allow renaming)
6870   if simplify(s:netrwmftgt) == simplify(b:netrw_curdir)
6871    if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
6872     " only one marked file
6873"     call Decho("case: only one marked file",'~'.expand("<slnum>"))
6874     let args    = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
6875     let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
6876    elseif a:0 == 1
6877"     call Decho("case: handling one input argument",'~'.expand("<slnum>"))
6878     " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
6879     let args    = s:ShellEscape(b:netrw_curdir.a:1)
6880     let oldname = a:1
6881    else
6882     " copy multiple marked files inside the same directory
6883"     call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
6884     let s:recursive= 1
6885     for oldname in s:netrwmarkfilelist_{bufnr("%")}
6886      let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
6887      if ret == 0
6888       break
6889      endif
6890     endfor
6891     unlet s:recursive
6892     call s:NetrwUnmarkList(curbufnr,curdir)
6893"     call Dret("s:NetrwMarkFileCopy ".ret)
6894     return ret
6895    endif
6896
6897    call inputsave()
6898    let newname= input("Copy ".oldname." to : ",oldname,"file")
6899    call inputrestore()
6900    if newname == ""
6901"     call Dret("s:NetrwMarkFileCopy 0")
6902     return 0
6903    endif
6904    let args= s:ShellEscape(oldname)
6905    let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
6906   else
6907    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
6908    let tgt = s:ShellEscape(s:netrwmftgt)
6909   endif
6910   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
6911    let args= substitute(args,'/','\\','g')
6912    let tgt = substitute(tgt, '/','\\','g')
6913   endif
6914   if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
6915   if tgt  =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
6916   if args =~ '//'|let args= substitute(args,'//','/','g')|endif
6917   if tgt  =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
6918"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
6919"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
6920   if isdirectory(s:NetrwFile(args))
6921"    call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
6922    let copycmd= g:netrw_localcopydircmd
6923"    call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
6924    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
6925     " window's xcopy doesn't copy a directory to a target properly.  Instead, it copies a directory's
6926     " contents to a target.  One must append the source directory name to the target to get xcopy to
6927     " do the right thing.
6928     let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
6929"     call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
6930    endif
6931   else
6932    let copycmd= g:netrw_localcopycmd
6933   endif
6934   if g:netrw_localcopycmd =~ '\s'
6935    let copycmd     = substitute(copycmd,'\s.*$','','')
6936    let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
6937    let copycmd     = netrw#WinPath(copycmd).copycmdargs
6938   else
6939    let copycmd = netrw#WinPath(copycmd)
6940   endif
6941"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
6942"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
6943"   call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
6944"   call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
6945   call system(copycmd.g:netrw_localcopycmdopt." '".args."' '".tgt."'")
6946   if v:shell_error != 0
6947    if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
6948     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)
6949    else
6950     call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
6951    endif
6952"    call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
6953    return 0
6954   endif
6955
6956  elseif  a:islocal && !s:netrwmftgt_islocal
6957   " Copy marked files, local directory to remote directory
6958"   call Decho("copy from local to remote",'~'.expand("<slnum>"))
6959   NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6960
6961  elseif !a:islocal &&  s:netrwmftgt_islocal
6962   " Copy marked files, remote directory to local directory
6963"   call Decho("copy from remote to local",'~'.expand("<slnum>"))
6964   NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6965
6966  elseif !a:islocal && !s:netrwmftgt_islocal
6967   " Copy marked files, remote directory to remote directory
6968"   call Decho("copy from remote to remote",'~'.expand("<slnum>"))
6969   let curdir = getcwd()
6970   let tmpdir = s:GetTempfile("")
6971   if tmpdir !~ '/'
6972    let tmpdir= curdir."/".tmpdir
6973   endif
6974   if exists("*mkdir")
6975    call mkdir(tmpdir)
6976   else
6977    call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(tmpdir,1))
6978    if v:shell_error != 0
6979     call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6980"     call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
6981     return
6982    endif
6983   endif
6984   if isdirectory(s:NetrwFile(tmpdir))
6985    if s:NetrwLcd(tmpdir)
6986"     call Dret("s:NetrwMarkFileCopy : lcd failure")
6987     return
6988    endif
6989    NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
6990    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
6991    NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
6992    if getcwd() == tmpdir
6993     for fname in s:netrwmarkfilelist_{bufnr('%')}
6994      NetrwKeepj call s:NetrwDelete(fname)
6995     endfor
6996     if s:NetrwLcd(curdir)
6997"      call Dret("s:NetrwMarkFileCopy : lcd failure")
6998      return
6999     endif
7000     if v:version < 704 || (v:version == 704 && !has("patch1107"))
7001      call s:NetrwExe("sil !".g:netrw_localrmdir.g:netrw_localrmdiropt." ".s:ShellEscape(tmpdir,1))
7002      if v:shell_error != 0
7003       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localrmdir<".g:netrw_localrmdir."> to something that works",80)
7004" "      call Dret("s:NetrwMarkFileCopy : failed: sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1) )
7005       return
7006      endif
7007     else
7008      if delete(tmpdir,"d")
7009       call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
7010      endif
7011     endif
7012    else
7013     if s:NetrwLcd(curdir)
7014"      call Dret("s:NetrwMarkFileCopy : lcd failure")
7015      return
7016     endif
7017    endif
7018   endif
7019  endif
7020
7021  " -------
7022  " cleanup
7023  " -------
7024"  call Decho("cleanup",'~'.expand("<slnum>"))
7025  " remove markings from local buffer
7026  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7027"  call Decho(" g:netrw_fastbrowse  =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
7028"  call Decho(" s:netrwmftgt        =".s:netrwmftgt,'~'.expand("<slnum>"))
7029"  call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
7030"  call Decho(" curdir              =".curdir,'~'.expand("<slnum>"))
7031"  call Decho(" a:islocal           =".a:islocal,'~'.expand("<slnum>"))
7032"  call Decho(" curbufnr            =".curbufnr,'~'.expand("<slnum>"))
7033  if exists("s:recursive")
7034"   call Decho(" s:recursive         =".s:recursive,'~'.expand("<slnum>"))
7035  else
7036"   call Decho(" s:recursive         =n/a",'~'.expand("<slnum>"))
7037  endif
7038  " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
7039  if g:netrw_fastbrowse <= 1
7040   NetrwKeepj call s:LocalBrowseRefresh()
7041  else
7042   " refresh local and targets for fast browsing
7043   if !exists("s:recursive")
7044    " remove markings from local buffer
7045"    call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
7046    NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
7047   endif
7048
7049   " refresh buffers
7050   if s:netrwmftgt_islocal
7051"    call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
7052    NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7053   endif
7054   if a:islocal && s:netrwmftgt != curdir
7055"    call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
7056    NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
7057   endif
7058  endif
7059
7060"  call Dret("s:NetrwMarkFileCopy 1")
7061  return 1
7062endfun
7063
7064" ---------------------------------------------------------------------
7065" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
7066"                      invoke vim's diff mode on the marked files.
7067"                      Either two or three files can be so handled.
7068"                      Uses the global marked file list.
7069fun! s:NetrwMarkFileDiff(islocal)
7070"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
7071  let curbufnr= bufnr("%")
7072
7073  " sanity check
7074  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7075   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7076"   call Dret("s:NetrwMarkFileDiff")
7077   return
7078  endif
7079  let curdir= s:NetrwGetCurdir(a:islocal)
7080"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7081
7082  if exists("s:netrwmarkfilelist_{".curbufnr."}")
7083   let cnt    = 0
7084   for fname in s:netrwmarkfilelist
7085    let cnt= cnt + 1
7086    if cnt == 1
7087"     call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
7088     exe "NetrwKeepj e ".fnameescape(fname)
7089     diffthis
7090    elseif cnt == 2 || cnt == 3
7091     vsplit
7092     wincmd l
7093"     call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
7094     exe "NetrwKeepj e ".fnameescape(fname)
7095     diffthis
7096    else
7097     break
7098    endif
7099   endfor
7100   call s:NetrwUnmarkList(curbufnr,curdir)
7101  endif
7102
7103"  call Dret("s:NetrwMarkFileDiff")
7104endfun
7105
7106" ---------------------------------------------------------------------
7107" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
7108"                       Uses global markfilelist
7109fun! s:NetrwMarkFileEdit(islocal)
7110"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
7111
7112  let curdir   = s:NetrwGetCurdir(a:islocal)
7113  let curbufnr = bufnr("%")
7114
7115  " sanity check
7116  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7117   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7118"   call Dret("s:NetrwMarkFileEdit")
7119   return
7120  endif
7121"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7122
7123  if exists("s:netrwmarkfilelist_{curbufnr}")
7124   call s:SetRexDir(a:islocal,curdir)
7125   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7126   " unmark markedfile list
7127"   call s:NetrwUnmarkList(curbufnr,curdir)
7128   call s:NetrwUnmarkAll()
7129"   call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
7130   exe "sil args ".flist
7131  endif
7132  echo "(use :bn, :bp to navigate files; :Rex to return)"
7133
7134"  call Dret("s:NetrwMarkFileEdit")
7135endfun
7136
7137" ---------------------------------------------------------------------
7138" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
7139fun! s:NetrwMarkFileQFEL(islocal,qfel)
7140"  call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
7141  call s:NetrwUnmarkAll()
7142  let curbufnr= bufnr("%")
7143
7144  if !empty(a:qfel)
7145   for entry in a:qfel
7146    let bufnmbr= entry["bufnr"]
7147"    call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
7148    if !exists("s:netrwmarkfilelist_{curbufnr}")
7149"     call Decho("case: no marked file list",'~'.expand("<slnum>"))
7150     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7151    elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
7152     " s:NetrwMarkFile will remove duplicate entries from the marked file list.
7153     " So, this test lets two or more hits on the same pattern to be ignored.
7154"     call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
7155     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
7156    else
7157"     call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
7158    endif
7159   endfor
7160   echo "(use me to edit marked files)"
7161  else
7162   call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
7163  endif
7164
7165"  call Dret("s:NetrwMarkFileQFEL")
7166endfun
7167
7168" ---------------------------------------------------------------------
7169" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
7170"                     mx enbloc=0: Uses the local marked-file list, applies command to each file individually
7171"                     mX enbloc=1: Uses the global marked-file list, applies command to entire list
7172fun! s:NetrwMarkFileExe(islocal,enbloc)
7173"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")")
7174  let svpos    = winsaveview()
7175"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7176  let curdir   = s:NetrwGetCurdir(a:islocal)
7177  let curbufnr = bufnr("%")
7178
7179  if a:enbloc == 0
7180   " individually apply command to files, one at a time
7181    " sanity check
7182    if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7183     NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7184"     call Dret("s:NetrwMarkFileExe")
7185     return
7186    endif
7187"    call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7188
7189    if exists("s:netrwmarkfilelist_{curbufnr}")
7190     " get the command
7191     call inputsave()
7192     let cmd= input("Enter command: ","","file")
7193     call inputrestore()
7194"     call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7195     if cmd == ""
7196"      call Dret("s:NetrwMarkFileExe : early exit, empty command")
7197      return
7198     endif
7199
7200     " apply command to marked files, individually.  Substitute: filename -> %
7201     " If no %, then append a space and the filename to the command
7202     for fname in s:netrwmarkfilelist_{curbufnr}
7203      if a:islocal
7204       if g:netrw_keepdir
7205	let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
7206       endif
7207      else
7208       let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
7209      endif
7210      if cmd =~ '%'
7211       let xcmd= substitute(cmd,'%',fname,'g')
7212      else
7213       let xcmd= cmd.' '.fname
7214      endif
7215      if a:islocal
7216"       call Decho("local: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7217       let ret= system(xcmd)
7218      else
7219"       call Decho("remote: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7220       let ret= s:RemoteSystem(xcmd)
7221      endif
7222      if v:shell_error < 0
7223       NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7224       break
7225      else
7226       echo ret
7227      endif
7228     endfor
7229
7230   " unmark marked file list
7231   call s:NetrwUnmarkList(curbufnr,curdir)
7232
7233   " refresh the listing
7234   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7235"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7236   NetrwKeepj call winrestview(svpos)
7237  else
7238   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7239  endif
7240
7241 else " apply command to global list of files, en bloc
7242
7243  call inputsave()
7244  let cmd= input("Enter command: ","","file")
7245  call inputrestore()
7246"  call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7247  if cmd == ""
7248"   call Dret("s:NetrwMarkFileExe : early exit, empty command")
7249   return
7250  endif
7251  if cmd =~ '%'
7252   let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7253  else
7254   let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7255  endif
7256  if a:islocal
7257   call system(cmd)
7258   if v:shell_error < 0
7259    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7260   endif
7261  else
7262   let ret= s:RemoteSystem(cmd)
7263  endif
7264  call s:NetrwUnmarkAll()
7265
7266  " refresh the listing
7267  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7268"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7269  NetrwKeepj call winrestview(svpos)
7270
7271 endif
7272
7273"  call Dret("s:NetrwMarkFileExe")
7274endfun
7275
7276" ---------------------------------------------------------------------
7277" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7278"                  as the marked file(s) (toggles suffix presence)
7279"                  Uses the local marked file list.
7280fun! s:NetrwMarkHideSfx(islocal)
7281"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7282  let svpos    = winsaveview()
7283"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7284  let curbufnr = bufnr("%")
7285
7286  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7287  if exists("s:netrwmarkfilelist_{curbufnr}")
7288
7289   for fname in s:netrwmarkfilelist_{curbufnr}
7290"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7291     " construct suffix pattern
7292     if fname =~ '\.'
7293      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7294     else
7295      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7296     endif
7297     " determine if its in the hiding list or not
7298     let inhidelist= 0
7299     if g:netrw_list_hide != ""
7300      let itemnum = 0
7301      let hidelist= split(g:netrw_list_hide,',')
7302      for hidepat in hidelist
7303       if sfxpat == hidepat
7304        let inhidelist= 1
7305        break
7306       endif
7307       let itemnum= itemnum + 1
7308      endfor
7309     endif
7310"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7311     if inhidelist
7312      " remove sfxpat from list
7313      call remove(hidelist,itemnum)
7314      let g:netrw_list_hide= join(hidelist,",")
7315     elseif g:netrw_list_hide != ""
7316      " append sfxpat to non-empty list
7317      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7318     else
7319      " set hiding list to sfxpat
7320      let g:netrw_list_hide= sfxpat
7321     endif
7322    endfor
7323
7324   " refresh the listing
7325   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7326"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7327   NetrwKeepj call winrestview(svpos)
7328  else
7329   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7330  endif
7331
7332"  call Dret("s:NetrwMarkHideSfx")
7333endfun
7334
7335" ---------------------------------------------------------------------
7336" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7337"                     Uses the local marked-file list.
7338fun! s:NetrwMarkFileVimCmd(islocal)
7339"  call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")")
7340  let svpos    = winsaveview()
7341"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7342  let curdir   = s:NetrwGetCurdir(a:islocal)
7343  let curbufnr = bufnr("%")
7344
7345  " sanity check
7346  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7347   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7348"   call Dret("s:NetrwMarkFileVimCmd")
7349   return
7350  endif
7351"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7352
7353  if exists("s:netrwmarkfilelist_{curbufnr}")
7354   " get the command
7355   call inputsave()
7356   let cmd= input("Enter vim command: ","","file")
7357   call inputrestore()
7358"   call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7359   if cmd == ""
7360"    "   call Dret("s:NetrwMarkFileVimCmd : early exit, empty command")
7361    return
7362   endif
7363
7364   " apply command to marked files.  Substitute: filename -> %
7365   " If no %, then append a space and the filename to the command
7366   for fname in s:netrwmarkfilelist_{curbufnr}
7367"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7368    if a:islocal
7369     1split
7370     exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7371"     call Decho("local<".fname.">: exe ".cmd,'~'.expand("<slnum>"))
7372     exe cmd
7373     exe "sil! keepalt wq!"
7374    else
7375"     call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET",'~'.expand("<slnum>"))
7376     echo "sorry, \"mv\" not supported yet for remote files"
7377    endif
7378   endfor
7379
7380   " unmark marked file list
7381   call s:NetrwUnmarkList(curbufnr,curdir)
7382
7383   " refresh the listing
7384   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7385"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7386   NetrwKeepj call winrestview(svpos)
7387  else
7388   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7389  endif
7390
7391"  call Dret("s:NetrwMarkFileVimCmd")
7392endfun
7393
7394" ---------------------------------------------------------------------
7395" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7396"                  as the marked file(s) (toggles suffix presence)
7397"                  Uses the local marked file list.
7398fun! s:NetrwMarkHideSfx(islocal)
7399"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7400  let svpos    = winsaveview()
7401"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7402  let curbufnr = bufnr("%")
7403
7404  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7405  if exists("s:netrwmarkfilelist_{curbufnr}")
7406
7407   for fname in s:netrwmarkfilelist_{curbufnr}
7408"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7409     " construct suffix pattern
7410     if fname =~ '\.'
7411      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7412     else
7413      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7414     endif
7415     " determine if its in the hiding list or not
7416     let inhidelist= 0
7417     if g:netrw_list_hide != ""
7418      let itemnum = 0
7419      let hidelist= split(g:netrw_list_hide,',')
7420      for hidepat in hidelist
7421       if sfxpat == hidepat
7422        let inhidelist= 1
7423        break
7424       endif
7425       let itemnum= itemnum + 1
7426      endfor
7427     endif
7428"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7429     if inhidelist
7430      " remove sfxpat from list
7431      call remove(hidelist,itemnum)
7432      let g:netrw_list_hide= join(hidelist,",")
7433     elseif g:netrw_list_hide != ""
7434      " append sfxpat to non-empty list
7435      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7436     else
7437      " set hiding list to sfxpat
7438      let g:netrw_list_hide= sfxpat
7439     endif
7440    endfor
7441
7442   " refresh the listing
7443   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7444"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7445   NetrwKeepj call winrestview(svpos)
7446  else
7447   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7448  endif
7449
7450"  call Dret("s:NetrwMarkHideSfx")
7451endfun
7452
7453" ---------------------------------------------------------------------
7454" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7455"                     Uses the global markfilelist
7456fun! s:NetrwMarkFileGrep(islocal)
7457"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7458  let svpos    = winsaveview()
7459"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7460  let curbufnr = bufnr("%")
7461  let curdir   = s:NetrwGetCurdir(a:islocal)
7462
7463  if exists("s:netrwmarkfilelist")
7464"  call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7465   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7466   call s:NetrwUnmarkAll()
7467  else
7468"   call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7469   let netrwmarkfilelist= "*"
7470  endif
7471
7472  " ask user for pattern
7473  call inputsave()
7474  let pat= input("Enter pattern: ","")
7475  call inputrestore()
7476  let patbang = ""
7477  if pat =~ '^!'
7478   let patbang = "!"
7479   let pat     = strpart(pat,2)
7480  endif
7481  if pat =~ '^\i'
7482   let pat    = escape(pat,'/')
7483   let pat    = '/'.pat.'/'
7484  else
7485   let nonisi = pat[0]
7486  endif
7487
7488  " use vimgrep for both local and remote
7489"  call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7490  try
7491   exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7492  catch /^Vim\%((\a\+)\)\=:E480/
7493   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7494"   call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7495   return
7496  endtry
7497  echo "(use :cn, :cp to navigate, :Rex to return)"
7498
7499  2match none
7500"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7501  NetrwKeepj call winrestview(svpos)
7502
7503  if exists("nonisi")
7504   " original, user-supplied pattern did not begin with a character from isident
7505"   call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7506   if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7507    call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7508   endif
7509  endif
7510
7511"  call Dret("s:NetrwMarkFileGrep")
7512endfun
7513
7514" ---------------------------------------------------------------------
7515" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7516"                      uses the global marked file list
7517"                      s:netrwmfloc= 0: target directory is remote
7518"                                  = 1: target directory is local
7519fun! s:NetrwMarkFileMove(islocal)
7520"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7521  let curdir   = s:NetrwGetCurdir(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:NetrwMarkFileMove")
7528   return
7529  endif
7530"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7531
7532  if !exists("s:netrwmftgt")
7533   NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7534"   call Dret("s:NetrwMarkFileCopy 0")
7535   return 0
7536  endif
7537"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7538
7539  if      a:islocal &&  s:netrwmftgt_islocal
7540   " move: local -> local
7541"   call Decho("move from local to local",'~'.expand("<slnum>"))
7542"   call Decho("local to local move",'~'.expand("<slnum>"))
7543   if !executable(g:netrw_localmovecmd)
7544    call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7545"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7546    return
7547   endif
7548   let tgt = s:ShellEscape(s:netrwmftgt)
7549"   call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7550   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7551    let tgt= substitute(tgt, '/','\\','g')
7552"    call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7553    if g:netrw_localmovecmd =~ '\s'
7554     let movecmd     = substitute(g:netrw_localmovecmd,'\s.*$','','')
7555     let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7556     let movecmd     = netrw#WinPath(movecmd).movecmdargs
7557"     call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7558    else
7559     let movecmd = netrw#WinPath(movecmd)
7560"     call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7561    endif
7562   else
7563    let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7564"    call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7565   endif
7566   for fname in s:netrwmarkfilelist_{bufnr("%")}
7567    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7568     let fname= substitute(fname,'/','\\','g')
7569    endif
7570"    call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7571    let ret= system(movecmd.g:netrw_localmovecmdopt." ".s:ShellEscape(fname)." ".tgt)
7572    if v:shell_error != 0
7573     if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7574      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)
7575     else
7576      call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7577     endif
7578     break
7579    endif
7580   endfor
7581
7582  elseif  a:islocal && !s:netrwmftgt_islocal
7583   " move: local -> remote
7584"   call Decho("move from local to remote",'~'.expand("<slnum>"))
7585"   call Decho("copy",'~'.expand("<slnum>"))
7586   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7587   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7588"   call Decho("remove",'~'.expand("<slnum>"))
7589   for fname in mflist
7590    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7591    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7592   endfor
7593   unlet mflist
7594
7595  elseif !a:islocal &&  s:netrwmftgt_islocal
7596   " move: remote -> local
7597"   call Decho("move from remote to local",'~'.expand("<slnum>"))
7598"   call Decho("copy",'~'.expand("<slnum>"))
7599   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7600   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7601"   call Decho("remove",'~'.expand("<slnum>"))
7602   for fname in mflist
7603    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7604    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7605   endfor
7606   unlet mflist
7607
7608  elseif !a:islocal && !s:netrwmftgt_islocal
7609   " move: remote -> remote
7610"   call Decho("move from remote to remote",'~'.expand("<slnum>"))
7611"   call Decho("copy",'~'.expand("<slnum>"))
7612   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7613   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7614"   call Decho("remove",'~'.expand("<slnum>"))
7615   for fname in mflist
7616    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7617    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7618   endfor
7619   unlet mflist
7620  endif
7621
7622  " -------
7623  " cleanup
7624  " -------
7625"  call Decho("cleanup",'~'.expand("<slnum>"))
7626
7627  " remove markings from local buffer
7628  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7629
7630  " refresh buffers
7631  if !s:netrwmftgt_islocal
7632"   call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7633   NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7634  endif
7635  if a:islocal
7636"   call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7637   NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7638  endif
7639  if g:netrw_fastbrowse <= 1
7640"   call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7641   NetrwKeepj call s:LocalBrowseRefresh()
7642  endif
7643
7644"  call Dret("s:NetrwMarkFileMove")
7645endfun
7646
7647" ---------------------------------------------------------------------
7648" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7649"                       using the hardcopy command.  Local marked-file list only.
7650fun! s:NetrwMarkFilePrint(islocal)
7651"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7652  let curbufnr= bufnr("%")
7653
7654  " sanity check
7655  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7656   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7657"   call Dret("s:NetrwMarkFilePrint")
7658   return
7659  endif
7660"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7661  let curdir= s:NetrwGetCurdir(a:islocal)
7662
7663  if exists("s:netrwmarkfilelist_{curbufnr}")
7664   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7665   call s:NetrwUnmarkList(curbufnr,curdir)
7666   for fname in netrwmarkfilelist
7667    if a:islocal
7668     if g:netrw_keepdir
7669      let fname= s:ComposePath(curdir,fname)
7670     endif
7671    else
7672     let fname= curdir.fname
7673    endif
7674    1split
7675    " the autocmds will handle both local and remote files
7676"    call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7677    exe "sil NetrwKeepj e ".fnameescape(fname)
7678"    call Decho("hardcopy",'~'.expand("<slnum>"))
7679    hardcopy
7680    q
7681   endfor
7682   2match none
7683  endif
7684"  call Dret("s:NetrwMarkFilePrint")
7685endfun
7686
7687" ---------------------------------------------------------------------
7688" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7689"                        files when given a regexp (for which a prompt is
7690"                        issued) (matches to name of files).
7691fun! s:NetrwMarkFileRegexp(islocal)
7692"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7693
7694  " get the regular expression
7695  call inputsave()
7696  let regexp= input("Enter regexp: ","","file")
7697  call inputrestore()
7698
7699  if a:islocal
7700   let curdir= s:NetrwGetCurdir(a:islocal)
7701   " get the matching list of files using local glob()
7702"   call Decho("handle local regexp",'~'.expand("<slnum>"))
7703   let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7704   if v:version > 704 || (v:version == 704 && has("patch656"))
7705    let files   = glob(s:ComposePath(dirname,regexp),0,0,1)
7706   else
7707    let files   = glob(s:ComposePath(dirname,regexp),0,0)
7708   endif
7709"   call Decho("files<".files.">",'~'.expand("<slnum>"))
7710   let filelist= split(files,"\n")
7711
7712  " mark the list of files
7713  for fname in filelist
7714"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7715   NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7716  endfor
7717
7718  else
7719"   call Decho("handle remote regexp",'~'.expand("<slnum>"))
7720
7721   " convert displayed listing into a filelist
7722   let eikeep = &ei
7723   let areg   = @a
7724   sil NetrwKeepj %y a
7725   setl ei=all ma
7726"   call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7727   1split
7728   NetrwKeepj call s:NetrwEnew()
7729   NetrwKeepj call s:NetrwSafeOptions()
7730   sil NetrwKeepj norm! "ap
7731   NetrwKeepj 2
7732   let bannercnt= search('^" =====','W')
7733   exe "sil NetrwKeepj 1,".bannercnt."d"
7734   setl bt=nofile
7735   if     g:netrw_liststyle == s:LONGLIST
7736    sil NetrwKeepj %s/\s\{2,}\S.*$//e
7737    call histdel("/",-1)
7738   elseif g:netrw_liststyle == s:WIDELIST
7739    sil NetrwKeepj %s/\s\{2,}/\r/ge
7740    call histdel("/",-1)
7741   elseif g:netrw_liststyle == s:TREELIST
7742    exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7743    sil! NetrwKeepj g/^ .*$/d
7744    call histdel("/",-1)
7745    call histdel("/",-1)
7746   endif
7747   " convert regexp into the more usual glob-style format
7748   let regexp= substitute(regexp,'\*','.*','g')
7749"   call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7750   exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7751   call histdel("/",-1)
7752   let filelist= getline(1,line("$"))
7753   q!
7754   for filename in filelist
7755    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7756   endfor
7757   unlet filelist
7758   let @a  = areg
7759   let &ei = eikeep
7760  endif
7761  echo "  (use me to edit marked files)"
7762
7763"  call Dret("s:NetrwMarkFileRegexp")
7764endfun
7765
7766" ---------------------------------------------------------------------
7767" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7768"                        Uses the local marked file list.
7769fun! s:NetrwMarkFileSource(islocal)
7770"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7771  let curbufnr= bufnr("%")
7772
7773  " sanity check
7774  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7775   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7776"   call Dret("s:NetrwMarkFileSource")
7777   return
7778  endif
7779"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7780  let curdir= s:NetrwGetCurdir(a:islocal)
7781
7782  if exists("s:netrwmarkfilelist_{curbufnr}")
7783   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7784   call s:NetrwUnmarkList(curbufnr,curdir)
7785   for fname in netrwmarkfilelist
7786    if a:islocal
7787     if g:netrw_keepdir
7788      let fname= s:ComposePath(curdir,fname)
7789     endif
7790    else
7791     let fname= curdir.fname
7792    endif
7793    " the autocmds will handle sourcing both local and remote files
7794"    call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7795    exe "so ".fnameescape(fname)
7796   endfor
7797   2match none
7798  endif
7799"  call Dret("s:NetrwMarkFileSource")
7800endfun
7801
7802" ---------------------------------------------------------------------
7803" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
7804"                     Uses the global markfilelist
7805fun! s:NetrwMarkFileTag(islocal)
7806"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
7807  let svpos    = winsaveview()
7808"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7809  let curdir   = s:NetrwGetCurdir(a:islocal)
7810  let curbufnr = bufnr("%")
7811
7812  " sanity check
7813  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7814   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7815"   call Dret("s:NetrwMarkFileTag")
7816   return
7817  endif
7818"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7819
7820  if exists("s:netrwmarkfilelist")
7821"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7822   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
7823   call s:NetrwUnmarkAll()
7824
7825   if a:islocal
7826
7827"    call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("<slnum>"))
7828    call system(g:netrw_ctags." ".netrwmarkfilelist)
7829    if v:shell_error
7830     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
7831    endif
7832
7833   else
7834    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
7835    call netrw#Obtain(a:islocal,"tags")
7836    let curdir= b:netrw_curdir
7837    1split
7838    NetrwKeepj e tags
7839    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
7840"    call Decho("curdir<".curdir."> path<".path.">",'~'.expand("<slnum>"))
7841    exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
7842    call histdel("/",-1)
7843    wq!
7844   endif
7845   2match none
7846   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7847"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7848   call winrestview(svpos)
7849  endif
7850
7851"  call Dret("s:NetrwMarkFileTag")
7852endfun
7853
7854" ---------------------------------------------------------------------
7855" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
7856"   Sets up two variables,
7857"     s:netrwmftgt         : holds the target directory
7858"     s:netrwmftgt_islocal : 0=target directory is remote
7859"                            1=target directory is local
7860fun! s:NetrwMarkFileTgt(islocal)
7861" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
7862  let svpos  = winsaveview()
7863"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7864  let curdir = s:NetrwGetCurdir(a:islocal)
7865  let hadtgt = exists("s:netrwmftgt")
7866  if !exists("w:netrw_bannercnt")
7867   let w:netrw_bannercnt= b:netrw_bannercnt
7868  endif
7869
7870  " set up target
7871  if line(".") < w:netrw_bannercnt
7872"   call Decho("set up target: line(.) < w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
7873   " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
7874   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
7875"    call Decho("cursor in banner region, and target already is <".b:netrw_curdir.">: removing target",'~'.expand("<slnum>"))
7876    unlet s:netrwmftgt s:netrwmftgt_islocal
7877    if g:netrw_fastbrowse <= 1
7878     call s:LocalBrowseRefresh()
7879    endif
7880    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7881"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7882    call winrestview(svpos)
7883"    call Dret("s:NetrwMarkFileTgt : removed target")
7884    return
7885   else
7886    let s:netrwmftgt= b:netrw_curdir
7887"    call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7888   endif
7889
7890  else
7891   " get word under cursor.
7892   "  * If directory, use it for the target.
7893   "  * If file, use b:netrw_curdir for the target
7894"   call Decho("get word under cursor",'~'.expand("<slnum>"))
7895   let curword= s:NetrwGetWord()
7896   let tgtdir = s:ComposePath(curdir,curword)
7897   if a:islocal && isdirectory(s:NetrwFile(tgtdir))
7898    let s:netrwmftgt = tgtdir
7899"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7900   elseif !a:islocal && tgtdir =~ '/$'
7901    let s:netrwmftgt = tgtdir
7902"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7903   else
7904    let s:netrwmftgt = curdir
7905"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7906   endif
7907  endif
7908  if a:islocal
7909   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
7910   let s:netrwmftgt= simplify(s:netrwmftgt)
7911"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7912  endif
7913  if g:netrw_cygwin
7914   let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
7915   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
7916  endif
7917  let s:netrwmftgt_islocal= a:islocal
7918
7919  " need to do refresh so that the banner will be updated
7920  "  s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
7921  if g:netrw_fastbrowse <= 1
7922"   call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers",'~'.expand("<slnum>"))
7923   call s:LocalBrowseRefresh()
7924  endif
7925"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7926  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7927   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop))
7928  else
7929   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7930  endif
7931"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7932  call winrestview(svpos)
7933  if !hadtgt
7934   sil! NetrwKeepj norm! j
7935  endif
7936
7937"  call Decho("getmatches=".string(getmatches()),'~'.expand("<slnum>"))
7938"  call Decho("s:netrwmarkfilelist=".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : 'n/a'),'~'.expand("<slnum>"))
7939"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
7940endfun
7941
7942" ---------------------------------------------------------------------
7943" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
7944fun! s:NetrwGetCurdir(islocal)
7945"  call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
7946
7947  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7948   let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
7949"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
7950  elseif !exists("b:netrw_curdir")
7951   let b:netrw_curdir= getcwd()
7952"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
7953  endif
7954
7955"  call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>"))
7956  if b:netrw_curdir !~ '\<\a\{3,}://'
7957   let curdir= b:netrw_curdir
7958"   call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
7959   if g:netrw_keepdir == 0
7960    call s:NetrwLcd(curdir)
7961   endif
7962  endif
7963
7964"  call Dret("s:NetrwGetCurdir <".curdir.">")
7965  return b:netrw_curdir
7966endfun
7967
7968" ---------------------------------------------------------------------
7969" s:NetrwOpenFile: query user for a filename and open it {{{2
7970fun! s:NetrwOpenFile(islocal)
7971"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
7972  let ykeep= @@
7973  call inputsave()
7974  let fname= input("Enter filename: ")
7975  call inputrestore()
7976  if fname !~ '[/\\]'
7977   if exists("b:netrw_curdir")
7978    if exists("g:netrw_quiet")
7979     let netrw_quiet_keep = g:netrw_quiet
7980    endif
7981    let g:netrw_quiet = 1
7982    " save position for benefit of Rexplore
7983    let s:rexposn_{bufnr("%")}= winsaveview()
7984"    call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
7985    if b:netrw_curdir =~ '/$'
7986     exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
7987    else
7988     exe "e ".fnameescape(b:netrw_curdir."/".fname)
7989    endif
7990    if exists("netrw_quiet_keep")
7991     let g:netrw_quiet= netrw_quiet_keep
7992    else
7993     unlet g:netrw_quiet
7994    endif
7995   endif
7996  else
7997   exe "NetrwKeepj e ".fnameescape(fname)
7998  endif
7999  let @@= ykeep
8000"  call Dret("s:NetrwOpenFile")
8001endfun
8002
8003" ---------------------------------------------------------------------
8004" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
8005"               For the mapping to this function be made via
8006"               netrwPlugin, you'll need to have had
8007"               g:netrw_usetab set to non-zero.
8008fun! netrw#Shrink()
8009"  call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
8010  let curwin  = winnr()
8011  let wiwkeep = &wiw
8012  set wiw=1
8013
8014  if &ft == "netrw"
8015   if winwidth(0) > g:netrw_wiw
8016    let t:netrw_winwidth= winwidth(0)
8017    exe "vert resize ".g:netrw_wiw
8018    wincmd l
8019    if winnr() == curwin
8020     wincmd h
8021    endif
8022"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8023   else
8024    exe "vert resize ".t:netrw_winwidth
8025"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8026   endif
8027
8028  elseif exists("t:netrw_lexbufnr")
8029   exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
8030   if     winwidth(bufwinnr(t:netrw_lexbufnr)) >  g:netrw_wiw
8031    let t:netrw_winwidth= winwidth(0)
8032    exe "vert resize ".g:netrw_wiw
8033    wincmd l
8034    if winnr() == curwin
8035     wincmd h
8036    endif
8037"    call Decho("vert resize 0",'~'.expand("<slnum>"))
8038   elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
8039    exe "vert resize ".t:netrw_winwidth
8040"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8041   else
8042    call netrw#Lexplore(0,0)
8043   endif
8044
8045  else
8046   call netrw#Lexplore(0,0)
8047  endif
8048  let wiw= wiwkeep
8049
8050"  call Dret("netrw#Shrink")
8051endfun
8052
8053" ---------------------------------------------------------------------
8054" s:NetSortSequence: allows user to edit the sorting sequence {{{2
8055fun! s:NetSortSequence(islocal)
8056"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
8057
8058  let ykeep= @@
8059  let svpos= winsaveview()
8060"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8061  call inputsave()
8062  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
8063  call inputrestore()
8064
8065  " refresh the listing
8066  let g:netrw_sort_sequence= newsortseq
8067  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8068"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8069  NetrwKeepj call winrestview(svpos)
8070  let @@= ykeep
8071
8072"  call Dret("NetSortSequence")
8073endfun
8074
8075" ---------------------------------------------------------------------
8076" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
8077"   User access provided by the <mF> mapping. (see :help netrw-mF)
8078"   Used by many MarkFile functions.
8079fun! s:NetrwUnmarkList(curbufnr,curdir)
8080"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
8081
8082  "  remove all files in local marked-file list from global list
8083  if exists("s:netrwmarkfilelist")
8084   for mfile in s:netrwmarkfilelist_{a:curbufnr}
8085    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
8086    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
8087    call remove(s:netrwmarkfilelist,idx)            " remove from global list
8088   endfor
8089   if s:netrwmarkfilelist == []
8090    unlet s:netrwmarkfilelist
8091   endif
8092
8093   " getting rid of the local marked-file lists is easy
8094   unlet s:netrwmarkfilelist_{a:curbufnr}
8095  endif
8096  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
8097   unlet s:netrwmarkfilemtch_{a:curbufnr}
8098  endif
8099  2match none
8100"  call Dret("s:NetrwUnmarkList")
8101endfun
8102
8103" ---------------------------------------------------------------------
8104" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
8105fun! s:NetrwUnmarkAll()
8106"  call Dfunc("s:NetrwUnmarkAll()")
8107  if exists("s:netrwmarkfilelist")
8108   unlet s:netrwmarkfilelist
8109  endif
8110  sil call s:NetrwUnmarkAll2()
8111  2match none
8112"  call Dret("s:NetrwUnmarkAll")
8113endfun
8114
8115" ---------------------------------------------------------------------
8116" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
8117fun! s:NetrwUnmarkAll2()
8118"  call Dfunc("s:NetrwUnmarkAll2()")
8119  redir => netrwmarkfilelist_let
8120  let
8121  redir END
8122  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
8123  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
8124  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
8125  for flist in netrwmarkfilelist_list
8126   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
8127   unlet s:netrwmarkfilelist_{curbufnr}
8128   unlet s:netrwmarkfilemtch_{curbufnr}
8129  endfor
8130"  call Dret("s:NetrwUnmarkAll2")
8131endfun
8132
8133" ---------------------------------------------------------------------
8134" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
8135"
8136" Marked files are in two types of lists:
8137"    s:netrwmarkfilelist    -- holds complete paths to all marked files
8138"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
8139"
8140" Marked files suitable for use with 2match are in:
8141"    s:netrwmarkfilemtch_#   -- used with 2match to display marked files
8142fun! s:NetrwUnMarkFile(islocal)
8143"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
8144  let svpos    = winsaveview()
8145"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8146  let curbufnr = bufnr("%")
8147
8148  " unmark marked file list
8149  " (although I expect s:NetrwUpload() to do it, I'm just making sure)
8150  if exists("s:netrwmarkfilelist")
8151"   "   call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
8152   unlet s:netrwmarkfilelist
8153  endif
8154
8155  let ibuf= 1
8156  while ibuf < bufnr("$")
8157   if exists("s:netrwmarkfilelist_".ibuf)
8158    unlet s:netrwmarkfilelist_{ibuf}
8159    unlet s:netrwmarkfilemtch_{ibuf}
8160   endif
8161   let ibuf = ibuf + 1
8162  endwhile
8163  2match none
8164
8165"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8166"call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8167call winrestview(svpos)
8168"  call Dret("s:NetrwUnMarkFile")
8169endfun
8170
8171" ---------------------------------------------------------------------
8172" s:NetrwMenu: generates the menu for gvim and netrw {{{2
8173fun! s:NetrwMenu(domenu)
8174
8175  if !exists("g:NetrwMenuPriority")
8176   let g:NetrwMenuPriority= 80
8177  endif
8178
8179  if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8180"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
8181
8182   if !exists("s:netrw_menu_enabled") && a:domenu
8183"    call Decho("initialize menu",'~'.expand("<slnum>"))
8184    let s:netrw_menu_enabled= 1
8185    exe 'sil! menu '.g:NetrwMenuPriority.'.1      '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
8186    exe 'sil! menu '.g:NetrwMenuPriority.'.5      '.g:NetrwTopLvlMenu.'-Sep1-	:'
8187    exe 'sil! menu '.g:NetrwMenuPriority.'.6      '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
8188    exe 'sil! menu '.g:NetrwMenuPriority.'.7      '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
8189    if g:netrw_dirhistmax > 0
8190     exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
8191     exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
8192     exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
8193     exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
8194    else
8195     exe 'sil! menu '.g:NetrwMenuPriority.'.8     '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History	:echo "(disabled)"'."\<cr>"
8196    endif
8197    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1    '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o	o'
8198    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2    '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v	v'
8199    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3    '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t	t'
8200    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4    '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p	p'
8201    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
8202    exe 'sil! menu '.g:NetrwMenuPriority.'.9.6    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
8203    exe 'sil! menu '.g:NetrwMenuPriority.'.9.7    '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
8204    exe 'sil! menu '.g:NetrwMenuPriority.'.9.8    '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
8205    exe 'sil! menu '.g:NetrwMenuPriority.'.9.9    '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
8206    exe 'sil! menu '.g:NetrwMenuPriority.'.10     '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
8207    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
8208    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
8209    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
8210    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
8211    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
8212    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t	t'
8213    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
8214    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1   '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
8215    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
8216    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
8217    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
8218    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
8219    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
8220    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
8221    exe 'sil! menu '.g:NetrwMenuPriority.'.13     '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
8222    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
8223    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
8224    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3   '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
8225    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4   '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
8226    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5   '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
8227    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6   '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
8228    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7   '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
8229    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8   '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
8230    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9   '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
8231    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10  '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
8232    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11  '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
8233    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12  '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
8234    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13  '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
8235    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14  '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
8236    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15  '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
8237    exe 'sil! menu '.g:NetrwMenuPriority.'.15     '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
8238    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i	:let w:netrw_liststyle=0<cr><c-L>'
8239    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i	:let w:netrw_liststyle=1<cr><c-L>'
8240    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i	:let w:netrw_liststyle=2<cr><c-L>'
8241    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i	:let w:netrw_liststyle=3<cr><c-L>'
8242    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>'
8243    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>'
8244    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>'
8245    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3   '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
8246    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>'
8247    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>'
8248    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>'
8249    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>'
8250    exe 'sil! menu '.g:NetrwMenuPriority.'.17     '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
8251    exe 'sil! menu '.g:NetrwMenuPriority.'.18     '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
8252    let s:netrw_menucnt= 28
8253    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
8254    call s:NetrwTgtMenu()      " let bookmarks and history be easy targets
8255
8256   elseif !a:domenu
8257    let s:netrwcnt = 0
8258    let curwin     = winnr()
8259    windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8260    exe curwin."wincmd w"
8261
8262    if s:netrwcnt <= 1
8263"     call Decho("clear menus",'~'.expand("<slnum>"))
8264     exe 'sil! unmenu '.g:NetrwTopLvlMenu
8265"     call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8266     sil! unlet s:netrw_menu_enabled
8267    endif
8268   endif
8269"   call Dret("NetrwMenu")
8270   return
8271  endif
8272
8273endfun
8274
8275" ---------------------------------------------------------------------
8276" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8277"                Used by the O maps (as <SID>NetrwObtain())
8278fun! s:NetrwObtain(islocal)
8279"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8280
8281  let ykeep= @@
8282  if exists("s:netrwmarkfilelist_{bufnr('%')}")
8283   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8284   call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8285   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
8286  else
8287   call netrw#Obtain(a:islocal,s:NetrwGetWord())
8288  endif
8289  let @@= ykeep
8290
8291"  call Dret("NetrwObtain")
8292endfun
8293
8294" ---------------------------------------------------------------------
8295" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
8296"   If there's only one window, then the window will first be split.
8297"   Returns:
8298"     choice = 0 : didn't have to choose
8299"     choice = 1 : saved modified file in window first
8300"     choice = 2 : didn't save modified file, opened window
8301"     choice = 3 : cancel open
8302fun! s:NetrwPrevWinOpen(islocal)
8303"  call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")")
8304
8305  let ykeep= @@
8306  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8307  let curdir = b:netrw_curdir
8308
8309  " get last window number and the word currently under the cursor
8310  let origwin   = winnr()
8311  let lastwinnr = winnr("$")
8312  let curword   = s:NetrwGetWord()
8313  let choice    = 0
8314  let s:treedir = s:NetrwTreeDir(a:islocal)
8315  let curdir    = s:treedir
8316"  call Decho("winnr($)#".lastwinnr." curword<".curword.">",'~'.expand("<slnum>"))
8317
8318  let didsplit = 0
8319  if lastwinnr == 1
8320   " if only one window, open a new one first
8321"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("<slnum>"))
8322   " g:netrw_preview=0: preview window shown in a horizontally split window
8323   " g:netrw_preview=1: preview window shown in a vertically   split window
8324   if g:netrw_preview
8325    " vertically split preview window
8326    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8327"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("<slnum>"))
8328    exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8329   else
8330    " horizontally split preview window
8331    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8332"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8333    exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8334   endif
8335   let didsplit = 1
8336"   call Decho("did split",'~'.expand("<slnum>"))
8337
8338  else
8339   NetrwKeepj call s:SaveBufVars()
8340   let eikeep= &ei
8341   setl ei=all
8342   wincmd p
8343"   call Decho("wincmd p  (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
8344
8345   " prevwinnr: the window number of the "prev" window
8346   " prevbufnr: the buffer number of the buffer in the "prev" window
8347   " bnrcnt   : the qty of windows open on the "prev" buffer
8348   let prevwinnr   = winnr()
8349   let prevbufnr   = bufnr("%")
8350   let prevbufname = bufname("%")
8351   let prevmod     = &mod
8352   let bnrcnt      = 0
8353   NetrwKeepj call s:RestoreBufVars()
8354"   call Decho("after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr,'~'.expand("<slnum>"))
8355
8356   " if the previous window's buffer has been changed (ie. its modified flag is set),
8357   " and it doesn't appear in any other extant window, then ask the
8358   " user if s/he wants to abandon modifications therein.
8359   if prevmod
8360"    call Decho("detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr(),'~'.expand("<slnum>"))
8361    windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8362"    call Decho("prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr,'~'.expand("<slnum>"))
8363    exe prevwinnr."wincmd w"
8364
8365    if bnrcnt == 1 && &hidden == 0
8366     " only one copy of the modified buffer in a window, and
8367     " hidden not set, so overwriting will lose the modified file.  Ask first...
8368     let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8369"     call Decho("(NetrwPrevWinOpen) prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("<slnum>"))
8370     let &ei= eikeep
8371
8372     if choice == 1
8373      " Yes -- write file & then browse
8374      let v:errmsg= ""
8375      sil w
8376      if v:errmsg != ""
8377       call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8378       exe origwin."wincmd w"
8379       let &ei = eikeep
8380       let @@  = ykeep
8381"       call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">")
8382       return choice
8383      endif
8384
8385     elseif choice == 2
8386      " No -- don't worry about changed file, just browse anyway
8387"      call Decho("don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")",'~'.expand("<slnum>"))
8388      echomsg "**note** changes to ".prevbufname." abandoned"
8389
8390     else
8391      " Cancel -- don't do this
8392"      call Decho("cancel, don't browse, switch to win#".origwin,'~'.expand("<slnum>"))
8393      exe origwin."wincmd w"
8394      let &ei= eikeep
8395      let @@ = ykeep
8396"      call Dret("s:NetrwPrevWinOpen ".choice." : cancelled")
8397      return choice
8398     endif
8399    endif
8400   endif
8401   let &ei= eikeep
8402  endif
8403
8404  " restore b:netrw_curdir (window split/enew may have lost it)
8405  let b:netrw_curdir= curdir
8406  if a:islocal < 2
8407   if a:islocal
8408    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
8409   else
8410    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
8411   endif
8412  endif
8413  let @@= ykeep
8414"  call Dret("s:NetrwPrevWinOpen ".choice)
8415  return choice
8416endfun
8417
8418" ---------------------------------------------------------------------
8419" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8420"                Always assumed to be local -> remote
8421"                call s:NetrwUpload(filename, target)
8422"                call s:NetrwUpload(filename, target, fromdirectory)
8423fun! s:NetrwUpload(fname,tgt,...)
8424"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
8425
8426  if a:tgt =~ '^\a\{3,}://'
8427   let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
8428  else
8429   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
8430  endif
8431"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
8432
8433  if a:0 > 0
8434   let fromdir= a:1
8435  else
8436   let fromdir= getcwd()
8437  endif
8438"  call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
8439
8440  if type(a:fname) == 1
8441   " handle uploading a single file using NetWrite
8442"   call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8443   1split
8444"   call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8445   exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8446"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8447   if a:tgt =~ '/$'
8448    let wfname= substitute(a:fname,'^.*/','','')
8449"    call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8450    exe "w! ".fnameescape(a:tgt.wfname)
8451   else
8452"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8453    exe "w ".fnameescape(a:tgt)
8454"    call Decho("done writing local->remote",'~'.expand("<slnum>"))
8455   endif
8456   q!
8457
8458  elseif type(a:fname) == 3
8459   " handle uploading a list of files via scp
8460"   call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8461   let curdir= getcwd()
8462   if a:tgt =~ '^scp:'
8463    if s:NetrwLcd(fromdir)
8464"     call Dret("s:NetrwUpload : lcd failure")
8465     return
8466    endif
8467    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8468    let args    = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8469    if exists("g:netrw_port") && g:netrw_port != ""
8470     let useport= " ".g:netrw_scpport." ".g:netrw_port
8471    else
8472     let useport= ""
8473    endif
8474    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8475    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8476    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8477    if s:NetrwLcd(curdir)
8478"     call Dret("s:NetrwUpload : lcd failure")
8479     return
8480    endif
8481
8482   elseif a:tgt =~ '^ftp:'
8483    call s:NetrwMethod(a:tgt)
8484
8485    if b:netrw_method == 2
8486     " handle uploading a list of files via ftp+.netrc
8487     let netrw_fname = b:netrw_fname
8488     sil NetrwKeepj new
8489"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8490
8491     NetrwKeepj put =g:netrw_ftpmode
8492"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8493
8494     if exists("g:netrw_ftpextracmd")
8495      NetrwKeepj put =g:netrw_ftpextracmd
8496"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8497     endif
8498
8499     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8500"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8501
8502     if tgtdir == ""
8503      let tgtdir= '/'
8504     endif
8505     NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8506"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8507
8508     for fname in a:fname
8509      NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8510"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8511     endfor
8512
8513     if exists("g:netrw_port") && g:netrw_port != ""
8514      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8515     else
8516"      call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8517      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8518     endif
8519     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8520     sil NetrwKeepj g/Local directory now/d
8521     call histdel("/",-1)
8522     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8523      call netrw#ErrorMsg(s:ERROR,getline(1),14)
8524     else
8525      bw!|q
8526     endif
8527
8528    elseif b:netrw_method == 3
8529     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8530     let netrw_fname= b:netrw_fname
8531     NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8532     let tmpbufnr= bufnr("%")
8533     setl ff=unix
8534
8535     if exists("g:netrw_port") && g:netrw_port != ""
8536      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8537"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8538     else
8539      NetrwKeepj put ='open '.g:netrw_machine
8540"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8541     endif
8542
8543     if exists("g:netrw_uid") && g:netrw_uid != ""
8544      if exists("g:netrw_ftp") && g:netrw_ftp == 1
8545       NetrwKeepj put =g:netrw_uid
8546"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8547       if exists("s:netrw_passwd")
8548        NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8549       endif
8550"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8551      elseif exists("s:netrw_passwd")
8552       NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8553"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8554      endif
8555     endif
8556
8557     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8558"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8559
8560     if exists("b:netrw_fname") && b:netrw_fname != ""
8561      NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8562"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8563     endif
8564
8565     if exists("g:netrw_ftpextracmd")
8566      NetrwKeepj put =g:netrw_ftpextracmd
8567"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8568     endif
8569
8570     for fname in a:fname
8571      NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8572"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8573     endfor
8574
8575     " perform ftp:
8576     " -i       : turns off interactive prompting from ftp
8577     " -n  unix : DON'T use <.netrc>, even though it exists
8578     " -n  win32: quit being obnoxious about password
8579     NetrwKeepj norm! 1Gdd
8580     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8581     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8582     sil NetrwKeepj g/Local directory now/d
8583     call histdel("/",-1)
8584     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8585      let debugkeep= &debug
8586      setl debug=msg
8587      call netrw#ErrorMsg(s:ERROR,getline(1),15)
8588      let &debug = debugkeep
8589      let mod    = 1
8590     else
8591      bw!|q
8592     endif
8593    elseif !exists("b:netrw_method") || b:netrw_method < 0
8594"     call Dret("s:#NetrwUpload : unsupported method")
8595     return
8596    endif
8597   else
8598    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
8599   endif
8600  endif
8601
8602"  call Dret("s:NetrwUpload")
8603endfun
8604
8605" ---------------------------------------------------------------------
8606" s:NetrwPreview: {{{2
8607fun! s:NetrwPreview(path) range
8608"  call Dfunc("NetrwPreview(path<".a:path.">)")
8609  let ykeep= @@
8610  NetrwKeepj call s:NetrwOptionSave("s:")
8611  NetrwKeepj call s:NetrwSafeOptions()
8612  if has("quickfix")
8613   if !isdirectory(s:NetrwFile(a:path))
8614    if g:netrw_preview && !g:netrw_alto
8615     let pvhkeep = &pvh
8616     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8617     let &pvh    = winwidth(0) - winsz
8618    endif
8619    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8620    if exists("pvhkeep")
8621     let &pvh= pvhkeep
8622    endif
8623   elseif !exists("g:netrw_quiet")
8624    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
8625   endif
8626  elseif !exists("g:netrw_quiet")
8627   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
8628  endif
8629  NetrwKeepj call s:NetrwOptionRestore("s:")
8630  let @@= ykeep
8631"  call Dret("NetrwPreview")
8632endfun
8633
8634" ---------------------------------------------------------------------
8635" s:NetrwRefresh: {{{2
8636fun! s:NetrwRefresh(islocal,dirname)
8637"  call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction)
8638  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
8639  setl ma noro
8640"  call Decho("setl ma noro",'~'.expand("<slnum>"))
8641"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8642  let ykeep      = @@
8643  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8644   if !exists("w:netrw_treetop")
8645    if exists("b:netrw_curdir")
8646     let w:netrw_treetop= b:netrw_curdir
8647    else
8648     let w:netrw_treetop= getcwd()
8649    endif
8650   endif
8651   NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
8652  endif
8653
8654  " save the cursor position before refresh.
8655  let screenposn = winsaveview()
8656"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8657
8658"  call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8659"  call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
8660  sil! NetrwKeepj %d _
8661  if a:islocal
8662   NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
8663  else
8664   NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
8665  endif
8666
8667  " restore position
8668"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8669  NetrwKeepj call winrestview(screenposn)
8670
8671  " restore file marks
8672  if has("syntax") && exists("g:syntax_on") && g:syntax_on
8673   if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8674" "   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8675    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8676   else
8677" "   call Decho("2match none  (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8678    2match none
8679   endif
8680 endif
8681
8682"  restore
8683  let @@= ykeep
8684"  call Dret("s:NetrwRefresh")
8685endfun
8686
8687" ---------------------------------------------------------------------
8688" s:NetrwRefreshDir: refreshes a directory by name {{{2
8689"                    Called by NetrwMarkFileCopy()
8690"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
8691fun! s:NetrwRefreshDir(islocal,dirname)
8692"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) g:netrw_fastbrowse=".g:netrw_fastbrowse)
8693  if g:netrw_fastbrowse == 0
8694   " slowest mode (keep buffers refreshed, local or remote)
8695"   call Decho("slowest mode: keep buffers refreshed, local or remote",'~'.expand("<slnum>"))
8696   let tgtwin= bufwinnr(a:dirname)
8697"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin,'~'.expand("<slnum>"))
8698
8699   if tgtwin > 0
8700    " tgtwin is being displayed, so refresh it
8701    let curwin= winnr()
8702"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")",'~'.expand("<slnum>"))
8703    exe tgtwin."wincmd w"
8704    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8705    exe curwin."wincmd w"
8706
8707   elseif bufnr(a:dirname) > 0
8708    let bn= bufnr(a:dirname)
8709"    call Decho("bd bufnr(".a:dirname.")=".bn,'~'.expand("<slnum>"))
8710    exe "sil keepj bd ".bn
8711   endif
8712
8713  elseif g:netrw_fastbrowse <= 1
8714"   call Decho("medium-speed mode: refresh local buffers only",'~'.expand("<slnum>"))
8715   NetrwKeepj call s:LocalBrowseRefresh()
8716  endif
8717"  call Dret("s:NetrwRefreshDir")
8718endfun
8719
8720" ---------------------------------------------------------------------
8721" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8722" window number to do its editing in.
8723" Supports   [count]C  where the count, if present, is used to specify
8724" a window to use for editing via the <cr> mapping.
8725fun! s:NetrwSetChgwin(...)
8726"  call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
8727  if a:0 > 0
8728"   call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8729   if a:1 == ""    " :NetrwC win#
8730    let g:netrw_chgwin= winnr()
8731   else              " :NetrwC
8732    let g:netrw_chgwin= a:1
8733   endif
8734  elseif v:count > 0 " [count]C
8735   let g:netrw_chgwin= v:count
8736  else               " C
8737   let g:netrw_chgwin= winnr()
8738  endif
8739  echo "editing window now set to window#".g:netrw_chgwin
8740"  call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
8741endfun
8742
8743" ---------------------------------------------------------------------
8744" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8745"          What this function does is to compute a priority for the patterns
8746"          in the g:netrw_sort_sequence.  It applies a substitute to any
8747"          "files" that satisfy each pattern, putting the priority / in
8748"          front.  An "*" pattern handles the default priority.
8749fun! s:NetrwSetSort()
8750"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
8751  let ykeep= @@
8752  if w:netrw_liststyle == s:LONGLIST
8753   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
8754  else
8755   let seqlist  = g:netrw_sort_sequence
8756  endif
8757  " sanity check -- insure that * appears somewhere
8758  if seqlist == ""
8759   let seqlist= '*'
8760  elseif seqlist !~ '\*'
8761   let seqlist= seqlist.',*'
8762  endif
8763  let priority = 1
8764  while seqlist != ""
8765   if seqlist =~ ','
8766    let seq     = substitute(seqlist,',.*$','','e')
8767    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
8768   else
8769    let seq     = seqlist
8770    let seqlist = ""
8771   endif
8772   if priority < 10
8773    let spriority= "00".priority.g:netrw_sepchr
8774   elseif priority < 100
8775    let spriority= "0".priority.g:netrw_sepchr
8776   else
8777    let spriority= priority.g:netrw_sepchr
8778   endif
8779"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
8780
8781   " sanity check
8782   if w:netrw_bannercnt > line("$")
8783    " apparently no files were left after a Hiding pattern was used
8784"    call Dret("SetSort : no files left after hiding")
8785    return
8786   endif
8787   if seq == '*'
8788    let starpriority= spriority
8789   else
8790    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
8791    call histdel("/",-1)
8792    " sometimes multiple sorting patterns will match the same file or directory.
8793    " The following substitute is intended to remove the excess matches.
8794    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
8795    NetrwKeepj call histdel("/",-1)
8796   endif
8797   let priority = priority + 1
8798  endwhile
8799  if exists("starpriority")
8800   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
8801   NetrwKeepj call histdel("/",-1)
8802  endif
8803
8804  " Following line associated with priority -- items that satisfy a priority
8805  " pattern get prefixed by ###/ which permits easy sorting by priority.
8806  " Sometimes files can satisfy multiple priority patterns -- only the latest
8807  " priority pattern needs to be retained.  So, at this point, these excess
8808  " priority prefixes need to be removed, but not directories that happen to
8809  " be just digits themselves.
8810  exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
8811  NetrwKeepj call histdel("/",-1)
8812  let @@= ykeep
8813
8814"  call Dret("SetSort")
8815endfun
8816
8817" ---------------------------------------------------------------------
8818" s:NetrwSetTgt: sets the target to the specified choice index {{{2
8819"    Implements [count]Tb  (bookhist<b>)
8820"               [count]Th  (bookhist<h>)
8821"               See :help netrw-qb for how to make the choice.
8822fun! s:NetrwSetTgt(islocal,bookhist,choice)
8823"  call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
8824
8825  if     a:bookhist == 'b'
8826   " supports choosing a bookmark as a target using a qb-generated list
8827   let choice= a:choice - 1
8828   if exists("g:netrw_bookmarklist[".choice."]")
8829    call netrw#MakeTgt(g:netrw_bookmarklist[choice])
8830   else
8831    echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
8832   endif
8833
8834  elseif a:bookhist == 'h'
8835   " supports choosing a history stack entry as a target using a qb-generated list
8836   let choice= (a:choice % g:netrw_dirhistmax) + 1
8837   if exists("g:netrw_dirhist_".choice)
8838    let histentry = g:netrw_dirhist_{choice}
8839    call netrw#MakeTgt(histentry)
8840   else
8841    echomsg "Sorry, history#".a:choice." not available!"
8842   endif
8843  endif
8844
8845  " refresh the display
8846  if !exists("b:netrw_curdir")
8847   let b:netrw_curdir= getcwd()
8848  endif
8849  call s:NetrwRefresh(a:islocal,b:netrw_curdir)
8850
8851"  call Dret("s:NetrwSetTgt")
8852endfun
8853
8854" =====================================================================
8855" s:NetrwSortStyle: change sorting style (name - time - size) and refresh display {{{2
8856fun! s:NetrwSortStyle(islocal)
8857"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
8858  NetrwKeepj call s:NetrwSaveWordPosn()
8859  let svpos= winsaveview()
8860"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8861
8862  let g:netrw_sort_by= (g:netrw_sort_by =~# '^n')? 'time' : (g:netrw_sort_by =~# '^t')? 'size' : (g:netrw_sort_by =~# '^siz')? 'exten' : 'name'
8863  NetrwKeepj norm! 0
8864  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8865"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8866  NetrwKeepj call winrestview(svpos)
8867
8868"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
8869endfun
8870
8871" ---------------------------------------------------------------------
8872" s:NetrwSplit: mode {{{2
8873"           =0 : net   and o
8874"           =1 : net   and t
8875"           =2 : net   and v
8876"           =3 : local and o
8877"           =4 : local and t
8878"           =5 : local and v
8879fun! s:NetrwSplit(mode)
8880"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
8881
8882  let ykeep= @@
8883  call s:SaveWinVars()
8884
8885  if a:mode == 0
8886   " remote and o
8887   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8888   if winsz == 0|let winsz= ""|endif
8889"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8890   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8891   let s:didsplit= 1
8892   NetrwKeepj call s:RestoreWinVars()
8893   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
8894   unlet s:didsplit
8895
8896  elseif a:mode == 1
8897   " remote and t
8898   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
8899"   call Decho("tabnew",'~'.expand("<slnum>"))
8900   tabnew
8901   let s:didsplit= 1
8902   NetrwKeepj call s:RestoreWinVars()
8903   NetrwKeepj call s:NetrwBrowse(0,newdir)
8904   unlet s:didsplit
8905
8906  elseif a:mode == 2
8907   " remote and v
8908   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8909   if winsz == 0|let winsz= ""|endif
8910"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
8911   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8912   let s:didsplit= 1
8913   NetrwKeepj call s:RestoreWinVars()
8914   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
8915   unlet s:didsplit
8916
8917  elseif a:mode == 3
8918   " local and o
8919   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8920   if winsz == 0|let winsz= ""|endif
8921"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8922   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8923   let s:didsplit= 1
8924   NetrwKeepj call s:RestoreWinVars()
8925   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8926   unlet s:didsplit
8927
8928  elseif a:mode == 4
8929   " local and t
8930   let cursorword  = s:NetrwGetWord()
8931   let eikeep      = &ei
8932   let netrw_winnr = winnr()
8933   let netrw_line  = line(".")
8934   let netrw_col   = virtcol(".")
8935   NetrwKeepj norm! H0
8936   let netrw_hline = line(".")
8937   setl ei=all
8938   exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8939   exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8940   let &ei          = eikeep
8941   let netrw_curdir = s:NetrwTreeDir(0)
8942"   call Decho("tabnew",'~'.expand("<slnum>"))
8943   tabnew
8944   let b:netrw_curdir = netrw_curdir
8945   let s:didsplit     = 1
8946   NetrwKeepj call s:RestoreWinVars()
8947   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
8948   if &ft == "netrw"
8949    setl ei=all
8950    exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8951    exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8952    let &ei= eikeep
8953   endif
8954   unlet s:didsplit
8955
8956  elseif a:mode == 5
8957   " local and v
8958   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8959   if winsz == 0|let winsz= ""|endif
8960"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
8961   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8962   let s:didsplit= 1
8963   NetrwKeepj call s:RestoreWinVars()
8964   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8965   unlet s:didsplit
8966
8967  else
8968   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
8969  endif
8970
8971  let @@= ykeep
8972"  call Dret("s:NetrwSplit")
8973endfun
8974
8975" ---------------------------------------------------------------------
8976" s:NetrwTgtMenu: {{{2
8977fun! s:NetrwTgtMenu()
8978  if !exists("s:netrw_menucnt")
8979   return
8980  endif
8981"  call Dfunc("s:NetrwTgtMenu()")
8982
8983  " the following test assures that gvim is running, has menus available, and has menus enabled.
8984  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8985   if exists("g:NetrwTopLvlMenu")
8986"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
8987    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
8988   endif
8989   if !exists("s:netrw_initbookhist")
8990    call s:NetrwBookHistRead()
8991   endif
8992
8993   " try to cull duplicate entries
8994   let tgtdict={}
8995
8996   " target bookmarked places
8997   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
8998"    call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
8999    let cnt= 1
9000    for bmd in g:netrw_bookmarklist
9001     if has_key(tgtdict,bmd)
9002      let cnt= cnt + 1
9003      continue
9004     endif
9005     let tgtdict[bmd]= cnt
9006     let ebmd= escape(bmd,g:netrw_menu_escape)
9007     " show bookmarks for goto menu
9008"     call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
9009     exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd."	:call netrw#MakeTgt('".bmd."')\<cr>"
9010     let cnt= cnt + 1
9011    endfor
9012   endif
9013
9014   " target directory browsing history
9015   if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
9016"    call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
9017    let histcnt = 1
9018    while histcnt <= g:netrw_dirhistmax
9019     let priority = g:netrw_dirhist_cnt + histcnt
9020     if exists("g:netrw_dirhist_{histcnt}")
9021      let histentry  = g:netrw_dirhist_{histcnt}
9022      if has_key(tgtdict,histentry)
9023       let histcnt = histcnt + 1
9024       continue
9025      endif
9026      let tgtdict[histentry] = histcnt
9027      let ehistentry         = escape(histentry,g:netrw_menu_escape)
9028"      call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
9029      exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry."	:call netrw#MakeTgt('".histentry."')\<cr>"
9030     endif
9031     let histcnt = histcnt + 1
9032    endwhile
9033   endif
9034  endif
9035"  call Dret("s:NetrwTgtMenu")
9036endfun
9037
9038" ---------------------------------------------------------------------
9039" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
9040" (full path directory with trailing slash returned)
9041fun! s:NetrwTreeDir(islocal)
9042"  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)
9043"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
9044"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9045"  call Decho("w:netrw_treetop  =".(exists("w:netrw_treetop")?   w:netrw_treetop   : 'n/a'),'~'.expand("<slnum>"))
9046
9047  if exists("s:treedir")
9048   " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
9049   let treedir= s:treedir
9050   unlet s:treedir
9051"   call Dret("s:NetrwTreeDir ".treedir)
9052   return treedir
9053  endif
9054
9055  if !exists("b:netrw_curdir") || b:netrw_curdir == ""
9056   let b:netrw_curdir= getcwd()
9057  endif
9058  let treedir = b:netrw_curdir
9059"  call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>"))
9060
9061  let s:treecurpos= winsaveview()
9062"  call Decho("saving posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9063
9064  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9065"   call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>"))
9066"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9067
9068   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
9069   let curline= substitute(getline('.'),"\t -->.*$",'','')
9070   if curline =~ '/$'
9071"    call Decho("extract tree subdirectory from current line",'~'.expand("<slnum>"))
9072    let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9073"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9074   elseif curline =~ '@$'
9075"    call Decho("handle symbolic link from current line",'~'.expand("<slnum>"))
9076    let treedir= resolve(substitute(substitute(getline('.'),'@.*$','','e'),'^|*\s*','','e'))
9077"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9078   else
9079"    call Decho("do not extract tree subdirectory from current line and set treedir to empty",'~'.expand("<slnum>"))
9080    let treedir= ""
9081   endif
9082
9083   " detect user attempting to close treeroot
9084"   call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>"))
9085"   call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9086"   call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~# '^'.s:treedepthstring)? '=~#' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>"))
9087   if curline !~ '^'.s:treedepthstring && getline('.') != '..'
9088"    call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>"))
9089    " now force a refresh
9090"    call Decho(".force refresh: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9091    sil! NetrwKeepj %d _
9092"    call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9093    return b:netrw_curdir
9094"   else " Decho
9095"    call Decho(".user not attempting to close treeroot",'~'.expand("<slnum>"))
9096   endif
9097
9098"   call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>"))
9099   let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
9100"   call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(potentialdir),'~'.expand("<slnum>"))
9101
9102   " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
9103"   if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
9104"    let newdir          = w:netrw_treetop.'/'.potentialdir
9105" "   call Decho("apply NetrwTreePath to newdir<".newdir.">",'~'.expand("<slnum>"))
9106"    let treedir         = s:NetrwTreePath(newdir)
9107"    let w:netrw_treetop = newdir
9108" "   call Decho("newdir <".newdir.">",'~'.expand("<slnum>"))
9109"   else
9110"    call Decho("apply NetrwTreePath to treetop<".w:netrw_treetop.">",'~'.expand("<slnum>"))
9111    let treedir = s:NetrwTreePath(w:netrw_treetop)
9112"   endif
9113  endif
9114
9115  " sanity maintenance: keep those //s away...
9116  let treedir= substitute(treedir,'//$','/','')
9117"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9118
9119"  call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
9120  return treedir
9121endfun
9122
9123" ---------------------------------------------------------------------
9124" s:NetrwTreeDisplay: recursive tree display {{{2
9125fun! s:NetrwTreeDisplay(dir,depth)
9126"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
9127
9128  " insure that there are no folds
9129  setl nofen
9130
9131  " install ../ and shortdir
9132  if a:depth == ""
9133   call setline(line("$")+1,'../')
9134"   call Decho("setline#".line("$")." ../ (depth is zero)",'~'.expand("<slnum>"))
9135  endif
9136  if a:dir =~ '^\a\{3,}://'
9137   if a:dir == w:netrw_treetop
9138    let shortdir= a:dir
9139   else
9140    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
9141   endif
9142   call setline(line("$")+1,a:depth.shortdir)
9143  else
9144   let shortdir= substitute(a:dir,'^.*/','','e')
9145   call setline(line("$")+1,a:depth.shortdir.'/')
9146  endif
9147"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">",'~'.expand("<slnum>"))
9148
9149  " append a / to dir if its missing one
9150  let dir= a:dir
9151
9152  " display subtrees (if any)
9153  let depth= s:treedepthstring.a:depth
9154"  call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>"))
9155
9156  " implement g:netrw_hide for tree listings (uses g:netrw_list_hide)
9157  if     g:netrw_hide == 1
9158   " hide given patterns
9159   let listhide= split(g:netrw_list_hide,',')
9160"   call Decho("listhide=".string(listhide))
9161   for pat in listhide
9162    call filter(w:netrw_treedict[dir],'v:val !~ "'.pat.'"')
9163   endfor
9164
9165  elseif g:netrw_hide == 2
9166   " show given patterns (only)
9167   let listhide= split(g:netrw_list_hide,',')
9168"   call Decho("listhide=".string(listhide))
9169   let entries=[]
9170   for entry in w:netrw_treedict[dir]
9171    for pat in listhide
9172     if entry =~ pat
9173      call add(entries,entry)
9174      break
9175     endif
9176    endfor
9177   endfor
9178   let w:netrw_treedict[dir]= entries
9179  endif
9180  if depth != ""
9181   " always remove "." and ".." entries when there's depth
9182   call filter(w:netrw_treedict[dir],'v:val !~ "\\.\\.$"')
9183   call filter(w:netrw_treedict[dir],'v:val !~ "\\.$"')
9184  endif
9185
9186"  call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>"))
9187  for entry in w:netrw_treedict[dir]
9188   if dir =~ '/$'
9189    let direntry= substitute(dir.entry,'[@/]$','','e')
9190   else
9191    let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
9192   endif
9193"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9194   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9195"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9196    NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
9197   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9198"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9199    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9200   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9201"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9202    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
9203   else
9204"    call Decho("<".entry."> is not a key in treedict (no subtree)",'~'.expand("<slnum>"))
9205    sil! NetrwKeepj call setline(line("$")+1,depth.entry)
9206   endif
9207  endfor
9208"  call Decho("displaying: ".string(getline(w:netrw_bannercnt,'$')))
9209
9210"  call Dret("NetrwTreeDisplay")
9211endfun
9212
9213" ---------------------------------------------------------------------
9214" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
9215fun! s:NetrwRefreshTreeDict(dir)
9216"  call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)")
9217  if !exists("w:netrw_treedict")
9218"   call Dret("s:NetrwRefreshTreeDict : w:netrw_treedict doesn't exist")
9219   return
9220  endif
9221
9222  for entry in w:netrw_treedict[a:dir]
9223   let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
9224"   call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
9225
9226   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
9227"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9228    NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
9229    let liststar                   = s:NetrwGlob(direntry,'*',1)
9230    let listdotstar                = s:NetrwGlob(direntry,'.*',1)
9231    let w:netrw_treedict[direntry] = liststar + listdotstar
9232"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9233
9234   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9235"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9236    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9237    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9238    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9239    let w:netrw_treedict[direntry]= liststar + listdotstar
9240"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9241
9242   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9243"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9244    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9245    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9246    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9247"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9248
9249   else
9250"    call Decho('not updating w:netrw_treedict['.string(direntry).'] with entry<'.string(entry).'> (no subtree)','~'.expand("<slnum>"))
9251   endif
9252  endfor
9253"  call Dret("s:NetrwRefreshTreeDict")
9254endfun
9255
9256" ---------------------------------------------------------------------
9257" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
9258"                     Called by s:PerformListing()
9259fun! s:NetrwTreeListing(dirname)
9260  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9261"   call Dfunc("NetrwTreeListing() bufname<".expand("%").">")
9262"   call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
9263"   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>"))
9264"   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>"))
9265
9266   " update the treetop
9267"   call Decho("update the treetop",'~'.expand("<slnum>"))
9268   if !exists("w:netrw_treetop")
9269    let w:netrw_treetop= a:dirname
9270"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>"))
9271   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
9272    let w:netrw_treetop= a:dirname
9273"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
9274   endif
9275
9276   if !exists("w:netrw_treedict")
9277    " insure that we have a treedict, albeit empty
9278"    call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
9279    let w:netrw_treedict= {}
9280   endif
9281
9282   " update the dictionary for the current directory
9283"   call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>"))
9284"   call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9285   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
9286   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
9287"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
9288   exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9289
9290   " if past banner, record word
9291   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
9292    let fname= expand("<cword>")
9293   else
9294    let fname= ""
9295   endif
9296"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9297"   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>"))
9298
9299   " display from treetop on down
9300   NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
9301"   call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
9302
9303   " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
9304   while getline(1) =~ '^\s*$' && byte2line(1) > 0
9305"    call Decho("deleting blank line",'~'.expand("<slnum>"))
9306    1d
9307   endwhile
9308
9309   exe "setl ".g:netrw_bufsettings
9310
9311"   call Dret("NetrwTreeListing : bufname<".expand("%").">")
9312   return
9313  endif
9314endfun
9315
9316" ---------------------------------------------------------------------
9317" s:NetrwTreePath: returns path to current file/directory in tree listing {{{2
9318"                  Normally, treetop is w:netrw_treetop, but a
9319"                  user of the function ( netrw#SetTreetop() )
9320"                  wipes that out prior to calling this function
9321fun! s:NetrwTreePath(treetop)
9322"  call Dfunc("s:NetrwTreePath(treetop<".a:treetop.">) line#".line(".")."<".getline(".").">")
9323  if line(".") < w:netrw_bannercnt + 2
9324   let treedir= a:treetop
9325   if treedir !~ '/$'
9326    let treedir= treedir.'/'
9327   endif
9328"   call Dret("s:NetrwTreePath ".treedir." : line#".line(".")." ≤ ".(w:netrw_bannercnt+2))
9329   return treedir
9330  endif
9331
9332  let svpos = winsaveview()
9333"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9334  let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
9335"  call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
9336  let depth = substitute(depth,'^'.s:treedepthstring,'','')
9337"  call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
9338  let curline= getline('.')
9339"  call Decho("curline<".curline.'>','~'.expand("<slnum>"))
9340  if curline =~ '/$'
9341"   call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9342   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9343"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9344  elseif curline =~ '@\s\+-->'
9345"   call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9346   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9347   let treedir= substitute(treedir,'@\s\+-->.*$','','e')
9348"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9349  else
9350"   call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9351   let treedir= ""
9352  endif
9353  " construct treedir by searching backwards at correct depth
9354"  call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9355"  call Decho("initial      treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
9356  while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
9357   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9358   let treedir= dirname.treedir
9359   let depth  = substitute(depth,'^'.s:treedepthstring,'','')
9360"   call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
9361  endwhile
9362"  call Decho("treedir#1<".treedir.">",'~'.expand("<slnum>"))
9363  if a:treetop =~ '/$'
9364   let treedir= a:treetop.treedir
9365  else
9366   let treedir= a:treetop.'/'.treedir
9367  endif
9368"  call Decho("treedir#2<".treedir.">",'~'.expand("<slnum>"))
9369  let treedir= substitute(treedir,'//$','/','')
9370"  call Decho("treedir#3<".treedir.">",'~'.expand("<slnum>"))
9371"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
9372  call winrestview(svpos)
9373"  call Dret("s:NetrwTreePath <".treedir.">")
9374  return treedir
9375endfun
9376
9377" ---------------------------------------------------------------------
9378" s:NetrwWideListing: {{{2
9379fun! s:NetrwWideListing()
9380
9381  if w:netrw_liststyle == s:WIDELIST
9382"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9383   " look for longest filename (cpf=characters per filename)
9384   " cpf: characters per filename
9385   " fpl: filenames per line
9386   " fpc: filenames per column
9387   setl ma noro
9388"   call Decho("setl ma noro",'~'.expand("<slnum>"))
9389   let b:netrw_cpf= 0
9390   if line("$") >= w:netrw_bannercnt
9391    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
9392    NetrwKeepj call histdel("/",-1)
9393   else
9394"    call Dret("NetrwWideListing")
9395    return
9396   endif
9397   let b:netrw_cpf= b:netrw_cpf + 2
9398"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
9399
9400   " determine qty files per line (fpl)
9401   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9402   if w:netrw_fpl <= 0
9403    let w:netrw_fpl= 1
9404   endif
9405"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
9406
9407   " make wide display
9408   "   fpc: files per column of wide listing
9409   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9410   NetrwKeepj call histdel("/",-1)
9411   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9412   let newcolstart = w:netrw_bannercnt + fpc
9413   let newcolend   = newcolstart + fpc - 1
9414"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9415   if has("clipboard")
9416    sil! let keepregstar = @*
9417    sil! let keepregplus = @+
9418   endif
9419   while line("$") >= newcolstart
9420    if newcolend > line("$") | let newcolend= line("$") | endif
9421    let newcolqty= newcolend - newcolstart
9422    exe newcolstart
9423    if newcolqty == 0
9424     exe "sil! NetrwKeepj norm! 0\<c-v>$hx".w:netrw_bannercnt."G$p"
9425    else
9426     exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$hx'.w:netrw_bannercnt.'G$p'
9427    endif
9428    exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
9429    exe 'sil! NetrwKeepj '.w:netrw_bannercnt
9430   endwhile
9431   if has("clipboard")
9432    sil! let @*= keepregstar
9433    sil! let @+= keepregplus
9434   endif
9435   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9436   NetrwKeepj call histdel("/",-1)
9437   exe 'nno <buffer> <silent> w	:call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9438   exe 'nno <buffer> <silent> b	:call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9439"   call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9440   exe "setl ".g:netrw_bufsettings
9441"   call Decho("(NetrwWideListing) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9442"   call Dret("NetrwWideListing")
9443   return
9444  else
9445   if hasmapto("w","n")
9446    sil! nunmap <buffer> w
9447   endif
9448   if hasmapto("b","n")
9449    sil! nunmap <buffer> b
9450   endif
9451  endif
9452
9453endfun
9454
9455" ---------------------------------------------------------------------
9456" s:PerformListing: {{{2
9457fun! s:PerformListing(islocal)
9458"  call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9459"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9460"  call Decho("settings: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (enter)"." ei<".&ei.">",'~'.expand("<slnum>"))
9461
9462  " set up syntax highlighting {{{3
9463"  call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
9464  sil! setl ft=netrw
9465
9466  NetrwKeepj call s:NetrwSafeOptions()
9467  setl noro ma
9468"  call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
9469
9470"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
9471"   call Decho("(netrw) Processing your browsing request...",'~'.expand("<slnum>"))
9472"  endif								" Decho
9473
9474"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9475  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
9476   " force a refresh for tree listings
9477"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9478   sil! NetrwKeepj %d _
9479  endif
9480
9481  " save current directory on directory history list
9482  NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
9483
9484  " Set up the banner {{{3
9485  if g:netrw_banner
9486"   call Decho("--set up banner",'~'.expand("<slnum>"))
9487   NetrwKeepj call setline(1,'" ============================================================================')
9488   if exists("g:netrw_pchk")
9489    " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9490    " failure detections.
9491    NetrwKeepj call setline(2,'" Netrw Directory Listing')
9492   else
9493    NetrwKeepj call setline(2,'" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')')
9494   endif
9495   if exists("g:netrw_pchk")
9496    let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9497   else
9498    let curdir= b:netrw_curdir
9499   endif
9500   if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9501    NetrwKeepj call setline(3,'"   '.substitute(curdir,'/','\\','g'))
9502   else
9503    NetrwKeepj call setline(3,'"   '.curdir)
9504   endif
9505   let w:netrw_bannercnt= 3
9506   NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
9507  else
9508"   call Decho("--no banner",'~'.expand("<slnum>"))
9509   NetrwKeepj 1
9510   let w:netrw_bannercnt= 1
9511  endif
9512"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9513"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9514
9515  let sortby= g:netrw_sort_by
9516  if g:netrw_sort_direction =~# "^r"
9517   let sortby= sortby." reversed"
9518  endif
9519
9520  " Sorted by... {{{3
9521  if g:netrw_banner
9522"   call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9523   if g:netrw_sort_by =~# "^n"
9524"   call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9525    " sorted by name
9526    NetrwKeepj put ='\"   Sorted by      '.sortby
9527    NetrwKeepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
9528    let w:netrw_bannercnt= w:netrw_bannercnt + 2
9529   else
9530"   call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9531    " sorted by size or date
9532    NetrwKeepj put ='\"   Sorted by '.sortby
9533    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9534   endif
9535   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9536"  else " Decho
9537"   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>"))
9538  endif
9539
9540  " show copy/move target, if any {{{3
9541  if g:netrw_banner
9542   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9543"    call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9544    NetrwKeepj put =''
9545    if s:netrwmftgt_islocal
9546     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9547    else
9548     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9549    endif
9550    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9551   else
9552"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
9553   endif
9554   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9555  endif
9556
9557  " Hiding...  -or-  Showing... {{{3
9558  if g:netrw_banner
9559"   call Decho("--handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9560   if g:netrw_list_hide != "" && g:netrw_hide
9561    if g:netrw_hide == 1
9562     NetrwKeepj put ='\"   Hiding:        '.g:netrw_list_hide
9563    else
9564     NetrwKeepj put ='\"   Showing:       '.g:netrw_list_hide
9565    endif
9566    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9567   endif
9568   exe "NetrwKeepj ".w:netrw_bannercnt
9569
9570"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9571   let quickhelp   = g:netrw_quickhelp%len(s:QuickHelp)
9572"   call Decho("quickhelp   =".quickhelp,'~'.expand("<slnum>"))
9573   NetrwKeepj put ='\"   Quick Help: <F1>:help  '.s:QuickHelp[quickhelp]
9574"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9575   NetrwKeepj put ='\" =============================================================================='
9576   let w:netrw_bannercnt= w:netrw_bannercnt + 2
9577"  else " Decho
9578"   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>"))
9579  endif
9580
9581  " bannercnt should index the line just after the banner
9582  if g:netrw_banner
9583   let w:netrw_bannercnt= w:netrw_bannercnt + 1
9584   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9585"   call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9586"  else " Decho
9587"   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>"))
9588  endif
9589
9590  " get list of files
9591"  call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
9592  if a:islocal
9593   NetrwKeepj call s:LocalListing()
9594  else " remote
9595   NetrwKeepj let badresult= s:NetrwRemoteListing()
9596   if badresult
9597"    call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9598"    call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9599    return
9600   endif
9601  endif
9602
9603  " manipulate the directory listing (hide, sort) {{{3
9604  if !exists("w:netrw_bannercnt")
9605   let w:netrw_bannercnt= 0
9606  endif
9607"  call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9608"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9609"  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>"))
9610
9611  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9612"   call Decho("manipulate directory listing (hide)",'~'.expand("<slnum>"))
9613"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9614   if g:netrw_hide && g:netrw_list_hide != ""
9615    NetrwKeepj call s:NetrwListHide()
9616   endif
9617   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9618"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9619
9620    if g:netrw_sort_by =~# "^n"
9621     " sort by name
9622     NetrwKeepj call s:NetrwSetSort()
9623
9624     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9625"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9626      if g:netrw_sort_direction =~# 'n'
9627       " normal direction sorting
9628       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9629      else
9630       " reverse direction sorting
9631       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9632      endif
9633     endif
9634     " remove priority pattern prefix
9635"     call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9636     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9637     NetrwKeepj call histdel("/",-1)
9638
9639    elseif g:netrw_sort_by =~# "^ext"
9640     " sort by extension
9641     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9642     NetrwKeepj call histdel("/",-1)
9643     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9644     NetrwKeepj call histdel("/",-1)
9645     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9646     NetrwKeepj call histdel("/",-1)
9647     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9648"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9649      if g:netrw_sort_direction =~# 'n'
9650       " normal direction sorting
9651       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9652      else
9653       " reverse direction sorting
9654       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9655      endif
9656     endif
9657     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9658     NetrwKeepj call histdel("/",-1)
9659
9660    elseif a:islocal
9661     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9662"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9663      if g:netrw_sort_direction =~# 'n'
9664"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9665       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9666      else
9667"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9668       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9669      endif
9670     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9671     NetrwKeepj call histdel("/",-1)
9672     endif
9673    endif
9674
9675   elseif g:netrw_sort_direction =~# 'r'
9676"    call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9677    if !g:netrw_banner || w:netrw_bannercnt < line('$')
9678     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9679     call histdel("/",-1)
9680    endif
9681   endif
9682  endif
9683"  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>"))
9684
9685  " convert to wide/tree listing {{{3
9686"  call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9687"  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>"))
9688  NetrwKeepj call s:NetrwWideListing()
9689"  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>"))
9690  NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
9691"  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>"))
9692
9693  " resolve symbolic links if local and (thin or tree)
9694  if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
9695"   call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9696   sil! g/@$/call s:ShowLink()
9697  endif
9698
9699  if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
9700   " place cursor on the top-left corner of the file listing
9701"   call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9702   exe 'sil! '.w:netrw_bannercnt
9703   sil! NetrwKeepj norm! 0
9704"   call Decho("  tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9705  else
9706"   call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9707"   call Decho("  w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9708"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
9709"   call Decho("  g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
9710  endif
9711
9712  " record previous current directory
9713  let w:netrw_prvdir= b:netrw_curdir
9714"  call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
9715
9716  " save certain window-oriented variables into buffer-oriented variables {{{3
9717"  call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9718"  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>"))
9719  NetrwKeepj call s:SetBufWinVars()
9720"  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>"))
9721  NetrwKeepj call s:NetrwOptionRestore("w:")
9722"  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>"))
9723
9724  " set display to netrw display settings
9725"  call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
9726  exe "setl ".g:netrw_bufsettings
9727"  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>"))
9728  if g:netrw_liststyle == s:LONGLIST
9729"   call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9730   exe "setl ts=".(g:netrw_maxfilenamelen+1)
9731  endif
9732
9733  if exists("s:treecurpos")
9734"   call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
9735"   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>"))
9736"   call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9737   NetrwKeepj call winrestview(s:treecurpos)
9738   unlet s:treecurpos
9739  endif
9740
9741"  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>"))
9742"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9743"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
9744endfun
9745
9746" ---------------------------------------------------------------------
9747" s:SetupNetrwStatusLine: {{{2
9748fun! s:SetupNetrwStatusLine(statline)
9749"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
9750
9751  if !exists("s:netrw_setup_statline")
9752   let s:netrw_setup_statline= 1
9753"   call Decho("do first-time status line setup",'~'.expand("<slnum>"))
9754
9755   if !exists("s:netrw_users_stl")
9756    let s:netrw_users_stl= &stl
9757   endif
9758   if !exists("s:netrw_users_ls")
9759    let s:netrw_users_ls= &laststatus
9760   endif
9761
9762   " set up User9 highlighting as needed
9763   let keepa= @a
9764   redir @a
9765   try
9766    hi User9
9767   catch /^Vim\%((\a\{3,})\)\=:E411/
9768    if &bg == "dark"
9769     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
9770    else
9771     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
9772    endif
9773   endtry
9774   redir END
9775   let @a= keepa
9776  endif
9777
9778  " set up status line (may use User9 highlighting)
9779  " insure that windows have a statusline
9780  " make sure statusline is displayed
9781  let &stl=a:statline
9782  setl laststatus=2
9783"  call Decho("stl=".&stl,'~'.expand("<slnum>"))
9784  redraw
9785
9786"  call Dret("SetupNetrwStatusLine : stl=".&stl)
9787endfun
9788
9789" =========================================
9790"  Remote Directory Browsing Support:  {{{1
9791" =========================================
9792
9793" ---------------------------------------------------------------------
9794" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
9795"  This function assumes that a long listing will be received.  Size, time,
9796"  and reverse sorts will be requested of the server but not otherwise
9797"  enforced here.
9798fun! s:NetrwRemoteFtpCmd(path,listcmd)
9799"  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 : "???")))
9800"  call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9801  " sanity check: {{{3
9802  if !exists("w:netrw_method")
9803   if exists("b:netrw_method")
9804    let w:netrw_method= b:netrw_method
9805   else
9806    call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
9807"    call Dret("NetrwRemoteFtpCmd")
9808    return
9809   endif
9810  endif
9811
9812  " WinXX ftp uses unix style input, so set ff to unix	" {{{3
9813  let ffkeep= &ff
9814  setl ma ff=unix noro
9815"  call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
9816
9817  " clear off any older non-banner lines	" {{{3
9818  " note that w:netrw_bannercnt indexes the line after the banner
9819"  call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _  (clear off old non-banner lines)",'~'.expand("<slnum>"))
9820  exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9821
9822  ".........................................
9823  if w:netrw_method == 2 || w:netrw_method == 5	" {{{3
9824   " ftp + <.netrc>:  Method #2
9825   if a:path != ""
9826    NetrwKeepj put ='cd \"'.a:path.'\"'
9827   endif
9828   if exists("g:netrw_ftpextracmd")
9829    NetrwKeepj put =g:netrw_ftpextracmd
9830"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9831   endif
9832   NetrwKeepj call setline(line("$")+1,a:listcmd)
9833"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9834   if exists("g:netrw_port") && g:netrw_port != ""
9835"    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>"))
9836    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)
9837   else
9838"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
9839    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
9840   endif
9841
9842  ".........................................
9843  elseif w:netrw_method == 3	" {{{3
9844   " ftp + machine,id,passwd,filename:  Method #3
9845    setl ff=unix
9846    if exists("g:netrw_port") && g:netrw_port != ""
9847     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
9848    else
9849     NetrwKeepj put ='open '.g:netrw_machine
9850    endif
9851
9852    " handle userid and password
9853    let host= substitute(g:netrw_machine,'\..*$','','')
9854"    call Decho("host<".host.">",'~'.expand("<slnum>"))
9855    if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
9856     call NetUserPass("ftp:".host)
9857    endif
9858    if exists("g:netrw_uid") && g:netrw_uid != ""
9859     if exists("g:netrw_ftp") && g:netrw_ftp == 1
9860      NetrwKeepj put =g:netrw_uid
9861      if exists("s:netrw_passwd") && s:netrw_passwd != ""
9862       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
9863      endif
9864     elseif exists("s:netrw_passwd")
9865      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
9866     endif
9867    endif
9868
9869   if a:path != ""
9870    NetrwKeepj put ='cd \"'.a:path.'\"'
9871   endif
9872   if exists("g:netrw_ftpextracmd")
9873    NetrwKeepj put =g:netrw_ftpextracmd
9874"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9875   endif
9876   NetrwKeepj call setline(line("$")+1,a:listcmd)
9877
9878   " perform ftp:
9879   " -i       : turns off interactive prompting from ftp
9880   " -n  unix : DON'T use <.netrc>, even though it exists
9881   " -n  win32: quit being obnoxious about password
9882   if exists("w:netrw_bannercnt")
9883"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9884    call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
9885"   else " Decho
9886"    call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
9887"    g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
9888   endif
9889
9890  ".........................................
9891  elseif w:netrw_method == 9	" {{{3
9892   " sftp username@machine: Method #9
9893   " s:netrw_sftp_cmd
9894   setl ff=unix
9895
9896   " restore settings
9897   let &ff= ffkeep
9898"   call Dret("NetrwRemoteFtpCmd")
9899   return
9900
9901  ".........................................
9902  else	" {{{3
9903   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
9904  endif
9905
9906  " cleanup for Windows " {{{3
9907  if has("win32") || has("win95") || has("win64") || has("win16")
9908   sil! NetrwKeepj %s/\r$//e
9909   NetrwKeepj call histdel("/",-1)
9910  endif
9911  if a:listcmd == "dir"
9912   " infer directory/link based on the file permission string
9913   sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
9914   sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
9915   NetrwKeepj call histdel("/",-1)
9916   NetrwKeepj call histdel("/",-1)
9917   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9918    exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
9919    NetrwKeepj call histdel("/",-1)
9920   endif
9921  endif
9922
9923  " ftp's listing doesn't seem to include ./ or ../ " {{{3
9924  if !search('^\.\/$\|\s\.\/$','wn')
9925   exe 'NetrwKeepj '.w:netrw_bannercnt
9926   NetrwKeepj put ='./'
9927  endif
9928  if !search('^\.\.\/$\|\s\.\.\/$','wn')
9929   exe 'NetrwKeepj '.w:netrw_bannercnt
9930   NetrwKeepj put ='../'
9931  endif
9932
9933  " restore settings " {{{3
9934  let &ff= ffkeep
9935"  call Dret("NetrwRemoteFtpCmd")
9936endfun
9937
9938" ---------------------------------------------------------------------
9939" s:NetrwRemoteListing: {{{2
9940fun! s:NetrwRemoteListing()
9941"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
9942
9943  if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
9944   let w:netrw_bannercnt= s:bannercnt
9945  endif
9946  if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
9947   let w:netrw_bannercnt= s:bannercnt
9948  endif
9949
9950  call s:RemotePathAnalysis(b:netrw_curdir)
9951
9952  " sanity check:
9953  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
9954"   call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
9955   if !executable("ftp")
9956"    call Decho("ftp is not executable",'~'.expand("<slnum>"))
9957    if !exists("g:netrw_quiet")
9958     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
9959    endif
9960    call s:NetrwOptionRestore("w:")
9961"    call Dret("s:NetrwRemoteListing -1")
9962    return -1
9963   endif
9964
9965  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
9966"   call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
9967   if !exists("g:netrw_quiet")
9968    if g:netrw_list_cmd == ""
9969     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)
9970    else
9971     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
9972    endif
9973   endif
9974
9975   NetrwKeepj call s:NetrwOptionRestore("w:")
9976"   call Dret("s:NetrwRemoteListing -1")
9977   return -1
9978  endif  " (remote handling sanity check)
9979"  call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
9980
9981  if exists("b:netrw_method")
9982"   call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
9983   let w:netrw_method= b:netrw_method
9984  endif
9985
9986  if s:method == "ftp"
9987   " use ftp to get remote file listing {{{3
9988"   call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
9989   let s:method  = "ftp"
9990   let listcmd = g:netrw_ftp_list_cmd
9991   if g:netrw_sort_by =~# '^t'
9992    let listcmd= g:netrw_ftp_timelist_cmd
9993   elseif g:netrw_sort_by =~# '^s'
9994    let listcmd= g:netrw_ftp_sizelist_cmd
9995   endif
9996"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
9997   call s:NetrwRemoteFtpCmd(s:path,listcmd)
9998"   exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
9999
10000   " report on missing file or directory messages
10001   if search('[Nn]o such file or directory\|Failed to change directory')
10002    let mesg= getline(".")
10003    if exists("w:netrw_bannercnt")
10004     setl ma
10005     exe w:netrw_bannercnt.",$d _"
10006     setl noma
10007    endif
10008    NetrwKeepj call s:NetrwOptionRestore("w:")
10009    call netrw#ErrorMsg(s:WARNING,mesg,96)
10010"    call Dret("s:NetrwRemoteListing : -1")
10011    return -1
10012   endif
10013
10014   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
10015    " shorten the listing
10016"    call Decho("generate short listing",'~'.expand("<slnum>"))
10017    exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
10018
10019    " cleanup
10020    if g:netrw_ftp_browse_reject != ""
10021     exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
10022     NetrwKeepj call histdel("/",-1)
10023    endif
10024    sil! NetrwKeepj %s/\r$//e
10025    NetrwKeepj call histdel("/",-1)
10026
10027    " if there's no ../ listed, then put ../ in
10028    let line1= line(".")
10029    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10030    let line2= search('\.\.\/\%(\s\|$\)','cnW')
10031"    call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2."  w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
10032    if line2 == 0
10033"     call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
10034     sil! NetrwKeepj put='../'
10035    endif
10036    exe "sil! NetrwKeepj ".line1
10037    sil! NetrwKeepj norm! 0
10038
10039"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
10040    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10041"     call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
10042     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
10043     NetrwKeepj call histdel("/",-1)
10044    else " normal ftp cleanup
10045"     call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
10046     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
10047     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
10048     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
10049     NetrwKeepj call histdel("/",-1)
10050     NetrwKeepj call histdel("/",-1)
10051     NetrwKeepj call histdel("/",-1)
10052    endif
10053   endif
10054
10055   else
10056   " use ssh to get remote file listing {{{3
10057"   call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
10058   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
10059"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
10060   if g:netrw_scp_cmd =~ '^pscp'
10061"    call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
10062    exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
10063    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
10064    sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
10065    sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
10066    sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
10067    NetrwKeepj call histdel("/",-1)
10068    NetrwKeepj call histdel("/",-1)
10069    NetrwKeepj call histdel("/",-1)
10070    if g:netrw_liststyle != s:LONGLIST
10071     sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
10072     NetrwKeepj call histdel("/",-1)
10073    endif
10074   else
10075    if s:path == ""
10076"     call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
10077     exe "NetrwKeepj keepalt r! ".listcmd
10078    else
10079"     call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
10080     exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
10081"     call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
10082    endif
10083   endif
10084
10085   " cleanup
10086   if g:netrw_ssh_browse_reject != ""
10087"    call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
10088    exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
10089    NetrwKeepj call histdel("/",-1)
10090   endif
10091  endif
10092
10093  if w:netrw_liststyle == s:LONGLIST
10094   " do a long listing; these substitutions need to be done prior to sorting {{{3
10095"   call Decho("fix long listing:",'~'.expand("<slnum>"))
10096
10097   if s:method == "ftp"
10098    " cleanup
10099    exe "sil! NetrwKeepj ".w:netrw_bannercnt
10100    while getline('.') =~# g:netrw_ftp_browse_reject
10101     sil! NetrwKeepj d
10102    endwhile
10103    " if there's no ../ listed, then put ../ in
10104    let line1= line(".")
10105    sil! NetrwKeepj 1
10106    sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
10107    let line2= line(".")
10108    if line2 == 0
10109     if b:netrw_curdir != '/'
10110      exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
10111     endif
10112    endif
10113    exe "sil! NetrwKeepj ".line1
10114    sil! NetrwKeepj norm! 0
10115   endif
10116
10117   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
10118"    call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
10119    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/'
10120   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
10121"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
10122    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
10123    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
10124    exe 'sil NetrwKeepj '.w:netrw_bannercnt
10125    NetrwKeepj call histdel("/",-1)
10126    NetrwKeepj call histdel("/",-1)
10127    NetrwKeepj call histdel("/",-1)
10128   endif
10129  endif
10130
10131"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
10132"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
10133"  endif " Decho
10134
10135"  call Dret("s:NetrwRemoteListing 0")
10136  return 0
10137endfun
10138
10139" ---------------------------------------------------------------------
10140" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
10141fun! s:NetrwRemoteRm(usrhost,path) range
10142"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
10143"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10144  let svpos= winsaveview()
10145"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10146
10147  let all= 0
10148  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10149   " remove all marked files
10150"   call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>"))
10151   for fname in s:netrwmarkfilelist_{bufnr("%")}
10152    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
10153    if ok =~# 'q\%[uit]'
10154     break
10155    elseif ok =~# 'a\%[ll]'
10156     let all= 1
10157    endif
10158   endfor
10159   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10160
10161  else
10162   " remove files specified by range
10163"   call Decho("remove files specified by range",'~'.expand("<slnum>"))
10164
10165   " preparation for removing multiple files/directories
10166   let keepsol = &l:sol
10167   setl nosol
10168   let ctr    = a:firstline
10169
10170   " remove multiple files and directories
10171   while ctr <= a:lastline
10172    exe "NetrwKeepj ".ctr
10173    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
10174    if ok =~# 'q\%[uit]'
10175     break
10176    elseif ok =~# 'a\%[ll]'
10177     let all= 1
10178    endif
10179    let ctr= ctr + 1
10180   endwhile
10181   let &l:sol = keepsol
10182  endif
10183
10184  " refresh the (remote) directory listing
10185"  call Decho("refresh remote directory listing",'~'.expand("<slnum>"))
10186  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10187"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10188  NetrwKeepj call winrestview(svpos)
10189
10190"  call Dret("s:NetrwRemoteRm")
10191endfun
10192
10193" ---------------------------------------------------------------------
10194" s:NetrwRemoteRmFile: {{{2
10195fun! s:NetrwRemoteRmFile(path,rmfile,all)
10196"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
10197
10198  let all= a:all
10199  let ok = ""
10200
10201  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
10202   " attempt to remove file
10203"    call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
10204   if !all
10205    echohl Statement
10206"    call Decho("case all=0:",'~'.expand("<slnum>"))
10207    call inputsave()
10208    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10209    call inputrestore()
10210    echohl NONE
10211    if ok == ""
10212     let ok="no"
10213    endif
10214    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10215    if ok =~# 'a\%[ll]'
10216     let all= 1
10217    endif
10218   endif
10219
10220   if all || ok =~# 'y\%[es]' || ok == ""
10221"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
10222    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10223"     call Decho("case ftp:",'~'.expand("<slnum>"))
10224     let path= a:path
10225     if path =~ '^\a\{3,}://'
10226      let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
10227     endif
10228     sil! NetrwKeepj .,$d _
10229     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
10230    else
10231"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
10232     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
10233"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10234     if !exists("b:netrw_curdir")
10235      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
10236      let ok="q"
10237     else
10238      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
10239"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
10240"      call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
10241"      call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
10242      if remotedir != ""
10243       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
10244      else
10245       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
10246      endif
10247"      call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
10248      let ret= system(netrw_rm_cmd)
10249      if v:shell_error != 0
10250       if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
10251        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)
10252       else
10253        call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10254       endif
10255      elseif ret != 0
10256       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10257      endif
10258"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10259     endif
10260    endif
10261   elseif ok =~# 'q\%[uit]'
10262"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10263   endif
10264
10265  else
10266   " attempt to remove directory
10267"    call Decho("attempt to remove directory",'~'.expand("<slnum>"))
10268   if !all
10269    call inputsave()
10270    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10271    call inputrestore()
10272    if ok == ""
10273     let ok="no"
10274    endif
10275    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10276    if ok =~# 'a\%[ll]'
10277     let all= 1
10278    endif
10279   endif
10280
10281   if all || ok =~# 'y\%[es]' || ok == ""
10282    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10283     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
10284    else
10285     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
10286     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
10287"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
10288     let ret= system(netrw_rmdir_cmd)
10289"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10290
10291     if v:shell_error != 0
10292"      call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
10293      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
10294"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
10295      let ret= system(netrw_rmf_cmd)
10296"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10297
10298      if v:shell_error != 0 && !exists("g:netrw_quiet")
10299      	NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
10300      endif
10301     endif
10302    endif
10303
10304   elseif ok =~# 'q\%[uit]'
10305"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10306   endif
10307  endif
10308
10309"  call Dret("s:NetrwRemoteRmFile ".ok)
10310  return ok
10311endfun
10312
10313" ---------------------------------------------------------------------
10314" s:NetrwRemoteRename: rename a remote file or directory {{{2
10315fun! s:NetrwRemoteRename(usrhost,path) range
10316"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
10317
10318  " preparation for removing multiple files/directories
10319  let svpos      = winsaveview()
10320"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10321  let ctr        = a:firstline
10322  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10323
10324  " rename files given by the markfilelist
10325  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10326   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10327"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10328    if exists("subfrom")
10329     let newname= substitute(oldname,subfrom,subto,'')
10330"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10331    else
10332     call inputsave()
10333     let newname= input("Moving ".oldname." to : ",oldname)
10334     call inputrestore()
10335     if newname =~ '^s/'
10336      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10337      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10338      let newname = substitute(oldname,subfrom,subto,'')
10339"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10340     endif
10341    endif
10342
10343    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10344     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10345    else
10346     let oldname= s:ShellEscape(a:path.oldname)
10347     let newname= s:ShellEscape(a:path.newname)
10348"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10349     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10350    endif
10351
10352   endfor
10353   call s:NetrwUnMarkFile(1)
10354
10355  else
10356
10357  " attempt to rename files/directories
10358   let keepsol= &l:sol
10359   setl nosol
10360   while ctr <= a:lastline
10361    exe "NetrwKeepj ".ctr
10362
10363    let oldname= s:NetrwGetWord()
10364"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10365
10366    call inputsave()
10367    let newname= input("Moving ".oldname." to : ",oldname)
10368    call inputrestore()
10369
10370    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10371     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10372    else
10373     let oldname= s:ShellEscape(a:path.oldname)
10374     let newname= s:ShellEscape(a:path.newname)
10375"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10376     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10377    endif
10378
10379    let ctr= ctr + 1
10380   endwhile
10381   let &l:sol= keepsol
10382  endif
10383
10384  " refresh the directory
10385  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10386"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10387  NetrwKeepj call winrestview(svpos)
10388
10389"  call Dret("NetrwRemoteRename")
10390endfun
10391
10392" ==========================================
10393"  Local Directory Browsing Support:    {{{1
10394" ==========================================
10395
10396" ---------------------------------------------------------------------
10397" netrw#FileUrlEdit: handles editing file://* files {{{2
10398"   Should accept:   file://localhost/etc/fstab
10399"                    file:///etc/fstab
10400"                    file:///c:/WINDOWS/clock.avi
10401"                    file:///c|/WINDOWS/clock.avi
10402"                    file://localhost/c:/WINDOWS/clock.avi
10403"                    file://localhost/c|/WINDOWS/clock.avi
10404"                    file://c:/foo.txt
10405"                    file:///c:/foo.txt
10406" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
10407fun! netrw#FileUrlEdit(fname)
10408"  call Dfunc("netrw#FileUrlEdit(fname<".a:fname.">)")
10409  let fname = a:fname
10410  if fname =~ '^file://localhost/'
10411"   call Decho('converting file://localhost/   -to-  file:///','~'.expand("<slnum>"))
10412   let fname= substitute(fname,'^file://localhost/','file:///','')
10413"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10414  endif
10415  if (has("win32") || has("win95") || has("win64") || has("win16"))
10416   if fname  =~ '^file:///\=\a[|:]/'
10417"    call Decho('converting file:///\a|/   -to-  file://\a:/','~'.expand("<slnum>"))
10418    let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10419"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10420   endif
10421  endif
10422  let fname2396 = netrw#RFC2396(fname)
10423  let fname2396e= fnameescape(fname2396)
10424  let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
10425  if (has("win32") || has("win95") || has("win64") || has("win16"))
10426"   call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10427   if plainfname =~ '^/\+\a:'
10428"    call Decho('removing leading "/"s','~'.expand("<slnum>"))
10429    let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10430   endif
10431  endif
10432
10433"  call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10434"  call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
10435  exe "sil doau BufReadPre ".fname2396e
10436  exe 'NetrwKeepj keepalt edit '.plainfname
10437  exe 'sil! NetrwKeepj keepalt bdelete '.fnameescape(a:fname)
10438
10439"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10440"  call Dret("netrw#FileUrlEdit")
10441  exe "sil doau BufReadPost ".fname2396e
10442endfun
10443
10444" ---------------------------------------------------------------------
10445" netrw#LocalBrowseCheck: {{{2
10446fun! netrw#LocalBrowseCheck(dirname)
10447  " This function is called by netrwPlugin.vim's s:LocalBrowse(), s:NetrwRexplore(), and by <cr> when atop listed file/directory
10448  " unfortunate interaction -- split window debugging can't be
10449  " used here, must use D-echoRemOn or D-echoTabOn -- the BufEnter
10450  " event triggers another call to LocalBrowseCheck() when attempts
10451  " to write to the DBG buffer are made.
10452  " The &ft == "netrw" test was installed because the BufEnter event
10453  " would hit when re-entering netrw windows, creating unexpected
10454  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
10455"  call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">")
10456"  call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>"))
10457"  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>"))
10458"  call Dredir("ls!","netrw#LocalBrowseCheck")
10459"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10460"  call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
10461
10462  let ykeep= @@
10463  if isdirectory(s:NetrwFile(a:dirname))
10464"   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>"))
10465
10466   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10467"    call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10468"    call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10469    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10470
10471   elseif &ft == "netrw" && line("$") == 1
10472"    call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10473    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10474
10475   elseif exists("s:treeforceredraw")
10476"    call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10477    unlet s:treeforceredraw
10478    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10479   endif
10480"   call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10481"   call Dret("netrw#LocalBrowseCheck")
10482   return
10483  endif
10484
10485  " following code wipes out currently unused netrw buffers
10486  "       IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10487  "   AND IF the listing style is not a tree listing
10488  if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
10489"   call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10490   let ibuf    = 1
10491   let buflast = bufnr("$")
10492   while ibuf <= buflast
10493    if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10494     exe "sil! keepj keepalt ".ibuf."bw!"
10495    endif
10496    let ibuf= ibuf + 1
10497   endwhile
10498  endif
10499  let @@= ykeep
10500"  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>"))
10501"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10502  " not a directory, ignore it
10503"  call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
10504endfun
10505
10506" ---------------------------------------------------------------------
10507" s:LocalBrowseRefresh: this function is called after a user has {{{2
10508" performed any shell command.  The idea is to cause all local-browsing
10509" buffers to be refreshed after a user has executed some shell command,
10510" on the chance that s/he removed/created a file/directory with it.
10511fun! s:LocalBrowseRefresh()
10512"  call Dfunc("s:LocalBrowseRefresh() tabpagenr($)=".tabpagenr("$"))
10513"  call Decho("s:netrw_browselist =".(exists("s:netrw_browselist")?  string(s:netrw_browselist)  : '<n/a>'),'~'.expand("<slnum>"))
10514"  call Decho("w:netrw_bannercnt  =".(exists("w:netrw_bannercnt")?   string(w:netrw_bannercnt)   : '<n/a>'),'~'.expand("<slnum>"))
10515
10516  " determine which buffers currently reside in a tab
10517  if !exists("s:netrw_browselist")
10518"   call Dret("s:LocalBrowseRefresh : browselist is empty")
10519   return
10520  endif
10521  if !exists("w:netrw_bannercnt")
10522"   call Dret("s:LocalBrowseRefresh : don't refresh when focus not on netrw window")
10523   return
10524  endif
10525  if exists("s:netrw_events") && s:netrw_events == 1
10526   " s:LocalFastBrowser gets called (indirectly) from a
10527   let s:netrw_events= 2
10528"   call Dret("s:LocalBrowseRefresh : avoid initial double refresh")
10529   return
10530  endif
10531  let itab       = 1
10532  let buftablist = []
10533  let ykeep      = @@
10534  while itab <= tabpagenr("$")
10535   let buftablist = buftablist + tabpagebuflist()
10536   let itab       = itab + 1
10537   sil! tabn
10538  endwhile
10539"  call Decho("buftablist".string(buftablist),'~'.expand("<slnum>"))
10540"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("<slnum>"))
10541  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10542  "   | refresh any netrw window
10543  "   | wipe out any non-displaying netrw buffer
10544  let curwinid = win_getid(winnr())
10545  let ibl    = 0
10546  for ibuf in s:netrw_browselist
10547"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("<slnum>"))
10548   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10549    " wipe out any non-displaying netrw buffer
10550    " (ibuf not shown in a current window AND
10551    "  ibuf not in any tab)
10552"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("<slnum>"))
10553    exe "sil! keepj bd ".fnameescape(ibuf)
10554    call remove(s:netrw_browselist,ibl)
10555"    call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10556    continue
10557   elseif index(tabpagebuflist(),ibuf) != -1
10558    " refresh any netrw buffer
10559"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>"))
10560    exe bufwinnr(ibuf)."wincmd w"
10561    if getline(".") =~# 'Quick Help'
10562     " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10563     " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10564     let g:netrw_quickhelp= g:netrw_quickhelp - 1
10565    endif
10566"    call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>"))
10567    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10568     NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10569    endif
10570    NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10571   endif
10572   let ibl= ibl + 1
10573"   call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("<slnum>"))
10574  endfor
10575"  call Decho("restore window: win_gotoid(".curwinid.")")
10576  call win_gotoid(curwinid)
10577  let @@= ykeep
10578
10579"  call Dret("s:LocalBrowseRefresh")
10580endfun
10581
10582" ---------------------------------------------------------------------
10583" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10584"
10585"     g:netrw_    Directory Is
10586"     fastbrowse  Local  Remote
10587"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
10588"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
10589"  fast   2         H      H
10590"
10591"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10592"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
10593"                       (re-using a buffer may not be as accurate)
10594"
10595"  s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds whena med or fast browsing
10596"                   =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10597"                       BufEnter may be first event, then a FocusGained event.  Ignore the first FocusGained event.
10598"                       If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10599"                   =2: autocmds installed (doesn't ignore any FocusGained events)
10600fun! s:LocalFastBrowser()
10601"  call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
10602"  call Decho("s:netrw_events        ".(exists("s:netrw_events")? "exists"    : 'n/a'),'~'.expand("<slnum>"))
10603"  call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")?  "installed" : "not installed"),'~'.expand("<slnum>"))
10604"  call Decho("autocmd: FocusGained  ".(exists("#FocusGained")?   "installed" : "not installed"),'~'.expand("<slnum>"))
10605
10606  " initialize browselist, a list of buffer numbers that the local browser has used
10607  if !exists("s:netrw_browselist")
10608"   call Decho("initialize s:netrw_browselist",'~'.expand("<slnum>"))
10609   let s:netrw_browselist= []
10610  endif
10611
10612  " append current buffer to fastbrowse list
10613  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
10614"   call Decho("appendng current buffer to browselist",'~'.expand("<slnum>"))
10615   call add(s:netrw_browselist,bufnr("%"))
10616"   call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10617  endif
10618
10619  " enable autocmd events to handle refreshing/removing local browser buffers
10620  "    If local browse buffer is currently showing: refresh it
10621  "    If local browse buffer is currently hidden : wipe it
10622  "    g:netrw_fastbrowse=0 : slow   speed, never re-use directory listing
10623  "                      =1 : medium speed, re-use directory listing for remote only
10624  "                      =2 : fast   speed, always re-use directory listing when possible
10625  if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
10626   let s:netrw_events= 1
10627   augroup AuNetrwEvent
10628    au!
10629    if (has("win32") || has("win95") || has("win64") || has("win16"))
10630"     call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
10631     au ShellCmdPost			*	call s:LocalBrowseRefresh()
10632    else
10633"     call Decho("installing autocmds: ShellCmdPost FocusGained",'~'.expand("<slnum>"))
10634     au ShellCmdPost,FocusGained	*	call s:LocalBrowseRefresh()
10635    endif
10636   augroup END
10637
10638  " user must have changed fastbrowse to its fast setting, so remove
10639  " the associated autocmd events
10640  elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
10641"   call Decho("remove AuNetrwEvent autcmd group",'~'.expand("<slnum>"))
10642   unlet s:netrw_events
10643   augroup AuNetrwEvent
10644    au!
10645   augroup END
10646   augroup! AuNetrwEvent
10647  endif
10648
10649"  call Dret("LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
10650endfun
10651
10652" ---------------------------------------------------------------------
10653"  s:LocalListing: does the job of "ls" for local directories {{{2
10654fun! s:LocalListing()
10655"  call Dfunc("s:LocalListing()")
10656"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10657"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
10658"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10659
10660"  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
10661"  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
10662"  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>"))
10663
10664  " get the list of files contained in the current directory
10665  let dirname    = b:netrw_curdir
10666  let dirnamelen = strlen(b:netrw_curdir)
10667  let filelist   = s:NetrwGlob(dirname,"*",0)
10668  let filelist   = filelist + s:NetrwGlob(dirname,".*",0)
10669"  call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10670
10671  if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
10672"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10673  elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
10674    " include ../ in the glob() entry if its missing
10675"   call Decho("forcibly including on \"..\"",'~'.expand("<slnum>"))
10676   let filelist= filelist+[s:ComposePath(b:netrw_curdir,"../")]
10677"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10678  endif
10679
10680"  call Decho("before while: dirname   <".dirname.">",'~'.expand("<slnum>"))
10681"  call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>"))
10682"  call Decho("before while: filelist  =".string(filelist),'~'.expand("<slnum>"))
10683
10684  if get(g:, 'netrw_dynamic_maxfilenamelen', 0)
10685   let filelistcopy           = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10686   let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
10687"   call Decho("dynamic_maxfilenamelen: filenames             =".string(filelistcopy),'~'.expand("<slnum>"))
10688"   call Decho("dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen,'~'.expand("<slnum>"))
10689  endif
10690"  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>"))
10691
10692  for filename in filelist
10693"   call Decho(" ",'~'.expand("<slnum>"))
10694"   call Decho("for filename in filelist: filename<".filename.">",'~'.expand("<slnum>"))
10695
10696   if getftype(filename) == "link"
10697    " indicate a symbolic link
10698"    call Decho("indicate <".filename."> is a symbolic link with trailing @",'~'.expand("<slnum>"))
10699    let pfile= filename."@"
10700
10701   elseif getftype(filename) == "socket"
10702    " indicate a socket
10703"    call Decho("indicate <".filename."> is a socket with trailing =",'~'.expand("<slnum>"))
10704    let pfile= filename."="
10705
10706   elseif getftype(filename) == "fifo"
10707    " indicate a fifo
10708"    call Decho("indicate <".filename."> is a fifo with trailing |",'~'.expand("<slnum>"))
10709    let pfile= filename."|"
10710
10711   elseif isdirectory(s:NetrwFile(filename))
10712    " indicate a directory
10713"    call Decho("indicate <".filename."> is a directory with trailing /",'~'.expand("<slnum>"))
10714    let pfile= filename."/"
10715
10716   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10717    if (has("win32") || has("win95") || has("win64") || has("win16"))
10718     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10719      " indicate an executable
10720"      call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10721      let pfile= filename."*"
10722     else
10723      " normal file
10724      let pfile= filename
10725     endif
10726    elseif executable(filename)
10727     " indicate an executable
10728"     call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10729     let pfile= filename."*"
10730    else
10731     " normal file
10732     let pfile= filename
10733    endif
10734
10735   else
10736    " normal file
10737    let pfile= filename
10738   endif
10739"   call Decho("pfile<".pfile."> (after *@/ appending)",'~'.expand("<slnum>"))
10740
10741   if pfile =~ '//$'
10742    let pfile= substitute(pfile,'//$','/','e')
10743"    call Decho("change // to /: pfile<".pfile.">",'~'.expand("<slnum>"))
10744   endif
10745   let pfile= strpart(pfile,dirnamelen)
10746   let pfile= substitute(pfile,'^[/\\]','','e')
10747"   call Decho("filename<".filename.">",'~'.expand("<slnum>"))
10748"   call Decho("pfile   <".pfile.">",'~'.expand("<slnum>"))
10749
10750   if w:netrw_liststyle == s:LONGLIST
10751    let sz   = getfsize(filename)
10752    if g:netrw_sizestyle =~# "[hH]"
10753     let sz= s:NetrwHumanReadable(sz)
10754    endif
10755    let fsz  = strpart("               ",1,15-strlen(sz)).sz
10756    let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
10757"    call Decho("longlist support: sz=".sz." fsz=".fsz,'~'.expand("<slnum>"))
10758   endif
10759
10760   if     g:netrw_sort_by =~# "^t"
10761    " sort by time (handles time up to 1 quintillion seconds, US)
10762"    call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>"))
10763    let t  = getftime(filename)
10764    let ft = strpart("000000000000000000",1,18-strlen(t)).t
10765"    call Decho("exe NetrwKeepj put ='".ft.'/'.filename."'",'~'.expand("<slnum>"))
10766    let ftpfile= ft.'/'.pfile
10767    sil! NetrwKeepj put=ftpfile
10768
10769   elseif g:netrw_sort_by =~ "^s"
10770    " sort by size (handles file sizes up to 1 quintillion bytes, US)
10771"    call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>"))
10772    let sz   = getfsize(filename)
10773    if g:netrw_sizestyle =~# "[hH]"
10774     let sz= s:NetrwHumanReadable(sz)
10775    endif
10776    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
10777"    call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>"))
10778    let fszpfile= fsz.'/'.pfile
10779    sil! NetrwKeepj put =fszpfile
10780
10781   else
10782    " sort by name
10783"    call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("<slnum>"))
10784    sil! NetrwKeepj put=pfile
10785   endif
10786  endfor
10787
10788  " cleanup any windows mess at end-of-line
10789  sil! NetrwKeepj g/^$/d
10790  sil! NetrwKeepj %s/\r$//e
10791  call histdel("/",-1)
10792"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
10793  exe "setl ts=".(g:netrw_maxfilenamelen+1)
10794
10795"  call Dret("s:LocalListing")
10796endfun
10797
10798" ---------------------------------------------------------------------
10799" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
10800fun! s:NetrwLocalExecute(cmd)
10801"  call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
10802  let ykeep= @@
10803  " sanity check
10804  if !executable(a:cmd)
10805   call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
10806   let @@= ykeep
10807"   call Dret("s:NetrwLocalExecute")
10808   return
10809  endif
10810
10811  let optargs= input(":!".a:cmd,"","file")
10812"  call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
10813  let result= system(a:cmd.optargs)
10814"  call Decho("result,'~'.expand("<slnum>"))
10815
10816  " strip any ansi escape sequences off
10817  let result = substitute(result,"\e\\[[0-9;]*m","","g")
10818
10819  " show user the result(s)
10820  echomsg result
10821  let @@= ykeep
10822
10823"  call Dret("s:NetrwLocalExecute")
10824endfun
10825
10826" ---------------------------------------------------------------------
10827" s:NetrwLocalRename: rename a local file or directory {{{2
10828fun! s:NetrwLocalRename(path) range
10829"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
10830
10831  " preparation for removing multiple files/directories
10832  let ykeep    = @@
10833  let ctr      = a:firstline
10834  let svpos    = winsaveview()
10835"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10836
10837  " rename files given by the markfilelist
10838  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10839   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10840"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10841    if exists("subfrom")
10842     let newname= substitute(oldname,subfrom,subto,'')
10843"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10844    else
10845     call inputsave()
10846     let newname= input("Moving ".oldname." to : ",oldname,"file")
10847     call inputrestore()
10848     if newname =~ ''
10849      " two ctrl-x's : ignore all of string preceding the ctrl-x's
10850      let newname = substitute(newname,'^.*','','')
10851     elseif newname =~ ''
10852      " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
10853      let newname = substitute(newname,'[^/]*','','')
10854     endif
10855     if newname =~ '^s/'
10856      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10857      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10858"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10859      let newname = substitute(oldname,subfrom,subto,'')
10860     endif
10861    endif
10862    call rename(oldname,newname)
10863   endfor
10864   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10865
10866  else
10867
10868   " attempt to rename files/directories
10869   while ctr <= a:lastline
10870    exe "NetrwKeepj ".ctr
10871
10872    " sanity checks
10873    if line(".") < w:netrw_bannercnt
10874     let ctr= ctr + 1
10875     continue
10876    endif
10877    let curword= s:NetrwGetWord()
10878    if curword == "./" || curword == "../"
10879     let ctr= ctr + 1
10880     continue
10881    endif
10882
10883    NetrwKeepj norm! 0
10884    let oldname= s:ComposePath(a:path,curword)
10885"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10886
10887    call inputsave()
10888    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
10889    call inputrestore()
10890
10891    call rename(oldname,newname)
10892"   call Decho("renaming <".oldname."> to <".newname.">",'~'.expand("<slnum>"))
10893
10894    let ctr= ctr + 1
10895   endwhile
10896  endif
10897
10898  " refresh the directory
10899"  call Decho("refresh the directory listing",'~'.expand("<slnum>"))
10900  NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10901"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10902  NetrwKeepj call winrestview(svpos)
10903  let @@= ykeep
10904
10905"  call Dret("NetrwLocalRename")
10906endfun
10907
10908" ---------------------------------------------------------------------
10909" s:NetrwLocalRm: {{{2
10910fun! s:NetrwLocalRm(path) range
10911"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
10912"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10913
10914  " preparation for removing multiple files/directories
10915  let ykeep = @@
10916  let ret   = 0
10917  let all   = 0
10918  let svpos = winsaveview()
10919"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10920
10921  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10922   " remove all marked files
10923"   call Decho("remove all marked files",'~'.expand("<slnum>"))
10924   for fname in s:netrwmarkfilelist_{bufnr("%")}
10925    let ok= s:NetrwLocalRmFile(a:path,fname,all)
10926    if ok =~# 'q\%[uit]' || ok == "no"
10927     break
10928    elseif ok =~# 'a\%[ll]'
10929     let all= 1
10930    endif
10931   endfor
10932   call s:NetrwUnMarkFile(1)
10933
10934  else
10935  " remove (multiple) files and directories
10936"   call Decho("remove files in range [".a:firstline.",".a:lastline."]",'~'.expand("<slnum>"))
10937
10938   let keepsol= &l:sol
10939   setl nosol
10940   let ctr = a:firstline
10941   while ctr <= a:lastline
10942    exe "NetrwKeepj ".ctr
10943
10944    " sanity checks
10945    if line(".") < w:netrw_bannercnt
10946     let ctr= ctr + 1
10947     continue
10948    endif
10949    let curword= s:NetrwGetWord()
10950    if curword == "./" || curword == "../"
10951     let ctr= ctr + 1
10952     continue
10953    endif
10954    let ok= s:NetrwLocalRmFile(a:path,curword,all)
10955    if ok =~# 'q\%[uit]' || ok == "no"
10956     break
10957    elseif ok =~# 'a\%[ll]'
10958     let all= 1
10959    endif
10960    let ctr= ctr + 1
10961   endwhile
10962   let &l:sol= keepsol
10963  endif
10964
10965  " refresh the directory
10966"  call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>"))
10967  if bufname("%") != "NetrwMessage"
10968   NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10969"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10970   NetrwKeepj call winrestview(svpos)
10971  endif
10972  let @@= ykeep
10973
10974"  call Dret("s:NetrwLocalRm")
10975endfun
10976
10977" ---------------------------------------------------------------------
10978" s:NetrwLocalRmFile: remove file fname given the path {{{2
10979"                     Give confirmation prompt unless all==1
10980fun! s:NetrwLocalRmFile(path,fname,all)
10981"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
10982
10983  let all= a:all
10984  let ok = ""
10985  NetrwKeepj norm! 0
10986  let rmfile= s:NetrwFile(s:ComposePath(a:path,a:fname))
10987"  call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
10988
10989  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
10990   " attempt to remove file
10991"   call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
10992   if !all
10993    echohl Statement
10994    call inputsave()
10995    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10996    call inputrestore()
10997    echohl NONE
10998    if ok == ""
10999     let ok="no"
11000    endif
11001"    call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
11002    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11003"    call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
11004    if ok =~# 'a\%[ll]'
11005     let all= 1
11006    endif
11007   endif
11008
11009   if all || ok =~# 'y\%[es]' || ok == ""
11010    let ret= s:NetrwDelete(rmfile)
11011"    call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
11012   endif
11013
11014  else
11015   " attempt to remove directory
11016   if !all
11017    echohl Statement
11018    call inputsave()
11019    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
11020    call inputrestore()
11021    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
11022    if ok == ""
11023     let ok="no"
11024    endif
11025    if ok =~# 'a\%[ll]'
11026     let all= 1
11027    endif
11028   endif
11029   let rmfile= substitute(rmfile,'[\/]$','','e')
11030
11031   if all || ok =~# 'y\%[es]' || ok == ""
11032    if v:version < 704 || (v:version == 704 && !has("patch1107"))
11033" "    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>"))
11034     call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile))
11035" "    call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>"))
11036
11037     if v:shell_error != 0
11038" "     call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11039      let errcode= s:NetrwDelete(rmfile)
11040" "     call Decho("errcode=".errcode,'~'.expand("<slnum>"))
11041
11042      if errcode != 0
11043       if has("unix")
11044" "       call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
11045	call system("rm ".s:ShellEscape(rmfile))
11046	if v:shell_error != 0 && !exists("g:netrw_quiet")
11047	 call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
11048	 let ok="no"
11049	endif
11050       elseif !exists("g:netrw_quiet")
11051	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
11052	let ok="no"
11053       endif
11054      endif
11055     endif
11056    else
11057     if delete(rmfile,"d")
11058      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
11059     endif
11060    endif
11061   endif
11062  endif
11063
11064"  call Dret("s:NetrwLocalRmFile ".ok)
11065  return ok
11066endfun
11067
11068" =====================================================================
11069" Support Functions: {{{1
11070
11071" ---------------------------------------------------------------------
11072" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
11073"   0: marked file list of current buffer
11074"   1: marked file target
11075fun! netrw#Access(ilist)
11076  if     a:ilist == 0
11077   if exists("s:netrwmarkfilelist_".bufnr('%'))
11078    return s:netrwmarkfilelist_{bufnr('%')}
11079   else
11080    return "no-list-buf#".bufnr('%')
11081   endif
11082  elseif a:ilist == 1
11083   return s:netrwmftgt
11084  endif
11085endfun
11086
11087" ---------------------------------------------------------------------
11088" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
11089fun! netrw#Call(funcname,...)
11090  return call("s:".a:funcname,a:000)
11091endfun
11092
11093" ---------------------------------------------------------------------
11094" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
11095"               I expect this function to be used in
11096"                 :PChkAssert netrw#Expose("netrwmarkfilelist")
11097"               for example.
11098fun! netrw#Expose(varname)
11099"   call Dfunc("netrw#Expose(varname<".a:varname.">)")
11100  if exists("s:".a:varname)
11101   exe "let retval= s:".a:varname
11102   if exists("g:netrw_pchk")
11103    if type(retval) == 3
11104     let retval = copy(retval)
11105     let i      = 0
11106     while i < len(retval)
11107      let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
11108      let i        = i + 1
11109     endwhile
11110    endif
11111"     call Dret("netrw#Expose ".string(retval))
11112    return string(retval)
11113   endif
11114  else
11115   let retval= "n/a"
11116  endif
11117
11118"  call Dret("netrw#Expose ".string(retval))
11119  return retval
11120endfun
11121
11122" ---------------------------------------------------------------------
11123" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
11124fun! netrw#Modify(varname,newvalue)
11125"  call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
11126  exe "let s:".a:varname."= ".string(a:newvalue)
11127"  call Dret("netrw#Modify")
11128endfun
11129
11130" ---------------------------------------------------------------------
11131"  netrw#RFC2396: converts %xx into characters {{{2
11132fun! netrw#RFC2396(fname)
11133"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
11134  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
11135"  call Dret("netrw#RFC2396 ".fname)
11136  return fname
11137endfun
11138
11139" ---------------------------------------------------------------------
11140" netrw#UserMaps: supports user-specified maps {{{2
11141"                 see :help function()
11142"
11143"                 g:Netrw_UserMaps is a List with members such as:
11144"                       [[keymap sequence, function reference],...]
11145"
11146"                 The referenced function may return a string,
11147"                 	refresh : refresh the display
11148"                 	-other- : this string will be executed
11149"                 or it may return a List of strings.
11150"
11151"                 Each keymap-sequence will be set up with a nnoremap
11152"                 to invoke netrw#UserMaps(islocal).
11153"                 Related functions:
11154"                   netrw#Expose(varname)          -- see s:varname variables
11155"                   netrw#Modify(varname,newvalue) -- modify value of s:varname variable
11156"                   netrw#Call(funcname,...)       -- call internal netrw function with optional arguments
11157fun! netrw#UserMaps(islocal)
11158"  call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
11159"  call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
11160
11161   " set up usermaplist
11162   if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
11163"    call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
11164    for umap in g:Netrw_UserMaps
11165"     call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
11166"     call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
11167     " if umap[0] is a string and umap[1] is a string holding a function name
11168     if type(umap[0]) == 1 && type(umap[1]) == 1
11169"      call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
11170      exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
11171      else
11172       call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
11173     endif
11174    endfor
11175   endif
11176"  call Dret("netrw#UserMaps")
11177endfun
11178
11179" ---------------------------------------------------------------------
11180" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
11181fun! netrw#WinPath(path)
11182"  call Dfunc("netrw#WinPath(path<".a:path.">)")
11183  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
11184   " remove cygdrive prefix, if present
11185   let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
11186   " remove trailing slash (Win95)
11187   let path = substitute(path, '\(\\\|/\)$', '', 'g')
11188   " remove escaped spaces
11189   let path = substitute(path, '\ ', ' ', 'g')
11190   " convert slashes to backslashes
11191   let path = substitute(path, '/', '\', 'g')
11192  else
11193   let path= a:path
11194  endif
11195"  call Dret("netrw#WinPath <".path.">")
11196  return path
11197endfun
11198
11199" ---------------------------------------------------------------------
11200" s:NetrwBadd: adds marked files to buffer list or vice versa {{{2
11201"              cb : bl2mf=0  add marked files to buffer list
11202"              cB : bl2mf=1  use bufferlist to mark files
11203"              (mnemonic: cb = copy (marked files) to buffer list)
11204fun! s:NetrwBadd(islocal,bl2mf)
11205"  "  call Dfunc("s:NetrwBadd(islocal=".a:islocal." mf2bl=".mf2bl.")")
11206  if a:bl2mf
11207   " cB: add buffer list to marked files
11208   redir => bufl
11209    ls
11210   redir END
11211   let bufl = map(split(bufl,"\n"),'substitute(v:val,''^.\{-}"\(.*\)".\{-}$'',''\1'','''')')
11212   for fname in bufl
11213    call s:NetrwMarkFile(a:islocal,fname)
11214   endfor
11215  else
11216   " cb: add marked files to buffer list
11217   for fname in s:netrwmarkfilelist_{bufnr("%")}
11218" "   call Decho("badd ".fname,'~'.expand("<slnum>"))
11219    exe "badd ".fnameescape(fname)
11220   endfor
11221   let curbufnr = bufnr("%")
11222   let curdir   = s:NetrwGetCurdir(a:islocal)
11223   call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
11224  endif
11225"  call Dret("s:NetrwBadd")
11226endfun
11227
11228" ---------------------------------------------------------------------
11229"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
11230fun! s:ComposePath(base,subdir)
11231"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
11232
11233  if has("amiga")
11234"   call Decho("amiga",'~'.expand("<slnum>"))
11235   let ec = a:base[s:Strlen(a:base)-1]
11236   if ec != '/' && ec != ':'
11237    let ret = a:base."/" . a:subdir
11238   else
11239    let ret = a:base.a:subdir
11240   endif
11241
11242   " COMBAK: test on windows with changing to root directory: :e C:/
11243  elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11244"   call Decho("windows",'~'.expand("<slnum>"))
11245   let ret= a:subdir
11246
11247  elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && (has("win32") || has("win95") || has("win64") || has("win16"))
11248"   call Decho("windows",'~'.expand("<slnum>"))
11249   if a:base =~ '[/\\]$'
11250    let ret= a:base.a:subdir
11251   else
11252    let ret= a:base.'/'.a:subdir
11253   endif
11254
11255  elseif a:base =~ '^\a\{3,}://'
11256"   call Decho("remote linux/macos",'~'.expand("<slnum>"))
11257   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
11258   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
11259   if a:subdir == '../'
11260    if curpath =~ '[^/]/[^/]\+/$'
11261     let curpath= substitute(curpath,'[^/]\+/$','','')
11262    else
11263     let curpath=""
11264    endif
11265    let ret= urlbase.curpath
11266   else
11267    let ret= urlbase.curpath.a:subdir
11268   endif
11269"   call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
11270"   call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
11271"   call Decho("ret<".ret.">",'~'.expand("<slnum>"))
11272
11273  else
11274"   call Decho("local linux/macos",'~'.expand("<slnum>"))
11275   let ret = substitute(a:base."/".a:subdir,"//","/","g")
11276   if a:base =~ '^//'
11277    " keeping initial '//' for the benefit of network share listing support
11278    let ret= '/'.ret
11279   endif
11280   let ret= simplify(ret)
11281  endif
11282
11283"  call Dret("s:ComposePath ".ret)
11284  return ret
11285endfun
11286
11287" ---------------------------------------------------------------------
11288" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
11289"   Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
11290fun! s:DeleteBookmark(fname)
11291"  call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
11292  call s:MergeBookmarks()
11293
11294  if exists("g:netrw_bookmarklist")
11295   let indx= index(g:netrw_bookmarklist,a:fname)
11296   if indx == -1
11297    let indx= 0
11298    while indx < len(g:netrw_bookmarklist)
11299     if g:netrw_bookmarklist[indx] =~ a:fname
11300      call remove(g:netrw_bookmarklist,indx)
11301      let indx= indx - 1
11302     endif
11303     let indx= indx + 1
11304    endwhile
11305   else
11306    " remove exact match
11307    call remove(g:netrw_bookmarklist,indx)
11308   endif
11309  endif
11310
11311"  call Dret("s:DeleteBookmark")
11312endfun
11313
11314" ---------------------------------------------------------------------
11315" s:FileReadable: o/s independent filereadable {{{2
11316fun! s:FileReadable(fname)
11317"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
11318
11319  if g:netrw_cygwin
11320   let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
11321  else
11322   let ret= filereadable(s:NetrwFile(a:fname))
11323  endif
11324
11325"  call Dret("s:FileReadable ".ret)
11326  return ret
11327endfun
11328
11329" ---------------------------------------------------------------------
11330"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
11331"                 Places correct suffix on end of temporary filename,
11332"                 using the suffix provided with fname
11333fun! s:GetTempfile(fname)
11334"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
11335
11336  if !exists("b:netrw_tmpfile")
11337   " get a brand new temporary filename
11338   let tmpfile= tempname()
11339"   call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
11340
11341   let tmpfile= substitute(tmpfile,'\','/','ge')
11342"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
11343
11344   " sanity check -- does the temporary file's directory exist?
11345   if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
11346"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11347    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
11348"    call Dret("s:GetTempfile getcwd<".getcwd().">")
11349    return ""
11350   endif
11351
11352   " let netrw#NetSource() know about the tmpfile
11353   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
11354"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
11355
11356   " o/s dependencies
11357   if g:netrw_cygwin != 0
11358    let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
11359   elseif has("win32") || has("win95") || has("win64") || has("win16")
11360    if !exists("+shellslash") || !&ssl
11361     let tmpfile = substitute(tmpfile,'/','\','g')
11362    endif
11363   else
11364    let tmpfile = tmpfile
11365   endif
11366   let b:netrw_tmpfile= tmpfile
11367"   call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
11368  else
11369   " re-use temporary filename
11370   let tmpfile= b:netrw_tmpfile
11371"   call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
11372  endif
11373
11374  " use fname's suffix for the temporary file
11375  if a:fname != ""
11376   if a:fname =~ '\.[^./]\+$'
11377"    call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11378    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11379     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11380    elseif a:fname =~ '.txz$'
11381     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11382    else
11383     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11384    endif
11385"    call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11386    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11387"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11388    let tmpfile .= suffix
11389"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11390    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
11391   endif
11392  endif
11393
11394"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11395"  call Dret("s:GetTempfile <".tmpfile.">")
11396  return tmpfile
11397endfun
11398
11399" ---------------------------------------------------------------------
11400" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
11401"               a correct command for use with a system() call
11402fun! s:MakeSshCmd(sshcmd)
11403"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
11404  if s:user == ""
11405   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
11406  else
11407   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
11408  endif
11409  if exists("g:netrw_port") && g:netrw_port != ""
11410   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
11411  elseif exists("s:port") && s:port != ""
11412   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
11413  else
11414   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
11415  endif
11416"  call Dret("s:MakeSshCmd <".sshcmd.">")
11417  return sshcmd
11418endfun
11419
11420" ---------------------------------------------------------------------
11421" s:MakeBookmark: enters a bookmark into Netrw's bookmark system   {{{2
11422fun! s:MakeBookmark(fname)
11423"  call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
11424
11425  if !exists("g:netrw_bookmarklist")
11426   let g:netrw_bookmarklist= []
11427  endif
11428
11429  if index(g:netrw_bookmarklist,a:fname) == -1
11430   " curdir not currently in g:netrw_bookmarklist, so include it
11431   if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11432    call add(g:netrw_bookmarklist,a:fname.'/')
11433   elseif a:fname !~ '/'
11434    call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11435   else
11436    call add(g:netrw_bookmarklist,a:fname)
11437   endif
11438   call sort(g:netrw_bookmarklist)
11439  endif
11440
11441"  call Dret("s:MakeBookmark")
11442endfun
11443
11444" ---------------------------------------------------------------------
11445" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11446fun! s:MergeBookmarks()
11447"  call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
11448  " get bookmarks from .netrwbook file
11449  let savefile= s:NetrwHome()."/.netrwbook"
11450  if filereadable(s:NetrwFile(savefile))
11451"   call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11452   NetrwKeepj call s:NetrwBookHistSave()
11453"   call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11454   NetrwKeepj call delete(savefile)
11455  endif
11456"  call Dret("s:MergeBookmarks")
11457endfun
11458
11459" ---------------------------------------------------------------------
11460" s:NetrwBMShow: {{{2
11461fun! s:NetrwBMShow()
11462"  call Dfunc("s:NetrwBMShow()")
11463  redir => bmshowraw
11464   menu
11465  redir END
11466  let bmshowlist = split(bmshowraw,'\n')
11467  if bmshowlist != []
11468   let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"')
11469   if bmshowfuncs != []
11470    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11471    if bmshowfunc =~# '^call.*BMShow()'
11472     exe "sil! NetrwKeepj ".bmshowfunc
11473    endif
11474   endif
11475  endif
11476"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
11477endfun
11478
11479" ---------------------------------------------------------------------
11480" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
11481fun! s:NetrwCursor()
11482  if !exists("w:netrw_liststyle")
11483   let w:netrw_liststyle= g:netrw_liststyle
11484  endif
11485"  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)
11486
11487  if &ft != "netrw"
11488   " if the current window isn't a netrw directory listing window, then use user cursorline/column
11489   " settings.  Affects when netrw is used to read/write a file using scp/ftp/etc.
11490"   call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
11491   let &l:cursorline   = s:netrw_usercul
11492   let &l:cursorcolumn = s:netrw_usercuc
11493
11494  elseif g:netrw_cursor == 4
11495   " all styles: cursorline, cursorcolumn
11496"   call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
11497   setl cursorline
11498   setl cursorcolumn
11499
11500  elseif g:netrw_cursor == 3
11501   " thin-long-tree: cursorline, user's cursorcolumn
11502   " wide          : cursorline, cursorcolumn
11503   if w:netrw_liststyle == s:WIDELIST
11504"    call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11505    setl cursorline
11506    setl cursorcolumn
11507   else
11508"    call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11509    setl cursorline
11510    let &l:cursorcolumn   = s:netrw_usercuc
11511   endif
11512
11513  elseif g:netrw_cursor == 2
11514   " thin-long-tree: cursorline, user's cursorcolumn
11515   " wide          : cursorline, user's cursorcolumn
11516"   call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11517   let &l:cursorcolumn = s:netrw_usercuc
11518   setl cursorline
11519
11520  elseif g:netrw_cursor == 1
11521   " thin-long-tree: user's cursorline, user's cursorcolumn
11522   " wide          : cursorline,        user's cursorcolumn
11523   let &l:cursorcolumn = s:netrw_usercuc
11524   if w:netrw_liststyle == s:WIDELIST
11525"    call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11526    setl cursorline
11527   else
11528"    call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11529    let &l:cursorline   = s:netrw_usercul
11530   endif
11531
11532  else
11533   " all styles: user's cursorline, user's cursorcolumn
11534"   call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11535   let &l:cursorline   = s:netrw_usercul
11536   let &l:cursorcolumn = s:netrw_usercuc
11537  endif
11538
11539"  call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
11540endfun
11541
11542" ---------------------------------------------------------------------
11543" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11544fun! s:RestoreCursorline()
11545"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
11546  if exists("s:netrw_usercul")
11547   let &l:cursorline   = s:netrw_usercul
11548  endif
11549  if exists("s:netrw_usercuc")
11550   let &l:cursorcolumn = s:netrw_usercuc
11551  endif
11552"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
11553endfun
11554
11555" ---------------------------------------------------------------------
11556" s:NetrwDelete: Deletes a file. {{{2
11557"           Uses Steve Hall's idea to insure that Windows paths stay
11558"           acceptable.  No effect on Unix paths.
11559"  Examples of use:  let result= s:NetrwDelete(path)
11560fun! s:NetrwDelete(path)
11561"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
11562
11563  let path = netrw#WinPath(a:path)
11564  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
11565   if exists("+shellslash")
11566    let sskeep= &shellslash
11567    setl noshellslash
11568    let result      = delete(path)
11569    let &shellslash = sskeep
11570   else
11571"    call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11572    let result= delete(path)
11573   endif
11574  else
11575"   call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11576   let result= delete(path)
11577  endif
11578  if result < 0
11579   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
11580  endif
11581
11582"  call Dret("s:NetrwDelete ".result)
11583  return result
11584endfun
11585
11586" ---------------------------------------------------------------------
11587" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
11588fun! s:NetrwEnew(...)
11589"  call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
11590"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
11591
11592  " grab a function-local-variable copy of buffer variables
11593"  call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
11594  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
11595  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
11596  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
11597  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
11598  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11599  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
11600  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
11601  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
11602  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11603  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11604  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
11605  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
11606  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
11607  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
11608  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
11609  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
11610
11611  NetrwKeepj call s:NetrwOptionRestore("w:")
11612"  call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>"))
11613  " when tree listing uses file TreeListing... a new buffer is made.
11614  " Want the old buffer to be unlisted.
11615  " COMBAK: this causes a problem, see P43
11616"  setl nobl
11617  let netrw_keepdiff= &l:diff
11618  noswapfile NetrwKeepj keepalt enew!
11619  let &l:diff= netrw_keepdiff
11620"  call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
11621  NetrwKeepj call s:NetrwOptionSave("w:")
11622
11623  " copy function-local-variables to buffer variable equivalents
11624"  call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
11625  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
11626  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
11627  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
11628  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
11629  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
11630  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
11631  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
11632  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
11633  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11634  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11635  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
11636  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
11637  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
11638  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
11639  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
11640  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
11641
11642  if a:0 > 0
11643   let b:netrw_curdir= a:1
11644   if b:netrw_curdir =~ '/$'
11645    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11646     setl nobl
11647     file NetrwTreeListing
11648     setl nobl bt=nowrite bh=hide
11649     nno <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
11650     nno <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
11651    else
11652     call s:NetrwBufRename(b:netrw_curdir)
11653    endif
11654   endif
11655  endif
11656
11657"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
11658endfun
11659
11660" ---------------------------------------------------------------------
11661" s:NetrwExe: executes a string using "!" {{{2
11662fun! s:NetrwExe(cmd)
11663"  call Dfunc("s:NetrwExe(a:cmd<".a:cmd.">)")
11664  if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin
11665"    call Decho("using win32:",expand("<slnum>"))
11666    let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
11667    set shell& shellcmdflag& shellxquote& shellxescape&
11668    set shellquote& shellpipe& shellredir& shellslash&
11669    exe a:cmd
11670    let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
11671  else
11672"   call Decho("exe ".a:cmd,'~'.expand("<slnum>"))
11673   exe a:cmd
11674  endif
11675"  call Dret("s:NetrwExe : v:shell_error=".v:shell_error)
11676endfun
11677
11678" ---------------------------------------------------------------------
11679" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
11680fun! s:NetrwInsureWinVars()
11681  if !exists("w:netrw_liststyle")
11682"   call Dfunc("s:NetrwInsureWinVars() win#".winnr())
11683   let curbuf = bufnr("%")
11684   let curwin = winnr()
11685   let iwin   = 1
11686   while iwin <= winnr("$")
11687    exe iwin."wincmd w"
11688    if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
11689     " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
11690     let winvars= w:
11691     break
11692    endif
11693    let iwin= iwin + 1
11694   endwhile
11695   exe "keepalt ".curwin."wincmd w"
11696   if exists("winvars")
11697"    call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
11698    for k in keys(winvars)
11699     let w:{k}= winvars[k]
11700    endfor
11701   endif
11702"   call Dret("s:NetrwInsureWinVars win#".winnr())
11703  endif
11704endfun
11705
11706" ---------------------------------------------------------------------
11707" s:NetrwLcd: handles changing the (local) directory {{{2
11708"   Returns: 0=success
11709"           -1=failed
11710fun! s:NetrwLcd(newdir)
11711"  call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
11712
11713  let err472= 0
11714  try
11715   exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
11716  catch /^Vim\%((\a\+)\)\=:E344/
11717     " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
11718     " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
11719     " 'root' (ie. '\').  The share name may start with either backslashes ('\\Foo') or
11720     " forward slashes ('//Foo'), depending on whether backslashes have been converted to
11721     " forward slashes by earlier code; so check for both.
11722     if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
11723       if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
11724         let dirname = '\'
11725	 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
11726       endif
11727     endif
11728  catch /^Vim\%((\a\+)\)\=:E472/
11729   let err472= 1
11730  endtry
11731
11732  if err472
11733   call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
11734   if exists("w:netrw_prvdir")
11735    let a:newdir= w:netrw_prvdir
11736   else
11737    call s:NetrwOptionRestore("w:")
11738"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
11739    exe "setl ".g:netrw_bufsettings
11740"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11741    let a:newdir= dirname
11742   endif
11743"   call Dret("s:NetrwBrowse -1 : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
11744   return -1
11745  endif
11746
11747"  call Dret("s:NetrwLcd 0")
11748  return 0
11749endfun
11750
11751" ------------------------------------------------------------------------
11752" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
11753" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
11754fun! s:NetrwSaveWordPosn()
11755"  call Dfunc("NetrwSaveWordPosn()")
11756  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
11757"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
11758endfun
11759
11760" ---------------------------------------------------------------------
11761" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
11762"                       1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
11763fun! s:NetrwHumanReadable(sz)
11764"  call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
11765
11766  if g:netrw_sizestyle == 'h'
11767   if a:sz >= 1000000000
11768    let sz = printf("%.1f",a:sz/1000000000.0)."g"
11769   elseif a:sz >= 10000000
11770    let sz = printf("%d",a:sz/1000000)."m"
11771   elseif a:sz >= 1000000
11772    let sz = printf("%.1f",a:sz/1000000.0)."m"
11773   elseif a:sz >= 10000
11774    let sz = printf("%d",a:sz/1000)."k"
11775   elseif a:sz >= 1000
11776    let sz = printf("%.1f",a:sz/1000.0)."k"
11777   else
11778    let sz= a:sz
11779   endif
11780
11781  elseif g:netrw_sizestyle == 'H'
11782   if a:sz >= 1073741824
11783    let sz = printf("%.1f",a:sz/1073741824.0)."G"
11784   elseif a:sz >= 10485760
11785    let sz = printf("%d",a:sz/1048576)."M"
11786   elseif a:sz >= 1048576
11787    let sz = printf("%.1f",a:sz/1048576.0)."M"
11788   elseif a:sz >= 10240
11789    let sz = printf("%d",a:sz/1024)."K"
11790   elseif a:sz >= 1024
11791    let sz = printf("%.1f",a:sz/1024.0)."K"
11792   else
11793    let sz= a:sz
11794   endif
11795
11796  else
11797   let sz= a:sz
11798  endif
11799
11800"  call Dret("s:NetrwHumanReadable ".sz)
11801  return sz
11802endfun
11803
11804" ---------------------------------------------------------------------
11805" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
11806"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
11807fun! s:NetrwRestoreWordPosn()
11808"  call Dfunc("NetrwRestoreWordPosn()")
11809  sil! call search(s:netrw_saveword,'w')
11810"  call Dret("NetrwRestoreWordPosn")
11811endfun
11812
11813" ---------------------------------------------------------------------
11814" s:RestoreBufVars: {{{2
11815fun! s:RestoreBufVars()
11816"  call Dfunc("s:RestoreBufVars()")
11817
11818  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
11819  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
11820  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
11821  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
11822  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
11823  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
11824
11825"  call Dret("s:RestoreBufVars")
11826endfun
11827
11828" ---------------------------------------------------------------------
11829" s:RemotePathAnalysis: {{{2
11830fun! s:RemotePathAnalysis(dirname)
11831"  call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
11832
11833  "                method   ://    user  @      machine      :port            /path
11834  let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
11835  let s:method  = substitute(a:dirname,dirpat,'\1','')
11836  let s:user    = substitute(a:dirname,dirpat,'\3','')
11837  let s:machine = substitute(a:dirname,dirpat,'\4','')
11838  let s:port    = substitute(a:dirname,dirpat,'\5','')
11839  let s:path    = substitute(a:dirname,dirpat,'\6','')
11840  let s:fname   = substitute(s:path,'^.*/\ze.','','')
11841  if s:machine =~ '@'
11842   let dirpat    = '^\(.*\)@\(.\{-}\)$'
11843   let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')
11844   let s:machine = substitute(s:machine,dirpat,'\2','')
11845  endif
11846
11847"  call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
11848"  call Decho("set up s:user   <".s:user   .">",'~'.expand("<slnum>"))
11849"  call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
11850"  call Decho("set up s:port   <".s:port.">",'~'.expand("<slnum>"))
11851"  call Decho("set up s:path   <".s:path   .">",'~'.expand("<slnum>"))
11852"  call Decho("set up s:fname  <".s:fname  .">",'~'.expand("<slnum>"))
11853
11854"  call Dret("s:RemotePathAnalysis")
11855endfun
11856
11857" ---------------------------------------------------------------------
11858" s:RemoteSystem: runs a command on a remote host using ssh {{{2
11859"                 Returns status
11860" Runs system() on
11861"    [cd REMOTEDIRPATH;] a:cmd
11862" Note that it doesn't do s:ShellEscape(a:cmd)!
11863fun! s:RemoteSystem(cmd)
11864"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
11865  if !executable(g:netrw_ssh_cmd)
11866   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
11867  elseif !exists("b:netrw_curdir")
11868   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
11869  else
11870   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
11871   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
11872   if remotedir != ""
11873    let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
11874   else
11875    let cmd= cmd.' '
11876   endif
11877   let cmd= cmd.a:cmd
11878"   call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
11879   let ret= system(cmd)
11880  endif
11881"  call Dret("s:RemoteSystem ".ret)
11882  return ret
11883endfun
11884
11885" ---------------------------------------------------------------------
11886" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
11887fun! s:RestoreWinVars()
11888"  call Dfunc("s:RestoreWinVars()")
11889  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
11890  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
11891  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
11892  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
11893  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
11894  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
11895  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
11896  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
11897  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
11898  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
11899  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
11900  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
11901  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
11902  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
11903  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
11904  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
11905  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
11906  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
11907"  call Dret("s:RestoreWinVars")
11908endfun
11909
11910" ---------------------------------------------------------------------
11911" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
11912"
11913"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
11914"             is true) and a command, :Rexplore, which call this function.
11915"
11916"             s:netrw_posn is set up by s:NetrwBrowseChgDir()
11917"
11918"             s:rexposn_BUFNR used to save/restore cursor position
11919fun! s:NetrwRexplore(islocal,dirname)
11920  if exists("s:netrwdrag")
11921   return
11922  endif
11923"  call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
11924"  call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
11925"  call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
11926
11927  if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
11928   " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
11929"   call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
11930   exe "NetrwKeepj e ".w:netrw_rexfile
11931   unlet w:netrw_rexfile
11932"   call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%").">  (ft=".&ft.")")
11933   return
11934"  else " Decho
11935"   call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
11936"   call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
11937  endif
11938
11939  " ---------------------------
11940  " :Rex issued while in a file
11941  " ---------------------------
11942
11943  " record current file so :Rex can return to it from netrw
11944  let w:netrw_rexfile= expand("%")
11945"  call Decho("set w:netrw_rexfile<".w:netrw_rexfile.">  (win#".winnr().")",'~'.expand("<slnum>"))
11946
11947  if !exists("w:netrw_rexlocal")
11948"   call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
11949   return
11950  endif
11951"  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>"))
11952  if w:netrw_rexlocal
11953   NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
11954  else
11955   NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
11956  endif
11957  if exists("s:initbeval")
11958   setl beval
11959  endif
11960  if exists("s:rexposn_".bufnr("%"))
11961"   call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
11962   " restore position in directory listing
11963"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
11964   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
11965   if exists("s:rexposn_".bufnr('%'))
11966    unlet s:rexposn_{bufnr('%')}
11967   endif
11968  else
11969"   call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
11970  endif
11971
11972  if has("syntax") && exists("g:syntax_on") && g:syntax_on
11973   if exists("s:explore_match")
11974    exe "2match netrwMarkFile /".s:explore_match."/"
11975   endif
11976  endif
11977
11978"  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>"))
11979"  call Dret("s:NetrwRexplore : ft=".&ft)
11980endfun
11981
11982" ---------------------------------------------------------------------
11983" s:SaveBufVars: save selected b: variables to s: variables {{{2
11984"                use s:RestoreBufVars() to restore b: variables from s: variables
11985fun! s:SaveBufVars()
11986"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
11987
11988  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
11989  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
11990  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
11991  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
11992  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
11993  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
11994
11995"  call Dret("s:SaveBufVars")
11996endfun
11997
11998" ---------------------------------------------------------------------
11999" s:SavePosn: saves position associated with current buffer into a dictionary {{{2
12000fun! s:SavePosn(posndict)
12001"  call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12002
12003  if !exists("a:posndict[bufnr('%')]")
12004   let a:posndict[bufnr("%")]= []
12005  endif
12006"  call Decho("before push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12007  call add(a:posndict[bufnr("%")],winsaveview())
12008"  call Decho("after  push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12009
12010"  call Dret("s:SavePosn posndict")
12011  return a:posndict
12012endfun
12013
12014" ---------------------------------------------------------------------
12015" s:RestorePosn: restores position associated with current buffer using dictionary {{{2
12016fun! s:RestorePosn(posndict)
12017"  call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
12018  if exists("a:posndict")
12019   if has_key(a:posndict,bufnr("%"))
12020"    call Decho("before pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12021    let posnlen= len(a:posndict[bufnr("%")])
12022    if posnlen > 0
12023     let posnlen= posnlen - 1
12024"     call Decho("restoring posn posndict[".bufnr("%")."][".posnlen."]=".string(a:posndict[bufnr("%")][posnlen]),'~'.expand("<slnum>"))
12025     call winrestview(a:posndict[bufnr("%")][posnlen])
12026     call remove(a:posndict[bufnr("%")],posnlen)
12027"     call Decho("after  pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
12028    endif
12029   endif
12030  endif
12031"  call Dret("s:RestorePosn")
12032endfun
12033
12034" ---------------------------------------------------------------------
12035" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
12036fun! s:SaveWinVars()
12037"  call Dfunc("s:SaveWinVars() win#".winnr())
12038  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
12039  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
12040  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
12041  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
12042  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
12043  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
12044  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
12045  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
12046  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
12047  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
12048  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
12049  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
12050  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
12051  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
12052  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
12053  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
12054  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
12055  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
12056"  call Dret("s:SaveWinVars")
12057endfun
12058
12059" ---------------------------------------------------------------------
12060" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
12061"   To allow separate windows to have their own activities, such as
12062"   Explore **/pattern, several variables have been made window-oriented.
12063"   However, when the user splits a browser window (ex: ctrl-w s), these
12064"   variables are not inherited by the new window.  SetBufWinVars() and
12065"   UseBufWinVars() get around that.
12066fun! s:SetBufWinVars()
12067"  call Dfunc("s:SetBufWinVars() win#".winnr())
12068  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
12069  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
12070  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
12071  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
12072  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
12073  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
12074  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
12075  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
12076  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
12077  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
12078"  call Dret("s:SetBufWinVars")
12079endfun
12080
12081" ---------------------------------------------------------------------
12082" s:SetRexDir: set directory for :Rexplore {{{2
12083fun! s:SetRexDir(islocal,dirname)
12084"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
12085  let w:netrw_rexdir         = a:dirname
12086  let w:netrw_rexlocal       = a:islocal
12087  let s:rexposn_{bufnr("%")} = winsaveview()
12088"  call Decho("setting w:netrw_rexdir  =".w:netrw_rexdir,'~'.expand("<slnum>"))
12089"  call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>"))
12090"  call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
12091"  call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>"))
12092"  call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
12093endfun
12094
12095" ---------------------------------------------------------------------
12096" s:ShowLink: used to modify thin and tree listings to show links {{{2
12097fun! s:ShowLink()
12098" "  call Dfunc("s:ShowLink()")
12099" "  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
12100" "  call Decho(printf("line#%4d: %s",line("."),getline(".")),'~'.expand("<slnum>"))
12101  if exists("b:netrw_curdir")
12102   norm! $?\a
12103   let fname   = b:netrw_curdir.'/'.s:NetrwGetWord()
12104   let resname = resolve(fname)
12105" "   call Decho("fname         <".fname.">",'~'.expand("<slnum>"))
12106" "   call Decho("resname       <".resname.">",'~'.expand("<slnum>"))
12107" "   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
12108   if resname =~ '^\M'.b:netrw_curdir.'/'
12109    let dirlen  = strlen(b:netrw_curdir)
12110    let resname = strpart(resname,dirlen+1)
12111" "    call Decho("resname<".resname.">  (b:netrw_curdir elided)",'~'.expand("<slnum>"))
12112   endif
12113   let modline = getline(".")."\t --> ".resname
12114" "   call Decho("fname  <".fname.">",'~'.expand("<slnum>"))
12115" "   call Decho("modline<".modline.">",'~'.expand("<slnum>"))
12116   setl noro ma
12117   call setline(".",modline)
12118   setl ro noma nomod
12119  endif
12120" "  call Dret("s:ShowLink".((exists("fname")? ' : '.fname : 'n/a')))
12121endfun
12122
12123" ---------------------------------------------------------------------
12124" s:ShowStyle: {{{2
12125fun! s:ShowStyle()
12126  if !exists("w:netrw_liststyle")
12127   let liststyle= g:netrw_liststyle
12128  else
12129   let liststyle= w:netrw_liststyle
12130  endif
12131  if     liststyle == s:THINLIST
12132   return s:THINLIST.":thin"
12133  elseif liststyle == s:LONGLIST
12134   return s:LONGLIST.":long"
12135  elseif liststyle == s:WIDELIST
12136   return s:WIDELIST.":wide"
12137  elseif liststyle == s:TREELIST
12138   return s:TREELIST.":tree"
12139  else
12140   return 'n/a'
12141  endif
12142endfun
12143
12144" ---------------------------------------------------------------------
12145" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
12146"           Solution from Nicolai Weibull, vim docs (:help strlen()),
12147"           Tony Mechelynck, and my own invention.
12148fun! s:Strlen(x)
12149"  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
12150
12151  if v:version >= 703 && exists("*strdisplaywidth")
12152   let ret= strdisplaywidth(a:x)
12153
12154  elseif type(g:Align_xstrlen) == 1
12155   " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
12156   exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
12157
12158  elseif g:Align_xstrlen == 1
12159   " number of codepoints (Latin a + combining circumflex is two codepoints)
12160   " (comment from TM, solution from NW)
12161   let ret= strlen(substitute(a:x,'.','c','g'))
12162
12163  elseif g:Align_xstrlen == 2
12164   " number of spacing codepoints (Latin a + combining circumflex is one spacing
12165   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
12166   " (comment from TM, solution from TM)
12167   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
12168
12169  elseif g:Align_xstrlen == 3
12170   " virtual length (counting, for instance, tabs as anything between 1 and
12171   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
12172   " preceded by lam, one otherwise, etc.)
12173   " (comment from TM, solution from me)
12174   let modkeep= &l:mod
12175   exe "norm! o\<esc>"
12176   call setline(line("."),a:x)
12177   let ret= virtcol("$") - 1
12178   d
12179   NetrwKeepj norm! k
12180   let &l:mod= modkeep
12181
12182  else
12183   " at least give a decent default
12184    let ret= strlen(a:x)
12185  endif
12186"  "" call Dret("s:Strlen ".ret)
12187  return ret
12188endfun
12189
12190" ---------------------------------------------------------------------
12191" s:ShellEscape: shellescape(), or special windows handling {{{2
12192fun! s:ShellEscape(s, ...)
12193  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
12194    return printf('"%s"', substitute(a:s, '"', '""', 'g'))
12195  endif
12196  let f = a:0 > 0 ? a:1 : 0
12197  return shellescape(a:s, f)
12198endfun
12199
12200" ---------------------------------------------------------------------
12201" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
12202fun! s:TreeListMove(dir)
12203"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
12204  let curline      = getline('.')
12205  let prvline      = (line(".") > 1)?         getline(line(".")-1) : ''
12206  let nxtline      = (line(".") < line("$"))? getline(line(".")+1) : ''
12207  let curindent    = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
12208  let indentm1     = substitute(curindent,'^'.s:treedepthstring,'','')
12209  let treedepthchr = substitute(s:treedepthstring,' ','','g')
12210  let stopline     = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
12211"  call Decho("prvline  <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
12212"  call Decho("curline  <".curline."> #".line(".")    , '~'.expand("<slnum>"))
12213"  call Decho("nxtline  <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
12214"  call Decho("curindent<".curindent.">"              , '~'.expand("<slnum>"))
12215"  call Decho("indentm1 <".indentm1.">"               , '~'.expand("<slnum>"))
12216  "  COMBAK : need to handle when on a directory
12217  "  COMBAK : need to handle ]] and ][.  In general, needs work!!!
12218  if curline !~ '/$'
12219   if     a:dir == '[[' && prvline != ''
12220    NetrwKeepj norm! 0
12221    let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
12222"    call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
12223   elseif a:dir == '[]' && nxtline != ''
12224    NetrwKeepj norm! 0
12225"    call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>"))
12226    let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
12227    if nl != 0
12228     NetrwKeepj norm! k
12229    else
12230     NetrwKeepj norm! G
12231    endif
12232"    call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
12233   endif
12234  endif
12235
12236"  call Dret("s:TreeListMove")
12237endfun
12238
12239" ---------------------------------------------------------------------
12240" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
12241"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
12242"                      can't be called except via emenu.  But due to locale, that menu line may not be called
12243"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
12244fun! s:UpdateBuffersMenu()
12245"  call Dfunc("s:UpdateBuffersMenu()")
12246  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
12247   try
12248    sil emenu Buffers.Refresh\ menu
12249   catch /^Vim\%((\a\+)\)\=:E/
12250    let v:errmsg= ""
12251    sil NetrwKeepj call s:NetrwBMShow()
12252   endtry
12253  endif
12254"  call Dret("s:UpdateBuffersMenu")
12255endfun
12256
12257" ---------------------------------------------------------------------
12258" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
12259"              Matching function to s:SetBufWinVars()
12260fun! s:UseBufWinVars()
12261"  call Dfunc("s:UseBufWinVars()")
12262  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
12263  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
12264  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
12265  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
12266  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
12267  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
12268  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
12269  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
12270  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
12271  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
12272"  call Dret("s:UseBufWinVars")
12273endfun
12274
12275" ---------------------------------------------------------------------
12276" s:UserMaps: supports user-defined UserMaps {{{2
12277"               * calls a user-supplied funcref(islocal,curdir)
12278"               * interprets result
12279"             See netrw#UserMaps()
12280fun! s:UserMaps(islocal,funcname)
12281"  call Dfunc("s:UserMaps(islocal=".a:islocal.",funcname<".a:funcname.">)")
12282
12283  if !exists("b:netrw_curdir")
12284   let b:netrw_curdir= getcwd()
12285  endif
12286  let Funcref = function(a:funcname)
12287  let result  = Funcref(a:islocal)
12288
12289  if     type(result) == 1
12290   " if result from user's funcref is a string...
12291"   call Decho("result string from user funcref<".result.">",'~'.expand("<slnum>"))
12292   if result == "refresh"
12293"    call Decho("refreshing display",'~'.expand("<slnum>"))
12294    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12295   elseif result != ""
12296"    call Decho("executing result<".result.">",'~'.expand("<slnum>"))
12297    exe result
12298   endif
12299
12300  elseif type(result) == 3
12301   " if result from user's funcref is a List...
12302"   call Decho("result List from user funcref<".string(result).">",'~'.expand("<slnum>"))
12303   for action in result
12304    if action == "refresh"
12305"     call Decho("refreshing display",'~'.expand("<slnum>"))
12306     call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12307    elseif action != ""
12308"     call Decho("executing action<".action.">",'~'.expand("<slnum>"))
12309     exe action
12310    endif
12311   endfor
12312  endif
12313
12314"  call Dret("s:UserMaps")
12315endfun
12316
12317" ==========================
12318" Settings Restoration: {{{1
12319" ==========================
12320let &cpo= s:keepcpo
12321unlet s:keepcpo
12322
12323" ===============
12324" Modelines: {{{1
12325" ===============
12326" vim:ts=8 fdm=marker
12327