xref: /vim-8.2.3635/runtime/autoload/netrw.vim (revision ba3ff539)
1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		Apr 20, 2016
4" Version:	156
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" netrw requires vim having patch 7.4.213; netrw will benefit from vim's having patch#656, too
26if v:version < 704 || (v:version == 704 && !has("patch213"))
27 if !exists("s:needpatch213")
28  unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch 213"
29 endif
30 let s:needpatch213= 1
31 finish
32endif
33let g:loaded_netrw = "v156"
34if !exists("s:NOTE")
35 let s:NOTE    = 0
36 let s:WARNING = 1
37 let s:ERROR   = 2
38endif
39
40let s:keepcpo= &cpo
41setl cpo&vim
42"let g:dechofuncname= 1
43"DechoRemOn
44"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw,'~'.expand("<slnum>"))
45
46" ======================
47"  Netrw Variables: {{{1
48" ======================
49
50" ---------------------------------------------------------------------
51" netrw#ErrorMsg: {{{2
52"   0=note     = s:NOTE
53"   1=warning  = s:WARNING
54"   2=error    = s:ERROR
55"   Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number)
56"          netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number)
57"          (this function can optionally take a list of messages)
58"  Jan 19, 2016 : max errnum currently is 103
59fun! netrw#ErrorMsg(level,msg,errnum)
60"  call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
61
62  if a:level < g:netrw_errorlvl
63"   call Dret("netrw#ErrorMsg : suppressing level=".a:level." since g:netrw_errorlvl=".g:netrw_errorlvl)
64   return
65  endif
66
67  if a:level == 1
68   let level= "**warning** (netrw) "
69  elseif a:level == 2
70   let level= "**error** (netrw) "
71  else
72   let level= "**note** (netrw) "
73  endif
74"  call Decho("level=".level,'~'.expand("<slnum>"))
75
76  if g:netrw_use_errorwindow
77   " (default) netrw creates a one-line window to show error/warning
78   " messages (reliably displayed)
79
80   " record current window number
81   let s:winBeforeErr= winnr()
82"   call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>"))
83
84   " getting messages out reliably is just plain difficult!
85   " This attempt splits the current window, creating a one line window.
86   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
87"    call Decho("write to NetrwMessage buffer",'~'.expand("<slnum>"))
88    exe bufwinnr("NetrwMessage")."wincmd w"
89"    call Decho("setl ma noro",'~'.expand("<slnum>"))
90    setl ma noro
91    if type(a:msg) == 3
92     for msg in a:msg
93      NetrwKeepj call setline(line("$")+1,level.msg)
94     endfor
95    else
96     NetrwKeepj call setline(line("$")+1,level.a:msg)
97    endif
98    NetrwKeepj $
99   else
100"    call Decho("create a NetrwMessage buffer window",'~'.expand("<slnum>"))
101    bo 1split
102    sil! call s:NetrwEnew()
103    sil! NetrwKeepj call s:NetrwSafeOptions()
104    setl bt=nofile
105    NetrwKeepj file NetrwMessage
106"    call Decho("setl ma noro",'~'.expand("<slnum>"))
107    setl ma noro
108    if type(a:msg) == 3
109     for msg in a:msg
110      NetrwKeepj call setline(line("$")+1,level.msg)
111     endfor
112    else
113     NetrwKeepj call setline(line("$"),level.a:msg)
114    endif
115    NetrwKeepj $
116   endif
117"   call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr(),'~'.expand("<slnum>"))
118   if &fo !~ '[ta]'
119    syn clear
120    syn match netrwMesgNote	"^\*\*note\*\*"
121    syn match netrwMesgWarning	"^\*\*warning\*\*"
122    syn match netrwMesgError	"^\*\*error\*\*"
123    hi link netrwMesgWarning WarningMsg
124    hi link netrwMesgError   Error
125   endif
126"   call Decho("setl noma ro bh=wipe",'~'.expand("<slnum>"))
127   setl ro nomod noma bh=wipe
128
129  else
130   " (optional) netrw will show messages using echomsg.  Even if the
131   " message doesn't appear, at least it'll be recallable via :messages
132"   redraw!
133   if a:level == s:WARNING
134    echohl WarningMsg
135   elseif a:level == s:ERROR
136    echohl Error
137   endif
138
139   if type(a:msg) == 3
140     for msg in a:msg
141      unsilent echomsg level.msg
142     endfor
143   else
144    unsilent echomsg level.a:msg
145   endif
146
147"   call Decho("echomsg ***netrw*** ".a:msg,'~'.expand("<slnum>"))
148   echohl None
149  endif
150
151"  call Dret("netrw#ErrorMsg")
152endfun
153
154" ---------------------------------------------------------------------
155" s:NetrwInit: initializes variables if they haven't been defined {{{2
156"            Loosely,  varname = value.
157fun s:NetrwInit(varname,value)
158" call Decho("varname<".a:varname."> value=".a:value,'~'.expand("<slnum>"))
159  if !exists(a:varname)
160   if type(a:value) == 0
161    exe "let ".a:varname."=".a:value
162   elseif type(a:value) == 1 && a:value =~ '^[{[]'
163    exe "let ".a:varname."=".a:value
164   elseif type(a:value) == 1
165    exe "let ".a:varname."="."'".a:value."'"
166   else
167    exe "let ".a:varname."=".a:value
168   endif
169  endif
170endfun
171
172" ---------------------------------------------------------------------
173"  Netrw Constants: {{{2
174call s:NetrwInit("g:netrw_dirhist_cnt",0)
175if !exists("s:LONGLIST")
176 call s:NetrwInit("s:THINLIST",0)
177 call s:NetrwInit("s:LONGLIST",1)
178 call s:NetrwInit("s:WIDELIST",2)
179 call s:NetrwInit("s:TREELIST",3)
180 call s:NetrwInit("s:MAXLIST" ,4)
181endif
182
183" ---------------------------------------------------------------------
184" Default values for netrw's global protocol variables {{{2
185call s:NetrwInit("g:netrw_use_errorwindow",1)
186
187if !exists("g:netrw_dav_cmd")
188 if executable("cadaver")
189  let g:netrw_dav_cmd	= "cadaver"
190 elseif executable("curl")
191  let g:netrw_dav_cmd	= "curl"
192 else
193  let g:netrw_dav_cmd   = ""
194 endif
195endif
196if !exists("g:netrw_fetch_cmd")
197 if executable("fetch")
198  let g:netrw_fetch_cmd	= "fetch -o"
199 else
200  let g:netrw_fetch_cmd	= ""
201 endif
202endif
203if !exists("g:netrw_file_cmd")
204 if executable("elinks")
205  call s:NetrwInit("g:netrw_file_cmd","elinks")
206 elseif executable("links")
207  call s:NetrwInit("g:netrw_file_cmd","links")
208 endif
209endif
210if !exists("g:netrw_ftp_cmd")
211  let g:netrw_ftp_cmd	= "ftp"
212endif
213let s:netrw_ftp_cmd= g:netrw_ftp_cmd
214if !exists("g:netrw_ftp_options")
215 let g:netrw_ftp_options= "-i -n"
216endif
217if !exists("g:netrw_http_cmd")
218 if executable("elinks")
219  let g:netrw_http_cmd = "elinks"
220  call s:NetrwInit("g:netrw_http_xcmd","-source >")
221 elseif executable("links")
222  let g:netrw_http_cmd = "links"
223  call s:NetrwInit("g:netrw_http_xcmd","-source >")
224 elseif executable("curl")
225  let g:netrw_http_cmd	= "curl"
226  call s:NetrwInit("g:netrw_http_xcmd","-o")
227 elseif executable("wget")
228  let g:netrw_http_cmd	= "wget"
229  call s:NetrwInit("g:netrw_http_xcmd","-q -O")
230 elseif executable("fetch")
231  let g:netrw_http_cmd	= "fetch"
232  call s:NetrwInit("g:netrw_http_xcmd","-o")
233 else
234  let g:netrw_http_cmd	= ""
235 endif
236endif
237call s:NetrwInit("g:netrw_http_put_cmd","curl -T")
238call s:NetrwInit("g:netrw_keepj","keepj")
239call s:NetrwInit("g:netrw_rcp_cmd"  , "rcp")
240call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
241if !exists("g:netrw_scp_cmd")
242 if executable("scp")
243  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
244 elseif executable("pscp")
245  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable('c:\private.ppk')
246   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -i c:\private.ppk')
247  else
248   call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
249  endif
250 else
251  call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
252 endif
253endif
254
255call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
256call s:NetrwInit("g:netrw_ssh_cmd"  , "ssh")
257
258if (has("win32") || has("win95") || has("win64") || has("win16"))
259  \ && exists("g:netrw_use_nt_rcp")
260  \ && g:netrw_use_nt_rcp
261  \ && executable( $SystemRoot .'/system32/rcp.exe')
262 let s:netrw_has_nt_rcp = 1
263 let s:netrw_rcpmode    = '-b'
264else
265 let s:netrw_has_nt_rcp = 0
266 let s:netrw_rcpmode    = ''
267endif
268
269" ---------------------------------------------------------------------
270" Default values for netrw's global variables {{{2
271" Cygwin Detection ------- {{{3
272if !exists("g:netrw_cygwin")
273 if has("win32") || has("win95") || has("win64") || has("win16")
274  if  has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
275   let g:netrw_cygwin= 1
276  else
277   let g:netrw_cygwin= 0
278  endif
279 else
280  let g:netrw_cygwin= 0
281 endif
282endif
283" Default values - a-c ---------- {{{3
284call s:NetrwInit("g:netrw_alto"        , &sb)
285call s:NetrwInit("g:netrw_altv"        , &spr)
286call s:NetrwInit("g:netrw_banner"      , 1)
287call s:NetrwInit("g:netrw_browse_split", 0)
288call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro nornu")
289call s:NetrwInit("g:netrw_chgwin"      , -1)
290call s:NetrwInit("g:netrw_compress"    , "gzip")
291call s:NetrwInit("g:netrw_ctags"       , "ctags")
292if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
293 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
294 let g:netrw_cursor= g:netrw_cursorline
295endif
296call s:NetrwInit("g:netrw_cursor"      , 2)
297let s:netrw_usercul = &cursorline
298let s:netrw_usercuc = &cursorcolumn
299call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
300" Default values - d-g ---------- {{{3
301call s:NetrwInit("s:didstarstar",0)
302call s:NetrwInit("g:netrw_dirhist_cnt"      , 0)
303call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }')
304call s:NetrwInit("g:netrw_dirhistmax"       , 10)
305call s:NetrwInit("g:netrw_errorlvl"  , s:NOTE)
306call s:NetrwInit("g:netrw_fastbrowse"       , 1)
307call s:NetrwInit("g:netrw_ftp_browse_reject", '^total\s\+\d\+$\|^Trying\s\+\d\+.*$\|^KERBEROS_V\d rejected\|^Security extensions not\|No such file\|: connect to address [0-9a-fA-F:]*: No route to host$')
308if !exists("g:netrw_ftp_list_cmd")
309 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
310  let g:netrw_ftp_list_cmd     = "ls -lF"
311  let g:netrw_ftp_timelist_cmd = "ls -tlF"
312  let g:netrw_ftp_sizelist_cmd = "ls -slF"
313 else
314  let g:netrw_ftp_list_cmd     = "dir"
315  let g:netrw_ftp_timelist_cmd = "dir"
316  let g:netrw_ftp_sizelist_cmd = "dir"
317 endif
318endif
319call s:NetrwInit("g:netrw_ftpmode",'binary')
320" Default values - h-lh ---------- {{{3
321call s:NetrwInit("g:netrw_hide",1)
322if !exists("g:netrw_ignorenetrc")
323 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
324  let g:netrw_ignorenetrc= 1
325 else
326  let g:netrw_ignorenetrc= 0
327 endif
328endif
329call s:NetrwInit("g:netrw_keepdir",1)
330if !exists("g:netrw_list_cmd")
331 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
332  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
333   " provide a pscp-based listing command
334   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
335  endif
336  if exists("g:netrw_list_cmd_options")
337   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
338  else
339   let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
340  endif
341 elseif executable(g:netrw_ssh_cmd)
342  " provide a scp-based default listing command
343  if exists("g:netrw_list_cmd_options")
344   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
345  else
346   let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
347  endif
348 else
349"  call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
350  let g:netrw_list_cmd= ""
351 endif
352endif
353call s:NetrwInit("g:netrw_list_hide","")
354" Default values - lh-lz ---------- {{{3
355if exists("g:netrw_local_copycmd")
356 let g:netrw_localcopycmd= g:netrw_local_copycmd
357 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_copycmd is deprecated in favor of g:netrw_localcopycmd",84)
358endif
359if !exists("g:netrw_localcmdshell")
360 let g:netrw_localcmdshell= ""
361endif
362if !exists("g:netrw_localcopycmd")
363 if has("win32") || has("win95") || has("win64") || has("win16")
364  if g:netrw_cygwin
365   let g:netrw_localcopycmd= "cp"
366  else
367   let g:netrw_localcopycmd= expand("$COMSPEC")." /c copy"
368  endif
369 elseif has("unix") || has("macunix")
370  let g:netrw_localcopycmd= "cp"
371 else
372  let g:netrw_localcopycmd= ""
373 endif
374endif
375if !exists("g:netrw_localcopydircmd")
376 if has("win32") || has("win95") || has("win64") || has("win16")
377  if g:netrw_cygwin
378   let g:netrw_localcopydircmd= "cp -R"
379  else
380   let g:netrw_localcopycmd= expand("$COMSPEC")." /c xcopy /e /c /h /i /k"
381  endif
382 elseif has("unix") || has("macunix")
383  let g:netrw_localcopydircmd= "cp -R"
384 else
385  let g:netrw_localcopycmd= ""
386 endif
387endif
388if exists("g:netrw_local_mkdir")
389 let g:netrw_localmkdir= g:netrw_local_mkdir
390 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
391endif
392if has("win32") || has("win95") || has("win64") || has("win16")
393  if g:netrw_cygwin
394   call s:NetrwInit("g:netrw_localmkdir","mkdir")
395  else
396   let g:netrw_localmkdir= expand("$COMSPEC")." /c mkdir"
397  endif
398else
399 call s:NetrwInit("g:netrw_localmkdir","mkdir")
400endif
401call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
402if exists("g:netrw_local_movecmd")
403 let g:netrw_localmovecmd= g:netrw_local_movecmd
404 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
405endif
406if !exists("g:netrw_localmovecmd")
407 if has("win32") || has("win95") || has("win64") || has("win16")
408  if g:netrw_cygwin
409   let g:netrw_localmovecmd= "mv"
410  else
411   let g:netrw_localmovecmd= expand("$COMSPEC")." /c move"
412  endif
413 elseif has("unix") || has("macunix")
414  let g:netrw_localmovecmd= "mv"
415 else
416  let g:netrw_localmovecmd= ""
417 endif
418endif
419if v:version < 704 || !has("patch1109")
420 if exists("g:netrw_local_rmdir")
421  let g:netrw_localrmdir= g:netrw_local_rmdir
422  call netrw#ErrorMsg(s:NOTE,"g:netrw_local_rmdir is deprecated in favor of g:netrw_localrmdir",86)
423 endif
424 if has("win32") || has("win95") || has("win64") || has("win16")
425   if g:netrw_cygwin
426    call s:NetrwInit("g:netrw_localrmdir","rmdir")
427   else
428    let g:netrw_localrmdir= expand("$COMSPEC")." /c rmdir"
429   endif
430 else
431  call s:NetrwInit("g:netrw_localrmdir","rmdir")
432 endif
433endif
434call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
435" sanity checks
436if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
437 let g:netrw_liststyle= s:THINLIST
438endif
439if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
440 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
441endif
442" Default values - m-r ---------- {{{3
443call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
444call s:NetrwInit("g:netrw_maxfilenamelen", 32)
445call s:NetrwInit("g:netrw_menu"          , 1)
446call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
447call s:NetrwInit("g:netrw_mousemaps"     , (exists("+mouse") && &mouse =~# '[anh]'))
448call s:NetrwInit("g:netrw_retmap"        , 0)
449if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
450 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
451elseif has("win32") || has("win95") || has("win64") || has("win16")
452 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
453else
454 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
455endif
456call s:NetrwInit("g:netrw_preview"       , 0)
457call s:NetrwInit("g:netrw_scpport"       , "-P")
458call s:NetrwInit("g:netrw_servername"    , "NETRWSERVER")
459call s:NetrwInit("g:netrw_sshport"       , "-p")
460call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
461call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
462call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
463call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
464" Default values - q-s ---------- {{{3
465call s:NetrwInit("g:netrw_quickhelp",0)
466let s:QuickHelp= ["-:go up dir  D:delete  R:rename  s:sort-by  x:special",
467   \              "(create new)  %:file  d:directory",
468   \              "(windows split&open) o:horz  v:vert  p:preview",
469   \              "i:style  qf:file info  O:obtain  r:reverse",
470   \              "(marks)  mf:mark file  mt:set target  mm:move  mc:copy",
471   \              "(bookmarks)  mb:make  mB:delete  qb:list  gb:go to",
472   \              "(history)  qb:list  u:go up  U:go down",
473   \              "(targets)  mt:target Tb:use bookmark  Th:use history"]
474" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
475call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
476if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
477 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
478else
479 call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
480endif
481call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
482call s:NetrwInit("g:netrw_sort_options"  , "")
483call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
484if !exists("g:netrw_sort_sequence")
485 if has("unix")
486  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
487 else
488  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
489 endif
490endif
491call s:NetrwInit("g:netrw_special_syntax"   , 0)
492call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
493call s:NetrwInit("g:netrw_suppress_gx_mesg",  1)
494call s:NetrwInit("g:netrw_use_noswf"        , 1)
495call s:NetrwInit("g:netrw_sizestyle"        ,"b")
496" Default values - t-w ---------- {{{3
497call s:NetrwInit("g:netrw_timefmt","%c")
498if !exists("g:netrw_xstrlen")
499 if exists("g:Align_xstrlen")
500  let g:netrw_xstrlen= g:Align_xstrlen
501 elseif exists("g:drawit_xstrlen")
502  let g:netrw_xstrlen= g:drawit_xstrlen
503 elseif &enc == "latin1" || !has("multi_byte")
504  let g:netrw_xstrlen= 0
505 else
506  let g:netrw_xstrlen= 1
507 endif
508endif
509call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
510call s:NetrwInit("g:netrw_win95ftp",1)
511call s:NetrwInit("g:netrw_winsize",50)
512call s:NetrwInit("g:netrw_wiw",1)
513if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
514" ---------------------------------------------------------------------
515" Default values for netrw's script variables: {{{2
516call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
517if has("win32") || has("win95") || has("win64") || has("win16")
518 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
519else
520 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
521endif
522call s:NetrwInit("g:netrw_menu_escape",'.&? \')
523call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
524call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
525if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
526 let s:treedepthstring= "│ "
527else
528 let s:treedepthstring= "| "
529endif
530call s:NetrwInit("s:netrw_nbcd",'{}')
531
532" BufEnter event ignored by decho when following variable is true
533"  Has a side effect that doau BufReadPost doesn't work, so
534"  files read by network transfer aren't appropriately highlighted.
535"let g:decho_bufenter = 1	"Decho
536
537" ======================
538"  Netrw Initialization: {{{1
539" ======================
540if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
541" call Decho("installed beval events",'~'.expand("<slnum>"))
542 let &l:bexpr = "netrw#BalloonHelp()"
543 au FileType netrw	setl beval
544 au WinLeave *		if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
545 au VimEnter * 		let s:initbeval= &beval
546"else " Decho
547" if v:version < 700           | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>"))     | endif
548" if !has("balloon_eval")      | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>"))        | endif
549" if exists("s:initbeval")     | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>"))                | endif
550" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>"))            | endif
551" if !has("syntax")            | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
552" if exists("g:syntax_on")     | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>"))                | endif
553endif
554au WinEnter *	if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
555
556if g:netrw_keepj =~# "keepj"
557 com! -nargs=*	NetrwKeepj	keepj <args>
558else
559 let g:netrw_keepj= ""
560 com! -nargs=*	NetrwKeepj	<args>
561endif
562
563" ==============================
564"  Netrw Utility Functions: {{{1
565" ==============================
566
567" ---------------------------------------------------------------------
568" netrw#BalloonHelp: {{{2
569if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
570" call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
571 fun! netrw#BalloonHelp()
572   if &ft != "netrw"
573    return ""
574   endif
575   if !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
576    let mesg= ""
577   elseif     v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
578    let mesg = "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
579   elseif     getline(v:beval_lnum) =~ '^"\s*/'
580    let mesg = "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
581   elseif     v:beval_text == "Sorted" || v:beval_text == "by"
582    let mesg = 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
583   elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
584    let mesg = "S: edit sorting sequence"
585   elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
586    let mesg = "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
587   elseif v:beval_text == "Quick" || v:beval_text == "Help"
588    let mesg = "Help: press <F1>"
589   elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
590    let mesg = "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
591   else
592    let mesg= ""
593   endif
594   return mesg
595 endfun
596"else " Decho
597" if v:version < 700            |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
598" if !has("balloon_eval")       |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>"))       |endif
599" if !has("syntax")             |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>"))                  |endif
600" if !exists("g:syntax_on")     |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>"))                  |endif
601" if  exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>"))           |endif
602endif
603
604" ------------------------------------------------------------------------
605" netrw#Explore: launch the local browser in the directory of the current file {{{2
606"          indx:  == -1: Nexplore
607"                 == -2: Pexplore
608"                 ==  +: this is overloaded:
609"                      * If Nexplore/Pexplore is in use, then this refers to the
610"                        indx'th item in the w:netrw_explore_list[] of items which
611"                        matched the */pattern **/pattern *//pattern **//pattern
612"                      * If Hexplore or Vexplore, then this will override
613"                        g:netrw_winsize to specify the qty of rows or columns the
614"                        newly split window should have.
615"          dosplit==0: the window will be split iff the current file has been modified and hidden not set
616"          dosplit==1: the window will be split before running the local browser
617"          style == 0: Explore     style == 1: Explore!
618"                == 2: Hexplore    style == 3: Hexplore!
619"                == 4: Vexplore    style == 5: Vexplore!
620"                == 6: Texplore
621fun! netrw#Explore(indx,dosplit,style,...)
622"  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)
623"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
624  if !exists("b:netrw_curdir")
625   let b:netrw_curdir= getcwd()
626"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
627  endif
628
629  " record current file for Rexplore's benefit
630  if &ft != "netrw"
631   let w:netrw_rexfile= expand("%:p")
632  endif
633
634  " record current directory
635  let curdir     = simplify(b:netrw_curdir)
636  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
637  if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
638   let curdir= substitute(curdir,'\','/','g')
639  endif
640"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">",'~'.expand("<slnum>"))
641
642  " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
643  " will end up with backslashes here.  Solution: strip off backslashes that precede white space and
644  " try Explore again.
645  if a:0 > 0
646"   call Decho('considering retry: a:1<'.a:1.'>: '.
647     \ ((a:1 =~ "\\\s")?                   'has backslash whitespace' : 'does not have backslash whitespace').', '.
648     \ ((filereadable(s:NetrwFile(a:1)))?  'is readable'              : 'is not readable').', '.
649     \ ((isdirectory(s:NetrwFile(a:1))))?  'is a directory'           : 'is not a directory',
650     \ '~'.expand("<slnum>"))
651   if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
652"    call Decho("re-trying Explore with <".substitute(a:1,'\\\(\s\)','\1','g').">",'~'.expand("<slnum>"))
653    call netrw#Explore(a:indx,a:dosplit,a:style,substitute(a:1,'\\\(\s\)','\1','g'))
654"    call Dret("netrw#Explore : returning from retry")
655    return
656"   else " Decho
657"    call Decho("retry not needed",'~'.expand("<slnum>"))
658   endif
659  endif
660
661  " save registers
662  if has("clipboard")
663   sil! let keepregstar = @*
664   sil! let keepregplus = @+
665  endif
666  sil! let keepregslash= @/
667
668  " if   dosplit
669  " -or- file has been modified AND file not hidden when abandoned
670  " -or- Texplore used
671  if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
672"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified",'~'.expand("<slnum>"))
673   call s:SaveWinVars()
674   let winsz= g:netrw_winsize
675   if a:indx > 0
676    let winsz= a:indx
677   endif
678
679   if a:style == 0      " Explore, Sexplore
680"    call Decho("style=0: Explore or Sexplore",'~'.expand("<slnum>"))
681    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
682    if winsz == 0|let winsz= ""|endif
683    exe "noswapfile ".winsz."wincmd s"
684"    call Decho("exe noswapfile ".winsz."wincmd s",'~'.expand("<slnum>"))
685
686   elseif a:style == 1  "Explore!, Sexplore!
687"    call Decho("style=1: Explore! or Sexplore!",'~'.expand("<slnum>"))
688    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
689    if winsz == 0|let winsz= ""|endif
690    exe "keepalt noswapfile ".winsz."wincmd v"
691"    call Decho("exe keepalt noswapfile ".winsz."wincmd v",'~'.expand("<slnum>"))
692
693   elseif a:style == 2  " Hexplore
694"    call Decho("style=2: Hexplore",'~'.expand("<slnum>"))
695    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
696    if winsz == 0|let winsz= ""|endif
697    exe "keepalt noswapfile bel ".winsz."wincmd s"
698"    call Decho("exe keepalt noswapfile bel ".winsz."wincmd s",'~'.expand("<slnum>"))
699
700   elseif a:style == 3  " Hexplore!
701"    call Decho("style=3: Hexplore!",'~'.expand("<slnum>"))
702    let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
703    if winsz == 0|let winsz= ""|endif
704    exe "keepalt noswapfile abo ".winsz."wincmd s"
705"    call Decho("exe keepalt noswapfile abo ".winsz."wincmd s",'~'.expand("<slnum>"))
706
707   elseif a:style == 4  " Vexplore
708"    call Decho("style=4: Vexplore",'~'.expand("<slnum>"))
709    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
710    if winsz == 0|let winsz= ""|endif
711    exe "keepalt noswapfile lefta ".winsz."wincmd v"
712"    call Decho("exe keepalt noswapfile lefta ".winsz."wincmd v",'~'.expand("<slnum>"))
713
714   elseif a:style == 5  " Vexplore!
715"    call Decho("style=5: Vexplore!",'~'.expand("<slnum>"))
716    let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
717    if winsz == 0|let winsz= ""|endif
718    exe "keepalt noswapfile rightb ".winsz."wincmd v"
719"    call Decho("exe keepalt noswapfile rightb ".winsz."wincmd v",'~'.expand("<slnum>"))
720
721   elseif a:style == 6  " Texplore
722    call s:SaveBufVars()
723"    call Decho("style  = 6: Texplore",'~'.expand("<slnum>"))
724    exe "keepalt tabnew ".fnameescape(curdir)
725"    call Decho("exe keepalt tabnew ".fnameescape(curdir),'~'.expand("<slnum>"))
726    call s:RestoreBufVars()
727   endif
728   call s:RestoreWinVars()
729"  else " Decho
730"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6",'~'.expand("<slnum>"))
731  endif
732  NetrwKeepj norm! 0
733
734  if a:0 > 0
735"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">",'~'.expand("<slnum>"))
736   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
737"    call Decho("..case a:1<".a:1.">: starts with ~ and unix or cygwin",'~'.expand("<slnum>"))
738    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
739"    call Decho("..using dirname<".dirname.">  (case: ~ && unix||cygwin)",'~'.expand("<slnum>"))
740   elseif a:1 == '.'
741"    call Decho("..case a:1<".a:1.">: matches .",'~'.expand("<slnum>"))
742    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
743    if dirname !~ '/$'
744     let dirname= dirname."/"
745    endif
746"    call Decho("..using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")",'~'.expand("<slnum>"))
747   elseif a:1 =~ '\$'
748"    call Decho("..case a:1<".a:1.">: matches ending $",'~'.expand("<slnum>"))
749    let dirname= simplify(expand(a:1))
750"    call Decho("..using user-specified dirname<".dirname."> with $env-var",'~'.expand("<slnum>"))
751   elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
752"    call Decho("..case a:1<".a:1.">: other, not pattern or filepattern",'~'.expand("<slnum>"))
753    let dirname= simplify(a:1)
754"    call Decho("..using user-specified dirname<".dirname.">",'~'.expand("<slnum>"))
755   else
756"    call Decho("..case a:1: pattern or filepattern",'~'.expand("<slnum>"))
757    let dirname= a:1
758   endif
759  else
760   " clear explore
761"   call Decho("case a:0=".a:0.": clearing Explore list",'~'.expand("<slnum>"))
762   call s:NetrwClearExplore()
763"   call Dret("netrw#Explore : cleared list")
764   return
765  endif
766
767"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
768  if dirname =~ '\.\./\=$'
769   let dirname= simplify(fnamemodify(dirname,':p:h'))
770  elseif dirname =~ '\.\.' || dirname == '.'
771   let dirname= simplify(fnamemodify(dirname,':p'))
772  endif
773"  call Decho("dirname<".dirname.">  (after simplify)",'~'.expand("<slnum>"))
774
775  if dirname =~ '^\*//'
776   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
777"   call Decho("case starpat=1: Explore *//pattern",'~'.expand("<slnum>"))
778   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
779   let starpat= 1
780"   call Decho("..Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
781   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
782
783  elseif dirname =~ '^\*\*//'
784   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
785"   call Decho("case starpat=2: Explore **//pattern",'~'.expand("<slnum>"))
786   let pattern= substitute(dirname,'^\*\*//','','')
787   let starpat= 2
788"   call Decho("..Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">",'~'.expand("<slnum>"))
789
790  elseif dirname =~ '/\*\*/'
791   " handle .../**/.../filepat
792"   call Decho("case starpat=4: Explore .../**/.../filepat",'~'.expand("<slnum>"))
793   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
794   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
795    let b:netrw_curdir = prefixdir
796   else
797    let b:netrw_curdir= getcwd().'/'.prefixdir
798   endif
799   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
800   let starpat= 4
801"   call Decho("..pwd<".getcwd()."> dirname<".dirname.">",'~'.expand("<slnum>"))
802"   call Decho("..case Explore ../**/../filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
803
804  elseif dirname =~ '^\*/'
805   " case starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
806   let starpat= 3
807"   call Decho("case starpat=3: Explore */filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
808
809  elseif dirname=~ '^\*\*/'
810   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
811   let starpat= 4
812"   call Decho("case starpat=4: Explore **/filepat (starpat=".starpat.")",'~'.expand("<slnum>"))
813
814  else
815   let starpat= 0
816"   call Decho("case starpat=0: default",'~'.expand("<slnum>"))
817  endif
818
819  if starpat == 0 && a:indx >= 0
820   " [Explore Hexplore Vexplore Sexplore] [dirname]
821"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname.">, handles Explore Hexplore Vexplore Sexplore",'~'.expand("<slnum>"))
822   if dirname == ""
823    let dirname= curfiledir
824"    call Decho("..empty dirname, using current file's directory<".dirname.">",'~'.expand("<slnum>"))
825   endif
826   if dirname =~# '^scp://' || dirname =~ '^ftp://'
827    call netrw#Nread(2,dirname)
828   else
829    if dirname == ""
830     let dirname= getcwd()
831    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
832     " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
833     " depending on whether backslashes have been converted to forward slashes by earlier code).
834     if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
835      let dirname= b:netrw_curdir."/".dirname
836     endif
837    elseif dirname !~ '^/'
838     let dirname= b:netrw_curdir."/".dirname
839    endif
840"    call Decho("..calling LocalBrowseCheck(dirname<".dirname.">)",'~'.expand("<slnum>"))
841    call netrw#LocalBrowseCheck(dirname)
842"    call Decho(" modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
843"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
844   endif
845   if exists("w:netrw_bannercnt")
846    " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
847    " If one wants to return the same place in the netrw window, use :Rex instead.
848    exe w:netrw_bannercnt
849   endif
850
851"   call Decho("curdir<".curdir.">",'~'.expand("<slnum>"))
852   " ---------------------------------------------------------------------
853   " Jan 24, 2013: not sure why the following was present.  See P08-Ingelrest
854"   if has("win32") || has("win95") || has("win64") || has("win16")
855"    NetrwKeepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
856"   else
857"    NetrwKeepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
858"   endif
859   " ---------------------------------------------------------------------
860
861  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
862  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
863  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
864  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
865  elseif a:indx <= 0
866   " Nexplore, Pexplore, Explore: handle starpat
867"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx,'~'.expand("<slnum>"))
868   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
869"    call Decho("..set up <s-up> and <s-down> maps",'~'.expand("<slnum>"))
870    let s:didstarstar= 1
871    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
872    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
873   endif
874
875   if has("path_extra")
876"    call Decho("..starpat=".starpat.": has +path_extra",'~'.expand("<slnum>"))
877    if !exists("w:netrw_explore_indx")
878     let w:netrw_explore_indx= 0
879    endif
880
881    let indx = a:indx
882"    call Decho("..starpat=".starpat.": set indx= [a:indx=".indx."]",'~'.expand("<slnum>"))
883
884    if indx == -1
885     " Nexplore
886"     call Decho("..case Nexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
887     if !exists("w:netrw_explore_list") " sanity check
888      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
889      if has("clipboard")
890       sil! let @* = keepregstar
891       sil! let @+ = keepregstar
892      endif
893      sil! let @/ = keepregslash
894"      call Dret("netrw#Explore")
895      return
896     endif
897     let indx= w:netrw_explore_indx
898     if indx < 0                        | let indx= 0                           | endif
899     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
900     let curfile= w:netrw_explore_list[indx]
901"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
902     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
903      let indx= indx + 1
904"      call Decho("....indx=".indx." (Nexplore while loop)",'~'.expand("<slnum>"))
905     endwhile
906     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
907"     call Decho("....Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
908
909    elseif indx == -2
910     " Pexplore
911"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")",'~'.expand("<slnum>"))
912     if !exists("w:netrw_explore_list") " sanity check
913      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
914      if has("clipboard")
915       sil! let @* = keepregstar
916       sil! let @+ = keepregstar
917      endif
918      sil! let @/ = keepregslash
919"      call Dret("netrw#Explore")
920      return
921     endif
922     let indx= w:netrw_explore_indx
923     if indx < 0                        | let indx= 0                           | endif
924     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
925     let curfile= w:netrw_explore_list[indx]
926"     call Decho("....indx=".indx." curfile<".curfile.">",'~'.expand("<slnum>"))
927     while indx >= 0 && curfile == w:netrw_explore_list[indx]
928      let indx= indx - 1
929"      call Decho("....indx=".indx." (Pexplore while loop)",'~'.expand("<slnum>"))
930     endwhile
931     if indx < 0                        | let indx= 0                           | endif
932"     call Decho("....Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx,'~'.expand("<slnum>"))
933
934    else
935     " Explore -- initialize
936     " build list of files to Explore with Nexplore/Pexplore
937"     call Decho("..starpat=".starpat.": case Explore: initialize (indx=".indx.")",'~'.expand("<slnum>"))
938     NetrwKeepj keepalt call s:NetrwClearExplore()
939     let w:netrw_explore_indx= 0
940     if !exists("b:netrw_curdir")
941      let b:netrw_curdir= getcwd()
942     endif
943"     call Decho("....starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
944
945     " switch on starpat to build the w:netrw_explore_list of files
946     if starpat == 1
947      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
948"      call Decho("..case starpat=".starpat.": build *//pattern list  (curdir-only srch for files containing pattern)  &hls=".&hls,'~'.expand("<slnum>"))
949"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
950      try
951       exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
952      catch /^Vim\%((\a\+)\)\=:E480/
953       keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
954"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
955       return
956      endtry
957      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
958      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
959
960     elseif starpat == 2
961      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
962"      call Decho("..case starpat=".starpat.": build **//pattern list  (recursive descent files containing pattern)",'~'.expand("<slnum>"))
963"      call Decho("....pattern<".pattern.">",'~'.expand("<slnum>"))
964      try
965       exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
966      catch /^Vim\%((\a\+)\)\=:E480/
967       keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
968       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
969       if has("clipboard")
970        sil! let @* = keepregstar
971        sil! let @+ = keepregstar
972       endif
973       sil! let @/ = keepregslash
974"       call Dret("netrw#Explore : no files matched pattern")
975       return
976      endtry
977      let s:netrw_curdir       = b:netrw_curdir
978      let w:netrw_explore_list = getqflist()
979      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
980      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
981
982     elseif starpat == 3
983      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
984"      call Decho("..case starpat=".starpat.": build */filepat list  (curdir-only srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
985      let filepat= substitute(dirname,'^\*/','','')
986      let filepat= substitute(filepat,'^[%#<]','\\&','')
987"      call Decho("....b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
988"      call Decho("....filepat<".filepat.">",'~'.expand("<slnum>"))
989      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
990      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
991
992     elseif starpat == 4
993      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
994"      call Decho("..case starpat=".starpat.": build **/filepat list  (recursive descent srch filenames matching filepat)  &hls=".&hls,'~'.expand("<slnum>"))
995      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
996      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
997     endif " switch on starpat to build w:netrw_explore_list
998
999     let w:netrw_explore_listlen = len(w:netrw_explore_list)
1000"     call Decho("....w:netrw_explore_list<".string(w:netrw_explore_list).">",'~'.expand("<slnum>"))
1001"     call Decho("....w:netrw_explore_listlen=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1002
1003     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1004      keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1005      if has("clipboard")
1006       sil! let @* = keepregstar
1007       sil! let @+ = keepregstar
1008      endif
1009      sil! let @/ = keepregslash
1010"      call Dret("netrw#Explore : no files matched")
1011      return
1012     endif
1013    endif  " if indx ... endif
1014
1015    " NetrwStatusLine support - for exploring support
1016    let w:netrw_explore_indx= indx
1017"    call Decho("....w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen,'~'.expand("<slnum>"))
1018
1019    " wrap the indx around, but issue a note
1020    if indx >= w:netrw_explore_listlen || indx < 0
1021"     call Decho("....wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")",'~'.expand("<slnum>"))
1022     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1023     let w:netrw_explore_indx= indx
1024     keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
1025    endif
1026
1027    exe "let dirfile= w:netrw_explore_list[".indx."]"
1028"    call Decho("....dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">",'~'.expand("<slnum>"))
1029    let newdir= substitute(dirfile,'/[^/]*$','','e')
1030"    call Decho("....newdir<".newdir.">",'~'.expand("<slnum>"))
1031
1032"    call Decho("....calling LocalBrowseCheck(newdir<".newdir.">)",'~'.expand("<slnum>"))
1033    call netrw#LocalBrowseCheck(newdir)
1034    if !exists("w:netrw_liststyle")
1035     let w:netrw_liststyle= g:netrw_liststyle
1036    endif
1037    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1038     keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1039    else
1040     keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1041    endif
1042    let w:netrw_explore_mtchcnt = indx + 1
1043    let w:netrw_explore_bufnr   = bufnr("%")
1044    let w:netrw_explore_line    = line(".")
1045    keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
1046"    call Decho("....explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line,'~'.expand("<slnum>"))
1047
1048   else
1049"    call Decho("..your vim does not have +path_extra",'~'.expand("<slnum>"))
1050    if !exists("g:netrw_quiet")
1051     keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1052    endif
1053    if has("clipboard")
1054     sil! let @* = keepregstar
1055     sil! let @+ = keepregstar
1056    endif
1057    sil! let @/ = keepregslash
1058"    call Dret("netrw#Explore : missing +path_extra")
1059    return
1060   endif
1061
1062  else
1063"   call Decho("..default case: Explore newdir<".dirname.">",'~'.expand("<slnum>"))
1064   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1065    sil! unlet w:netrw_treedict
1066    sil! unlet w:netrw_treetop
1067   endif
1068   let newdir= dirname
1069   if !exists("b:netrw_curdir")
1070    NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1071   else
1072    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
1073   endif
1074  endif
1075
1076  " visual display of **/ **// */ Exploration files
1077"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"),'~'.expand("<slnum>"))
1078"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">",'~'.expand("<slnum>"))
1079  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
1080"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"),'~'.expand("<slnum>"))
1081   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1082    " only update match list when current directory isn't the same as before
1083"    call Decho("only update match list when current directory not the same as before",'~'.expand("<slnum>"))
1084    let s:explore_prvdir = b:netrw_curdir
1085    let s:explore_match  = ""
1086    let dirlen           = strlen(b:netrw_curdir)
1087    if b:netrw_curdir !~ '/$'
1088     let dirlen= dirlen + 1
1089    endif
1090    let prvfname= ""
1091    for fname in w:netrw_explore_list
1092"     call Decho("fname<".fname.">",'~'.expand("<slnum>"))
1093     if fname =~ '^'.b:netrw_curdir
1094      if s:explore_match == ""
1095       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1096      else
1097       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1098      endif
1099     elseif fname !~ '^/' && fname != prvfname
1100      if s:explore_match == ""
1101       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1102      else
1103       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1104      endif
1105     endif
1106     let prvfname= fname
1107    endfor
1108"    call Decho("explore_match<".s:explore_match.">",'~'.expand("<slnum>"))
1109    exe "2match netrwMarkFile /".s:explore_match."/"
1110   endif
1111   echo "<s-up>==Pexplore  <s-down>==Nexplore"
1112  else
1113   2match none
1114   if exists("s:explore_match")  | unlet s:explore_match  | endif
1115   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
1116   echo " "
1117"   call Decho("cleared explore match list",'~'.expand("<slnum>"))
1118  endif
1119
1120  " since Explore may be used to initialize netrw's browser,
1121  " there's no danger of a late FocusGained event on initialization.
1122  " Consequently, set s:netrw_events to 2.
1123  let s:netrw_events= 2
1124  if has("clipboard")
1125   sil! let @* = keepregstar
1126   sil! let @+ = keepregstar
1127  endif
1128  sil! let @/ = keepregslash
1129"  call Dret("netrw#Explore : @/<".@/.">")
1130endfun
1131
1132" ---------------------------------------------------------------------
1133" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
1134fun! netrw#Lexplore(count,rightside,...)
1135"  call Dfunc("netrw#Lexplore(count=".a:count."rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
1136  let curwin= winnr()
1137
1138  if a:0 > 0 && a:1 != ""
1139   " if a netrw window is already on the left-side of the tab
1140   " and a directory has been specified, explore with that
1141   " directory.
1142   let a1 = expand(a:1)
1143"   call Decho("a:1<".a:1.">  curwin#".curwin,'~'.expand("<slnum>"))
1144   exe "1wincmd w"
1145   if &ft == "netrw"
1146"    call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
1147    exe "Explore ".fnameescape(a1)
1148    exe curwin."wincmd w"
1149    if exists("t:netrw_lexposn")
1150"     call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
1151     unlet t:netrw_lexposn
1152    endif
1153"    call Dret("netrw#Lexplore")
1154    return
1155   endif
1156   exe curwin."wincmd w"
1157  else
1158   let a1= ""
1159  endif
1160
1161  if exists("t:netrw_lexbufnr")
1162   " check if t:netrw_lexbufnr refers to a netrw window
1163   let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1164  else
1165   let lexwinnr= 0
1166  endif
1167
1168  if lexwinnr > 0
1169   " close down netrw explorer window
1170"  call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
1171   exe lexwinnr."wincmd w"
1172   let g:netrw_winsize = -winwidth(0)
1173   let t:netrw_lexposn = winsaveview()
1174"   call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1175"   call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
1176   close
1177   if lexwinnr < curwin
1178    let curwin= curwin - 1
1179   endif
1180   exe curwin."wincmd w"
1181   unlet t:netrw_lexbufnr
1182
1183  else
1184   " open netrw explorer window
1185"   call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
1186   exe "1wincmd w"
1187   let keep_altv    = g:netrw_altv
1188   let g:netrw_altv = 0
1189   if a:count != 0
1190    let netrw_winsize   = g:netrw_winsize
1191    let g:netrw_winsize = a:count
1192   endif
1193   let curfile= expand("%")
1194"   call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
1195   exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1196   if a:0 > 0 && a1 != ""
1197"    call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
1198    exe "Explore ".fnameescape(a1)
1199   elseif curfile =~ '^\a\{3,}://'
1200"    call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
1201    exe "Explore ".substitute(curfile,'[^/\\]*$','','')
1202   else
1203"    call Decho("case 3: Explore .",'~'.expand("<slnum>"))
1204    Explore .
1205   endif
1206   if a:count != 0
1207    let g:netrw_winsize = netrw_winsize
1208   endif
1209   setlocal winfixwidth
1210   let g:netrw_altv     = keep_altv
1211   let t:netrw_lexbufnr = bufnr("%")
1212   if exists("t:netrw_lexposn")
1213"    call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1214"    call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1215    call winrestview(t:netrw_lexposn)
1216    unlet t:netrw_lexposn
1217   endif
1218  endif
1219
1220  " set up default window for editing via <cr>
1221  if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
1222   if a:rightside
1223    let g:netrw_chgwin= 1
1224   else
1225    let g:netrw_chgwin= 2
1226   endif
1227  endif
1228
1229"  call Dret("netrw#Lexplore")
1230endfun
1231
1232" ---------------------------------------------------------------------
1233" netrw#Clean: remove netrw {{{2
1234" supports :NetrwClean  -- remove netrw from first directory on runtimepath
1235"          :NetrwClean! -- remove netrw from all directories on runtimepath
1236fun! netrw#Clean(sys)
1237"  call Dfunc("netrw#Clean(sys=".a:sys.")")
1238
1239  if a:sys
1240   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
1241  else
1242   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
1243  endif
1244"  call Decho("choice=".choice,'~'.expand("<slnum>"))
1245  let diddel= 0
1246  let diddir= ""
1247
1248  if choice == 1
1249   for dir in split(&rtp,',')
1250    if filereadable(dir."/plugin/netrwPlugin.vim")
1251"     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1252     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
1253     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1254     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
1255     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
1256     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
1257     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
1258     let diddir= dir
1259     let diddel= diddel + 1
1260     if !a:sys|break|endif
1261    endif
1262   endfor
1263  endif
1264
1265   echohl WarningMsg
1266  if diddel == 0
1267   echomsg "netrw is either not installed or not removable"
1268  elseif diddel == 1
1269   echomsg "removed one copy of netrw from <".diddir.">"
1270  else
1271   echomsg "removed ".diddel." copies of netrw"
1272  endif
1273   echohl None
1274
1275"  call Dret("netrw#Clean")
1276endfun
1277
1278" ---------------------------------------------------------------------
1279" netrw#MakeTgt: make a target out of the directory name provided {{{2
1280fun! netrw#MakeTgt(dname)
1281"  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1282   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
1283  let svpos               = winsaveview()
1284"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1285  let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
1286"  call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
1287  if s:netrwmftgt_islocal
1288   let netrwmftgt= simplify(a:dname)
1289  else
1290   let netrwmftgt= a:dname
1291  endif
1292  if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
1293   " re-selected target, so just clear it
1294   unlet s:netrwmftgt s:netrwmftgt_islocal
1295  else
1296   let s:netrwmftgt= netrwmftgt
1297  endif
1298  if g:netrw_fastbrowse <= 1
1299   call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
1300  endif
1301"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
1302  call winrestview(svpos)
1303"  call Dret("netrw#MakeTgt")
1304endfun
1305
1306" ---------------------------------------------------------------------
1307" netrw#Obtain: {{{2
1308"   netrw#Obtain(islocal,fname[,tgtdirectory])
1309"     islocal=0  obtain from remote source
1310"            =1  obtain from local source
1311"     fname  :   a filename or a list of filenames
1312"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
1313fun! netrw#Obtain(islocal,fname,...)
1314"  call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
1315  " NetrwStatusLine support - for obtaining support
1316
1317  if type(a:fname) == 1
1318   let fnamelist= [ a:fname ]
1319  elseif type(a:fname) == 3
1320   let fnamelist= a:fname
1321  else
1322   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1323"   call Dret("netrw#Obtain")
1324   return
1325  endif
1326"  call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
1327  if a:0 > 0
1328   let tgtdir= a:1
1329  else
1330   let tgtdir= getcwd()
1331  endif
1332"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
1333
1334  if exists("b:netrw_islocal") && b:netrw_islocal
1335   " obtain a file from local b:netrw_curdir to (local) tgtdir
1336"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1337   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1338    let topath= s:ComposePath(tgtdir,"")
1339    if (has("win32") || has("win95") || has("win64") || has("win16"))
1340     " transfer files one at time
1341"     call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1342     for fname in fnamelist
1343"      call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1344      call system(g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1345      if v:shell_error != 0
1346       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1347"       call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1348       return
1349      endif
1350     endfor
1351    else
1352     " transfer files with one command
1353"     call Decho("transfer files with one command",'~'.expand("<slnum>"))
1354     let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1355"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1356     call system(g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1357     if v:shell_error != 0
1358      call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1359"      call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1360      return
1361     endif
1362    endif
1363   elseif !exists("b:netrw_curdir")
1364    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
1365   else
1366    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
1367   endif
1368
1369  else
1370   " obtain files from remote b:netrw_curdir to local tgtdir
1371"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1372   if type(a:fname) == 1
1373    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
1374   endif
1375   call s:NetrwMethod(b:netrw_curdir)
1376
1377   if b:netrw_method == 4
1378    " obtain file using scp
1379"    call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1380    if exists("g:netrw_port") && g:netrw_port != ""
1381     let useport= " ".g:netrw_scpport." ".g:netrw_port
1382    else
1383     let useport= ""
1384    endif
1385    if b:netrw_fname =~ '/'
1386     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1387    else
1388     let path= ""
1389    endif
1390    let filelist= join(map(deepcopy(fnamelist),'s:ShellEscape(g:netrw_machine.":".path.v:val,1)'))
1391    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
1392
1393   elseif b:netrw_method == 2
1394    " obtain file using ftp + .netrc
1395"     call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1396     call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1397     let tmpbufnr= bufnr("%")
1398     setl ff=unix
1399     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1400      NetrwKeepj put =g:netrw_ftpmode
1401"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1402     endif
1403
1404     if exists("b:netrw_fname") && b:netrw_fname != ""
1405      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1406"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1407     endif
1408
1409     if exists("g:netrw_ftpextracmd")
1410      NetrwKeepj put =g:netrw_ftpextracmd
1411"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1412     endif
1413     for fname in fnamelist
1414      call setline(line("$")+1,'get "'.fname.'"')
1415"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1416     endfor
1417     if exists("g:netrw_port") && g:netrw_port != ""
1418      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1419     else
1420      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1421     endif
1422     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1423     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1424      let debugkeep= &debug
1425      setl debug=msg
1426      call netrw#ErrorMsg(s:ERROR,getline(1),4)
1427      let &debug= debugkeep
1428     endif
1429
1430   elseif b:netrw_method == 3
1431    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1432"    call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1433    call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1434    let tmpbufnr= bufnr("%")
1435    setl ff=unix
1436
1437    if exists("g:netrw_port") && g:netrw_port != ""
1438     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1439"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1440    else
1441     NetrwKeepj put ='open '.g:netrw_machine
1442"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1443    endif
1444
1445    if exists("g:netrw_uid") && g:netrw_uid != ""
1446     if exists("g:netrw_ftp") && g:netrw_ftp == 1
1447      NetrwKeepj put =g:netrw_uid
1448"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1449      if exists("s:netrw_passwd") && s:netrw_passwd != ""
1450       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1451      endif
1452"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1453     elseif exists("s:netrw_passwd")
1454      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1455"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1456     endif
1457    endif
1458
1459    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1460     NetrwKeepj put =g:netrw_ftpmode
1461"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1462    endif
1463
1464    if exists("b:netrw_fname") && b:netrw_fname != ""
1465     NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1466"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1467    endif
1468
1469    if exists("g:netrw_ftpextracmd")
1470     NetrwKeepj put =g:netrw_ftpextracmd
1471"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1472    endif
1473
1474    if exists("g:netrw_ftpextracmd")
1475     NetrwKeepj put =g:netrw_ftpextracmd
1476"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1477    endif
1478    for fname in fnamelist
1479     NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1480    endfor
1481"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1482
1483    " perform ftp:
1484    " -i       : turns off interactive prompting from ftp
1485    " -n  unix : DON'T use <.netrc>, even though it exists
1486    " -n  win32: quit being obnoxious about password
1487    NetrwKeepj norm! 1Gdd
1488    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1489    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1490    if getline(1) !~ "^$"
1491"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1492     if !exists("g:netrw_quiet")
1493      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1494     endif
1495    endif
1496
1497   elseif b:netrw_method == 9
1498    " obtain file using sftp
1499"    call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1500    if a:fname =~ '/'
1501     let localfile= substitute(a:fname,'^.*/','','')
1502    else
1503     let localfile= a:fname
1504    endif
1505    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))
1506
1507   elseif !exists("b:netrw_method") || b:netrw_method < 0
1508    " probably a badly formed url; protocol not recognized
1509"    call Dret("netrw#Obtain : unsupported method")
1510    return
1511
1512   else
1513    " protocol recognized but not supported for Obtain (yet?)
1514    if !exists("g:netrw_quiet")
1515     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1516    endif
1517"    call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1518    return
1519   endif
1520
1521   " restore status line
1522   if type(a:fname) == 1 && exists("s:netrw_users_stl")
1523    NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
1524   endif
1525
1526  endif
1527
1528  " cleanup
1529  if exists("tmpbufnr")
1530   if bufnr("%") != tmpbufnr
1531    exe tmpbufnr."bw!"
1532   else
1533    q!
1534   endif
1535  endif
1536
1537"  call Dret("netrw#Obtain")
1538endfun
1539
1540" ---------------------------------------------------------------------
1541" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1542fun! netrw#Nread(mode,fname)
1543"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
1544  let svpos= winsaveview()
1545"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1546  call netrw#NetRead(a:mode,a:fname)
1547"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
1548  call winrestview(svpos)
1549
1550  if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
1551   if exists("w:netrw_bannercnt")
1552    " start with cursor just after the banner
1553    exe w:netrw_bannercnt
1554   endif
1555  endif
1556"  call Dret("netrw#Nread")
1557endfun
1558
1559" ------------------------------------------------------------------------
1560" s:NetrwOptionRestore: restore options (based on prior s:NetrwOptionSave) {{{2
1561fun! s:NetrwOptionRestore(vt)
1562"  call Dfunc("s:NetrwOptionRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
1563"  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>"))
1564  if !exists("{a:vt}netrw_optionsave")
1565   call s:RestorePosn(s:netrw_nbcd)
1566"   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>"))
1567"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1568"   call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist")
1569   return
1570  endif
1571  unlet {a:vt}netrw_optionsave
1572
1573  if exists("+acd")
1574   if exists("{a:vt}netrw_acdkeep")
1575"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1576    let curdir = getcwd()
1577    let &l:acd = {a:vt}netrw_acdkeep
1578    unlet {a:vt}netrw_acdkeep
1579    if &l:acd
1580     call s:NetrwLcd(curdir)
1581    endif
1582   endif
1583  endif
1584  if exists("{a:vt}netrw_aikeep")   |let &l:ai     = {a:vt}netrw_aikeep      |unlet {a:vt}netrw_aikeep   |endif
1585  if exists("{a:vt}netrw_awkeep")   |let &l:aw     = {a:vt}netrw_awkeep      |unlet {a:vt}netrw_awkeep   |endif
1586  if exists("{a:vt}netrw_blkeep")   |let &l:bl     = {a:vt}netrw_blkeep      |unlet {a:vt}netrw_blkeep   |endif
1587  if exists("{a:vt}netrw_btkeep")   |let &l:bt     = {a:vt}netrw_btkeep      |unlet {a:vt}netrw_btkeep   |endif
1588  if exists("{a:vt}netrw_bombkeep") |let &l:bomb   = {a:vt}netrw_bombkeep    |unlet {a:vt}netrw_bombkeep |endif
1589  if exists("{a:vt}netrw_cedit")    |let &cedit    = {a:vt}netrw_cedit       |unlet {a:vt}netrw_cedit    |endif
1590  if exists("{a:vt}netrw_cikeep")   |let &l:ci     = {a:vt}netrw_cikeep      |unlet {a:vt}netrw_cikeep   |endif
1591  if exists("{a:vt}netrw_cinkeep")  |let &l:cin    = {a:vt}netrw_cinkeep     |unlet {a:vt}netrw_cinkeep  |endif
1592  if exists("{a:vt}netrw_cinokeep") |let &l:cino   = {a:vt}netrw_cinokeep    |unlet {a:vt}netrw_cinokeep |endif
1593  if exists("{a:vt}netrw_comkeep")  |let &l:com    = {a:vt}netrw_comkeep     |unlet {a:vt}netrw_comkeep  |endif
1594  if exists("{a:vt}netrw_cpokeep")  |let &l:cpo    = {a:vt}netrw_cpokeep     |unlet {a:vt}netrw_cpokeep  |endif
1595  if exists("{a:vt}netrw_diffkeep") |let &l:diff   = {a:vt}netrw_diffkeep    |unlet {a:vt}netrw_diffkeep |endif
1596  if exists("{a:vt}netrw_fenkeep")  |let &l:fen    = {a:vt}netrw_fenkeep     |unlet {a:vt}netrw_fenkeep  |endif
1597  if exists("g:netrw_ffkep") && g:netrw_ffkeep
1598   if exists("{a:vt}netrw_ffkeep")   |let &l:ff     = {a:vt}netrw_ffkeep      |unlet {a:vt}netrw_ffkeep   |endif
1599  endif
1600  if exists("{a:vt}netrw_fokeep")   |let &l:fo     = {a:vt}netrw_fokeep      |unlet {a:vt}netrw_fokeep   |endif
1601  if exists("{a:vt}netrw_gdkeep")   |let &l:gd     = {a:vt}netrw_gdkeep      |unlet {a:vt}netrw_gdkeep   |endif
1602  if exists("{a:vt}netrw_hidkeep")  |let &l:hidden = {a:vt}netrw_hidkeep     |unlet {a:vt}netrw_hidkeep  |endif
1603  if exists("{a:vt}netrw_imkeep")   |let &l:im     = {a:vt}netrw_imkeep      |unlet {a:vt}netrw_imkeep   |endif
1604  if exists("{a:vt}netrw_iskkeep")  |let &l:isk    = {a:vt}netrw_iskkeep     |unlet {a:vt}netrw_iskkeep  |endif
1605  if exists("{a:vt}netrw_lskeep")   |let &l:ls     = {a:vt}netrw_lskeep      |unlet {a:vt}netrw_lskeep   |endif
1606  if exists("{a:vt}netrw_makeep")   |let &l:ma     = {a:vt}netrw_makeep      |unlet {a:vt}netrw_makeep   |endif
1607  if exists("{a:vt}netrw_magickeep")|let &l:magic  = {a:vt}netrw_magickeep   |unlet {a:vt}netrw_magickeep|endif
1608  if exists("{a:vt}netrw_modkeep")  |let &l:mod    = {a:vt}netrw_modkeep     |unlet {a:vt}netrw_modkeep  |endif
1609  if exists("{a:vt}netrw_nukeep")   |let &l:nu     = {a:vt}netrw_nukeep      |unlet {a:vt}netrw_nukeep   |endif
1610  if exists("{a:vt}netrw_rnukeep")  |let &l:rnu    = {a:vt}netrw_rnukeep     |unlet {a:vt}netrw_rnukeep  |endif
1611  if exists("{a:vt}netrw_repkeep")  |let &l:report = {a:vt}netrw_repkeep     |unlet {a:vt}netrw_repkeep  |endif
1612  if exists("{a:vt}netrw_rokeep")   |let &l:ro     = {a:vt}netrw_rokeep      |unlet {a:vt}netrw_rokeep   |endif
1613  if exists("{a:vt}netrw_selkeep")  |let &l:sel    = {a:vt}netrw_selkeep     |unlet {a:vt}netrw_selkeep  |endif
1614  if exists("{a:vt}netrw_spellkeep")|let &l:spell  = {a:vt}netrw_spellkeep   |unlet {a:vt}netrw_spellkeep|endif
1615  if has("clipboard")
1616   if exists("{a:vt}netrw_starkeep") |let @*        = {a:vt}netrw_starkeep    |unlet {a:vt}netrw_starkeep |endif
1617  endif
1618  " Problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1619"  if exists("{a:vt}netrw_tskeep")   |let &l:ts     = {a:vt}netrw_tskeep      |unlet {a:vt}netrw_tskeep   |endif
1620  if exists("{a:vt}netrw_twkeep")   |let &l:tw     = {a:vt}netrw_twkeep      |unlet {a:vt}netrw_twkeep   |endif
1621  if exists("{a:vt}netrw_wigkeep")  |let &l:wig    = {a:vt}netrw_wigkeep     |unlet {a:vt}netrw_wigkeep  |endif
1622  if exists("{a:vt}netrw_wrapkeep") |let &l:wrap   = {a:vt}netrw_wrapkeep    |unlet {a:vt}netrw_wrapkeep |endif
1623  if exists("{a:vt}netrw_writekeep")|let &l:write  = {a:vt}netrw_writekeep   |unlet {a:vt}netrw_writekeep|endif
1624  if exists("s:yykeep")             |let  @@       = s:yykeep                |unlet s:yykeep             |endif
1625  if exists("{a:vt}netrw_swfkeep")
1626   if &directory == ""
1627    " user hasn't specified a swapfile directory;
1628    " netrw will temporarily set the swapfile directory
1629    " to the current directory as returned by getcwd().
1630    let &l:directory= getcwd()
1631    sil! let &l:swf = {a:vt}netrw_swfkeep
1632    setl directory=
1633    unlet {a:vt}netrw_swfkeep
1634   elseif &l:swf != {a:vt}netrw_swfkeep
1635    if !g:netrw_use_noswf
1636     " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1637     sil! let &l:swf= {a:vt}netrw_swfkeep
1638    endif
1639    unlet {a:vt}netrw_swfkeep
1640   endif
1641  endif
1642  if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
1643   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1644   if exists("{a:vt}netrw_dirkeep")
1645    call s:NetrwLcd(dirkeep)
1646    unlet {a:vt}netrw_dirkeep
1647   endif
1648  endif
1649  if has("clipboard")
1650   if exists("{a:vt}netrw_regstar") |sil! let @*= {a:vt}netrw_regstar |unlet {a:vt}netrw_regstar |endif
1651  endif
1652  if exists("{a:vt}netrw_regslash")|sil! let @/= {a:vt}netrw_regslash|unlet {a:vt}netrw_regslash|endif
1653  call s:RestorePosn(s:netrw_nbcd)
1654
1655"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
1656"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
1657"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
1658"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
1659"  call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
1660  " Moved the filetype detect here from NetrwGetFile() because remote files
1661  " were having their filetype detect-generated settings overwritten by
1662  " NetrwOptionRestore.
1663  if &ft != "netrw"
1664"   call Decho("filetype detect  (ft=".&ft.")",'~'.expand("<slnum>"))
1665   filetype detect
1666  endif
1667"  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>"))
1668"  call Dret("s:NetrwOptionRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
1669endfun
1670
1671" ---------------------------------------------------------------------
1672" s:NetrwOptionSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1673"             Options get restored by s:NetrwOptionRestore()
1674"  06/08/07 : removed call to NetrwSafeOptions(), either placed
1675"             immediately after NetrwOptionSave() calls in NetRead
1676"             and NetWrite, or after the s:NetrwEnew() call in
1677"             NetrwBrowse.
1678"             vt: normally its "w:" or "s:" (a variable type)
1679fun! s:NetrwOptionSave(vt)
1680"  call Dfunc("s:NetrwOptionSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1681"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1682"  call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>"))
1683
1684  if !exists("{a:vt}netrw_optionsave")
1685   let {a:vt}netrw_optionsave= 1
1686  else
1687"   call Dret("s:NetrwOptionSave : options already saved")
1688   return
1689  endif
1690"  call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
1691
1692  " Save current settings and current directory
1693"  call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
1694  let s:yykeep          = @@
1695  if exists("&l:acd")|let {a:vt}netrw_acdkeep  = &l:acd|endif
1696  let {a:vt}netrw_aikeep    = &l:ai
1697  let {a:vt}netrw_awkeep    = &l:aw
1698  let {a:vt}netrw_bhkeep    = &l:bh
1699  let {a:vt}netrw_blkeep    = &l:bl
1700  let {a:vt}netrw_btkeep    = &l:bt
1701  let {a:vt}netrw_bombkeep  = &l:bomb
1702  let {a:vt}netrw_cedit     = &cedit
1703  let {a:vt}netrw_cikeep    = &l:ci
1704  let {a:vt}netrw_cinkeep   = &l:cin
1705  let {a:vt}netrw_cinokeep  = &l:cino
1706  let {a:vt}netrw_comkeep   = &l:com
1707  let {a:vt}netrw_cpokeep   = &l:cpo
1708  let {a:vt}netrw_diffkeep  = &l:diff
1709  let {a:vt}netrw_fenkeep   = &l:fen
1710  if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
1711   let {a:vt}netrw_ffkeep    = &l:ff
1712  endif
1713  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
1714  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
1715  let {a:vt}netrw_hidkeep   = &l:hidden
1716  let {a:vt}netrw_imkeep    = &l:im
1717  let {a:vt}netrw_iskkeep   = &l:isk
1718  let {a:vt}netrw_lskeep    = &l:ls
1719  let {a:vt}netrw_makeep    = &l:ma
1720  let {a:vt}netrw_magickeep = &l:magic
1721  let {a:vt}netrw_modkeep   = &l:mod
1722  let {a:vt}netrw_nukeep    = &l:nu
1723  let {a:vt}netrw_rnukeep   = &l:rnu
1724  let {a:vt}netrw_repkeep   = &l:report
1725  let {a:vt}netrw_rokeep    = &l:ro
1726  let {a:vt}netrw_selkeep   = &l:sel
1727  let {a:vt}netrw_spellkeep = &l:spell
1728  if !g:netrw_use_noswf
1729   let {a:vt}netrw_swfkeep  = &l:swf
1730  endif
1731  if has("clipboard")
1732   let {a:vt}netrw_starkeep = @*
1733  endif
1734  let {a:vt}netrw_tskeep    = &l:ts
1735  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
1736  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
1737  let {a:vt}netrw_wrapkeep  = &l:wrap
1738  let {a:vt}netrw_writekeep = &l:write
1739
1740  " save a few selected netrw-related variables
1741"  call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
1742  if g:netrw_keepdir
1743   let {a:vt}netrw_dirkeep  = getcwd()
1744  endif
1745  if has("clipboard")
1746   if &go =~# 'a' | sil! let {a:vt}netrw_regstar = @* | endif
1747  endif
1748  sil! let {a:vt}netrw_regslash= @/
1749
1750"  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>"))
1751"  call Dret("s:NetrwOptionSave : tab#".tabpagenr()." win#".winnr())
1752endfun
1753
1754" ------------------------------------------------------------------------
1755" s:NetrwSafeOptions: sets options to help netrw do its job {{{2
1756"                     Use  s:NetrwSaveOptions() to save user settings
1757"                     Use  s:NetrwOptionRestore() to restore user settings
1758fun! s:NetrwSafeOptions()
1759"  call Dfunc("s:NetrwSafeOptions() win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1760"  call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1761"  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>"))
1762  if exists("+acd") | setl noacd | endif
1763  setl noai
1764  setl noaw
1765  setl nobl
1766  setl nobomb
1767  setl bt=nofile
1768  setl noci
1769  setl nocin
1770  setl bh=hide
1771  setl cino=
1772  setl com=
1773  setl cpo-=a
1774  setl cpo-=A
1775  setl fo=nroql2
1776  setl nohid
1777  setl noim
1778  setl isk+=@ isk+=* isk+=/
1779  setl magic
1780  if g:netrw_use_noswf
1781   setl noswf
1782  endif
1783  setl report=10000
1784  setl sel=inclusive
1785  setl nospell
1786  setl tw=0
1787  setl wig=
1788  setl cedit&
1789  call s:NetrwCursor()
1790
1791  " allow the user to override safe options
1792"  call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
1793  if &ft == "netrw"
1794"   call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1795   sil! keepalt NetrwKeepj doau FileType netrw
1796  endif
1797
1798"  call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1799"  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>"))
1800"  call Dret("s:NetrwSafeOptions")
1801endfun
1802
1803" ---------------------------------------------------------------------
1804" NetrwStatusLine: {{{2
1805fun! NetrwStatusLine()
1806
1807" vvv NetrwStatusLine() debugging vvv
1808"  let g:stlmsg=""
1809"  if !exists("w:netrw_explore_bufnr")
1810"   let g:stlmsg="!X<explore_bufnr>"
1811"  elseif w:netrw_explore_bufnr != bufnr("%")
1812"   let g:stlmsg="explore_bufnr!=".bufnr("%")
1813"  endif
1814"  if !exists("w:netrw_explore_line")
1815"   let g:stlmsg=" !X<explore_line>"
1816"  elseif w:netrw_explore_line != line(".")
1817"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1818"  endif
1819"  if !exists("w:netrw_explore_list")
1820"   let g:stlmsg=" !X<explore_list>"
1821"  endif
1822" ^^^ NetrwStatusLine() debugging ^^^
1823
1824  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")
1825   " restore user's status line
1826   let &stl        = s:netrw_users_stl
1827   let &laststatus = s:netrw_users_ls
1828   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1829   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1830   return ""
1831  else
1832   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
1833  endif
1834endfun
1835
1836" ---------------------------------------------------------------------
1837"  Netrw Transfer Functions: {{{1
1838" ===============================
1839
1840" ------------------------------------------------------------------------
1841" netrw#NetRead: responsible for reading a file over the net {{{2
1842"   mode: =0 read remote file and insert before current line
1843"         =1 read remote file and insert after current line
1844"         =2 replace with remote file
1845"         =3 obtain file, but leave in temporary format
1846fun! netrw#NetRead(mode,...)
1847"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
1848
1849  " NetRead: save options {{{3
1850  call s:NetrwOptionSave("w:")
1851  call s:NetrwSafeOptions()
1852  call s:RestoreCursorline()
1853  " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
1854  " However, this setting is not wanted for a remote editing session.  The buffer should be "nofile", still.
1855  setl bl
1856"  call Decho("(netrw#NetRead) buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
1857
1858  " NetRead: interpret mode into a readcmd {{{3
1859  if     a:mode == 0 " read remote file before current line
1860   let readcmd = "0r"
1861  elseif a:mode == 1 " read file after current line
1862   let readcmd = "r"
1863  elseif a:mode == 2 " replace with remote file
1864   let readcmd = "%r"
1865  elseif a:mode == 3 " skip read of file (leave as temporary)
1866   let readcmd = "t"
1867  else
1868   exe a:mode
1869   let readcmd = "r"
1870  endif
1871  let ichoice = (a:0 == 0)? 0 : 1
1872"  call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
1873
1874  " NetRead: get temporary filename {{{3
1875  let tmpfile= s:GetTempfile("")
1876  if tmpfile == ""
1877"   call Dret("netrw#NetRead : unable to get a tempfile!")
1878   return
1879  endif
1880
1881  while ichoice <= a:0
1882
1883   " attempt to repeat with previous host-file-etc
1884   if exists("b:netrw_lastfile") && a:0 == 0
1885"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
1886    let choice = b:netrw_lastfile
1887    let ichoice= ichoice + 1
1888
1889   else
1890    exe "let choice= a:" . ichoice
1891"    call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
1892
1893    if match(choice,"?") == 0
1894     " give help
1895     echomsg 'NetRead Usage:'
1896     echomsg ':Nread machine:path                         uses rcp'
1897     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
1898     echomsg ':Nread "machine id password path"           uses ftp'
1899     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
1900     echomsg ':Nread fetch://machine/path                 uses fetch'
1901     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
1902     echomsg ':Nread http://[user@]machine/path           uses http  wget'
1903     echomsg ':Nread file:///path           		  uses elinks'
1904     echomsg ':Nread https://[user@]machine/path          uses http  wget'
1905     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
1906     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
1907     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
1908     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
1909     sleep 4
1910     break
1911
1912    elseif match(choice,'^"') != -1
1913     " Reconstruct Choice if choice starts with '"'
1914"     call Decho("reconstructing choice",'~'.expand("<slnum>"))
1915     if match(choice,'"$') != -1
1916      " case "..."
1917      let choice= strpart(choice,1,strlen(choice)-2)
1918     else
1919       "  case "... ... ..."
1920      let choice      = strpart(choice,1,strlen(choice)-1)
1921      let wholechoice = ""
1922
1923      while match(choice,'"$') == -1
1924       let wholechoice = wholechoice . " " . choice
1925       let ichoice     = ichoice + 1
1926       if ichoice > a:0
1927       	if !exists("g:netrw_quiet")
1928	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
1929	endif
1930"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
1931        return
1932       endif
1933       let choice= a:{ichoice}
1934      endwhile
1935      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
1936     endif
1937    endif
1938   endif
1939
1940"   call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
1941   let ichoice= ichoice + 1
1942
1943   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
1944   call s:NetrwMethod(choice)
1945   if !exists("b:netrw_method") || b:netrw_method < 0
1946"    call Dfunc("netrw#NetRead : unsupported method")
1947    return
1948   endif
1949   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
1950
1951   " Check whether or not NetrwBrowse() should be handling this request
1952"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
1953   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
1954"    call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
1955    NetrwKeepj call s:NetrwBrowse(0,choice)
1956"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
1957    return
1958   endif
1959
1960   " ============
1961   " NetRead: Perform Protocol-Based Read {{{3
1962   " ===========================
1963   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
1964    echo "(netrw) Processing your read request..."
1965   endif
1966
1967   ".........................................
1968   " NetRead: (rcp)  NetRead Method #1 {{{3
1969   if  b:netrw_method == 1 " read with rcp
1970"    call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
1971   " ER: nothing done with g:netrw_uid yet?
1972   " ER: on Win2K" rcp machine[.user]:file tmpfile
1973   " ER: when machine contains '.' adding .user is required (use $USERNAME)
1974   " ER: the tmpfile is full path: rcp sees C:\... as host C
1975   if s:netrw_has_nt_rcp == 1
1976    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
1977     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
1978    else
1979     " Any way needed it machine contains a '.'
1980     let uid_machine = g:netrw_machine .'.'. $USERNAME
1981    endif
1982   else
1983    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
1984     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
1985    else
1986     let uid_machine = g:netrw_machine
1987    endif
1988   endif
1989   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))
1990   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
1991   let b:netrw_lastfile = choice
1992
1993   ".........................................
1994   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
1995   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
1996"     call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1997     let netrw_fname= b:netrw_fname
1998     NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
1999     let filtbuf= bufnr("%")
2000     setl ff=unix
2001     NetrwKeepj put =g:netrw_ftpmode
2002"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2003     if exists("g:netrw_ftpextracmd")
2004      NetrwKeepj put =g:netrw_ftpextracmd
2005"      call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2006     endif
2007     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2008"     call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2009     if exists("g:netrw_port") && g:netrw_port != ""
2010      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2011     else
2012      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2013     endif
2014     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2015     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2016      let debugkeep = &debug
2017      setl debug=msg
2018      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2019      let &debug    = debugkeep
2020     endif
2021     call s:SaveBufVars()
2022     keepj bd!
2023     if bufname("%") == "" && getline("$") == "" && line('$') == 1
2024      " needed when one sources a file in a nolbl setting window via ftp
2025      q!
2026     endif
2027     call s:RestoreBufVars()
2028     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2029     let b:netrw_lastfile = choice
2030
2031   ".........................................
2032   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
2033   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
2034    " Construct execution string (four lines) which will be passed through filter
2035"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2036    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2037    NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2038    let filtbuf= bufnr("%")
2039    setl ff=unix
2040    if exists("g:netrw_port") && g:netrw_port != ""
2041     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2042"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2043    else
2044     NetrwKeepj put ='open '.g:netrw_machine
2045"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2046    endif
2047
2048    if exists("g:netrw_uid") && g:netrw_uid != ""
2049     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2050      NetrwKeepj put =g:netrw_uid
2051"       call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2052      if exists("s:netrw_passwd")
2053       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2054      endif
2055"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2056     elseif exists("s:netrw_passwd")
2057      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2058"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2059     endif
2060    endif
2061
2062    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2063     NetrwKeepj put =g:netrw_ftpmode
2064"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2065    endif
2066    if exists("g:netrw_ftpextracmd")
2067     NetrwKeepj put =g:netrw_ftpextracmd
2068"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2069    endif
2070    NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2071"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2072
2073    " perform ftp:
2074    " -i       : turns off interactive prompting from ftp
2075    " -n  unix : DON'T use <.netrc>, even though it exists
2076    " -n  win32: quit being obnoxious about password
2077    NetrwKeepj norm! 1Gdd
2078    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2079    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2080    if getline(1) !~ "^$"
2081"     call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2082     if !exists("g:netrw_quiet")
2083      call netrw#ErrorMsg(s:ERROR,getline(1),5)
2084     endif
2085    endif
2086    call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2087    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2088    let b:netrw_lastfile = choice
2089
2090   ".........................................
2091   " NetRead: (scp) NetRead Method #4 {{{3
2092   elseif     b:netrw_method  == 4	" read with scp
2093"    call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2094    if exists("g:netrw_port") && g:netrw_port != ""
2095     let useport= " ".g:netrw_scpport." ".g:netrw_port
2096    else
2097     let useport= ""
2098    endif
2099    " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2100    " This is workaround to avoid mis-handle windows local-path:
2101    if g:netrw_scp_cmd =~ '^scp' && (has("win32") || has("win95") || has("win64") || has("win16"))
2102      let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2103    else
2104      let tmpfile_get = tmpfile
2105    endif
2106    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile_get,1))
2107    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2108    let b:netrw_lastfile = choice
2109
2110   ".........................................
2111   " NetRead: (http) NetRead Method #5 (wget) {{{3
2112   elseif     b:netrw_method  == 5
2113"    call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2114    if g:netrw_http_cmd == ""
2115     if !exists("g:netrw_quiet")
2116      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2117     endif
2118"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2119     return
2120    endif
2121
2122    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2123     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2124"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2125     if exists("g:netrw_http_xcmd")
2126      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))
2127     else
2128      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))
2129     endif
2130     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2131
2132    else
2133     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2134"     call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2135     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2136     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2137"     call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2138"     call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2139     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))
2140     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2141"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2142     exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2143    endif
2144    let b:netrw_lastfile = choice
2145"    call Decho("setl ro",'~'.expand("<slnum>"))
2146    setl ro nomod
2147
2148   ".........................................
2149   " NetRead: (dav) NetRead Method #6 {{{3
2150   elseif     b:netrw_method  == 6
2151"    call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2152
2153    if !executable(g:netrw_dav_cmd)
2154     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2155"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2156     return
2157    endif
2158    if g:netrw_dav_cmd =~ "curl"
2159     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2160    else
2161     " Construct execution string (four lines) which will be passed through filter
2162     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2163     new
2164     setl ff=unix
2165     if exists("g:netrw_port") && g:netrw_port != ""
2166      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2167     else
2168      NetrwKeepj put ='open '.g:netrw_machine
2169     endif
2170     if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2171      NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2172     endif
2173     NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2174     NetrwKeepj put ='quit'
2175
2176     " perform cadaver operation:
2177     NetrwKeepj norm! 1Gdd
2178     call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2179     keepj bd!
2180    endif
2181    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2182    let b:netrw_lastfile = choice
2183
2184   ".........................................
2185   " NetRead: (rsync) NetRead Method #7 {{{3
2186   elseif     b:netrw_method  == 7
2187"    call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2188    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2189    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2190    let b:netrw_lastfile = choice
2191
2192   ".........................................
2193   " NetRead: (fetch) NetRead Method #8 {{{3
2194   "    fetch://[user@]host[:http]/path
2195   elseif     b:netrw_method  == 8
2196"    call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2197    if g:netrw_fetch_cmd == ""
2198     if !exists("g:netrw_quiet")
2199      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2200     endif
2201"     call Dret("NetRead")
2202     return
2203    endif
2204    if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2205     let netrw_option= "http"
2206    else
2207     let netrw_option= "ftp"
2208    endif
2209"    call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2210
2211    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2212     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))
2213    else
2214     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))
2215    endif
2216
2217    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2218    let b:netrw_lastfile = choice
2219"    call Decho("setl ro",'~'.expand("<slnum>"))
2220    setl ro nomod
2221
2222   ".........................................
2223   " NetRead: (sftp) NetRead Method #9 {{{3
2224   elseif     b:netrw_method  == 9
2225"    call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2226    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2227    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2228    let b:netrw_lastfile = choice
2229
2230   ".........................................
2231   " NetRead: (file) NetRead Method #10 {{{3
2232  elseif      b:netrw_method == 10 && exists("g:netrw_file_cmd")
2233"   "    call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2234   call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2235   let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2236   let b:netrw_lastfile = choice
2237
2238   ".........................................
2239   " NetRead: Complain {{{3
2240   else
2241    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
2242   endif
2243  endwhile
2244
2245  " NetRead: cleanup {{{3
2246  if exists("b:netrw_method")
2247"   call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2248   unlet b:netrw_method
2249   unlet b:netrw_fname
2250  endif
2251  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
2252"   call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2253   NetrwKeepj call s:NetrwDelete(tmpfile)
2254  endif
2255  NetrwKeepj call s:NetrwOptionRestore("w:")
2256
2257"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
2258endfun
2259
2260" ------------------------------------------------------------------------
2261" netrw#NetWrite: responsible for writing a file over the net {{{2
2262fun! netrw#NetWrite(...) range
2263"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
2264
2265  " NetWrite: option handling {{{3
2266  let mod= 0
2267  call s:NetrwOptionSave("w:")
2268  call s:NetrwSafeOptions()
2269
2270  " NetWrite: Get Temporary Filename {{{3
2271  let tmpfile= s:GetTempfile("")
2272  if tmpfile == ""
2273"   call Dret("netrw#NetWrite : unable to get a tempfile!")
2274   return
2275  endif
2276
2277  if a:0 == 0
2278   let ichoice = 0
2279  else
2280   let ichoice = 1
2281  endif
2282
2283  let curbufname= expand("%")
2284"  call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
2285  if &binary
2286   " For binary writes, always write entire file.
2287   " (line numbers don't really make sense for that).
2288   " Also supports the writing of tar and zip files.
2289"   call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2290   exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2291  elseif g:netrw_cygwin
2292   " write (selected portion of) file to temporary
2293   let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2294"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2295   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
2296  else
2297   " write (selected portion of) file to temporary
2298"   call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2299   exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
2300  endif
2301
2302  if curbufname == ""
2303   " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2304   " on the temporary file's name.  Deletion of the temporary file during
2305   " cleanup then causes an error message.
2306   0file!
2307  endif
2308
2309  " NetWrite: while choice loop: {{{3
2310  while ichoice <= a:0
2311
2312   " Process arguments: {{{4
2313   " attempt to repeat with previous host-file-etc
2314   if exists("b:netrw_lastfile") && a:0 == 0
2315"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2316    let choice = b:netrw_lastfile
2317    let ichoice= ichoice + 1
2318   else
2319    exe "let choice= a:" . ichoice
2320
2321    " Reconstruct Choice when choice starts with '"'
2322    if match(choice,"?") == 0
2323     echomsg 'NetWrite Usage:"'
2324     echomsg ':Nwrite machine:path                        uses rcp'
2325     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
2326     echomsg ':Nwrite "machine id password path"          uses ftp'
2327     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
2328     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
2329     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
2330     echomsg ':Nwrite rcp://machine/path                  uses rcp'
2331     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
2332     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2333     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
2334     sleep 4
2335     break
2336
2337    elseif match(choice,"^\"") != -1
2338     if match(choice,"\"$") != -1
2339       " case "..."
2340      let choice=strpart(choice,1,strlen(choice)-2)
2341     else
2342      "  case "... ... ..."
2343      let choice      = strpart(choice,1,strlen(choice)-1)
2344      let wholechoice = ""
2345
2346      while match(choice,"\"$") == -1
2347       let wholechoice= wholechoice . " " . choice
2348       let ichoice    = ichoice + 1
2349       if choice > a:0
2350       	if !exists("g:netrw_quiet")
2351	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2352	endif
2353"        call Dret("netrw#NetWrite")
2354        return
2355       endif
2356       let choice= a:{ichoice}
2357      endwhile
2358      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2359     endif
2360    endif
2361   endif
2362   let ichoice= ichoice + 1
2363"   call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
2364
2365   " Determine method of write (ftp, rcp, etc) {{{4
2366   NetrwKeepj call s:NetrwMethod(choice)
2367   if !exists("b:netrw_method") || b:netrw_method < 0
2368"    call Dfunc("netrw#NetWrite : unsupported method")
2369    return
2370   endif
2371
2372   " =============
2373   " NetWrite: Perform Protocol-Based Write {{{3
2374   " ============================
2375   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2376    echo "(netrw) Processing your write request..."
2377"    call Decho("(netrw) Processing your write request...",'~'.expand("<slnum>"))
2378   endif
2379
2380   ".........................................
2381   " NetWrite: (rcp) NetWrite Method #1 {{{3
2382   if  b:netrw_method == 1
2383"    call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2384    if s:netrw_has_nt_rcp == 1
2385     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2386      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2387     else
2388      let uid_machine = g:netrw_machine .'.'. $USERNAME
2389     endif
2390    else
2391     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2392      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2393     else
2394      let uid_machine = g:netrw_machine
2395     endif
2396    endif
2397    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))
2398    let b:netrw_lastfile = choice
2399
2400   ".........................................
2401   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2402   elseif b:netrw_method == 2
2403"    call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2404    let netrw_fname = b:netrw_fname
2405
2406    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2407    let bhkeep      = &l:bh
2408    let curbuf      = bufnr("%")
2409    setl bh=hide
2410    keepj keepalt enew
2411
2412"    call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2413    setl ff=unix
2414    NetrwKeepj put =g:netrw_ftpmode
2415"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2416    if exists("g:netrw_ftpextracmd")
2417     NetrwKeepj put =g:netrw_ftpextracmd
2418"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2419    endif
2420    NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2421"    call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2422    if exists("g:netrw_port") && g:netrw_port != ""
2423     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2424    else
2425"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2426     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2427    endif
2428    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2429    if getline(1) !~ "^$"
2430     if !exists("g:netrw_quiet")
2431      NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2432     endif
2433     let mod=1
2434    endif
2435
2436    " remove enew buffer (quietly)
2437    let filtbuf= bufnr("%")
2438    exe curbuf."b!"
2439    let &l:bh            = bhkeep
2440    exe filtbuf."bw!"
2441
2442    let b:netrw_lastfile = choice
2443
2444   ".........................................
2445   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2446   elseif b:netrw_method == 3
2447    " Construct execution string (three or more lines) which will be passed through filter
2448"    call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2449    let netrw_fname = b:netrw_fname
2450    let bhkeep      = &l:bh
2451
2452    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2453    let curbuf      = bufnr("%")
2454    setl bh=hide
2455    keepj keepalt enew
2456    setl ff=unix
2457
2458    if exists("g:netrw_port") && g:netrw_port != ""
2459     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2460"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2461    else
2462     NetrwKeepj put ='open '.g:netrw_machine
2463"     call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2464    endif
2465    if exists("g:netrw_uid") && g:netrw_uid != ""
2466     if exists("g:netrw_ftp") && g:netrw_ftp == 1
2467      NetrwKeepj put =g:netrw_uid
2468"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2469      if exists("s:netrw_passwd") && s:netrw_passwd != ""
2470       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2471      endif
2472"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2473     elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2474      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2475"      call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2476     endif
2477    endif
2478    NetrwKeepj put =g:netrw_ftpmode
2479"    call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2480    if exists("g:netrw_ftpextracmd")
2481     NetrwKeepj put =g:netrw_ftpextracmd
2482"     call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2483    endif
2484    NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2485"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2486    " save choice/id/password for future use
2487    let b:netrw_lastfile = choice
2488
2489    " perform ftp:
2490    " -i       : turns off interactive prompting from ftp
2491    " -n  unix : DON'T use <.netrc>, even though it exists
2492    " -n  win32: quit being obnoxious about password
2493    NetrwKeepj norm! 1Gdd
2494    call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2495    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2496    if getline(1) !~ "^$"
2497     if  !exists("g:netrw_quiet")
2498      call netrw#ErrorMsg(s:ERROR,getline(1),15)
2499     endif
2500     let mod=1
2501    endif
2502
2503    " remove enew buffer (quietly)
2504    let filtbuf= bufnr("%")
2505    exe curbuf."b!"
2506    let &l:bh= bhkeep
2507    exe filtbuf."bw!"
2508
2509   ".........................................
2510   " NetWrite: (scp) NetWrite Method #4 {{{3
2511   elseif     b:netrw_method == 4
2512"    call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2513    if exists("g:netrw_port") && g:netrw_port != ""
2514     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2515    else
2516     let useport= ""
2517    endif
2518    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2519    let b:netrw_lastfile = choice
2520
2521   ".........................................
2522   " NetWrite: (http) NetWrite Method #5 {{{3
2523   elseif     b:netrw_method == 5
2524"    call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2525    let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2526    if executable(curl)
2527     let url= g:netrw_choice
2528     call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2529    elseif !exists("g:netrw_quiet")
2530     call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd".">".",16)
2531    endif
2532
2533   ".........................................
2534   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2535   elseif     b:netrw_method == 6
2536"    call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2537
2538    " Construct execution string (four lines) which will be passed through filter
2539    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2540    let bhkeep      = &l:bh
2541
2542    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2543    let curbuf      = bufnr("%")
2544    setl bh=hide
2545    keepj keepalt enew
2546
2547    setl ff=unix
2548    if exists("g:netrw_port") && g:netrw_port != ""
2549     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2550    else
2551     NetrwKeepj put ='open '.g:netrw_machine
2552    endif
2553    if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2554     NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2555    endif
2556    NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2557
2558    " perform cadaver operation:
2559    NetrwKeepj norm! 1Gdd
2560    call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2561
2562    " remove enew buffer (quietly)
2563    let filtbuf= bufnr("%")
2564    exe curbuf."b!"
2565    let &l:bh            = bhkeep
2566    exe filtbuf."bw!"
2567
2568    let b:netrw_lastfile = choice
2569
2570   ".........................................
2571   " NetWrite: (rsync) NetWrite Method #7 {{{3
2572   elseif     b:netrw_method == 7
2573"    call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2574    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2575    let b:netrw_lastfile = choice
2576
2577   ".........................................
2578   " NetWrite: (sftp) NetWrite Method #9 {{{3
2579   elseif     b:netrw_method == 9
2580"    call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2581    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2582    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
2583     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2584    else
2585     let uid_machine = g:netrw_machine
2586    endif
2587
2588    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
2589    let bhkeep = &l:bh
2590    let curbuf = bufnr("%")
2591    setl bh=hide
2592    keepj keepalt enew
2593
2594    setl ff=unix
2595    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2596"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2597    let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2598    call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2599    let filtbuf= bufnr("%")
2600    exe curbuf."b!"
2601    let &l:bh            = bhkeep
2602    exe filtbuf."bw!"
2603    let b:netrw_lastfile = choice
2604
2605   ".........................................
2606   " NetWrite: Complain {{{3
2607   else
2608    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2609    let leavemod= 1
2610   endif
2611  endwhile
2612
2613  " NetWrite: Cleanup: {{{3
2614"  call Decho("cleanup",'~'.expand("<slnum>"))
2615  if s:FileReadable(tmpfile)
2616"   call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2617   call s:NetrwDelete(tmpfile)
2618  endif
2619  call s:NetrwOptionRestore("w:")
2620
2621  if a:firstline == 1 && a:lastline == line("$")
2622   " restore modifiability; usually equivalent to set nomod
2623   let &mod= mod
2624"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2625  elseif !exists("leavemod")
2626   " indicate that the buffer has not been modified since last written
2627"   call Decho("set nomod",'~'.expand("<slnum>"))
2628   setl nomod
2629"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2630  endif
2631
2632"  call Dret("netrw#NetWrite")
2633endfun
2634
2635" ---------------------------------------------------------------------
2636" netrw#NetSource: source a remotely hosted vim script {{{2
2637" uses NetRead to get a copy of the file into a temporarily file,
2638"              then sources that file,
2639"              then removes that file.
2640fun! netrw#NetSource(...)
2641"  call Dfunc("netrw#NetSource() a:0=".a:0)
2642  if a:0 > 0 && a:1 == '?'
2643   " give help
2644   echomsg 'NetSource Usage:'
2645   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
2646   echomsg ':Nsource fetch://machine/path                 uses fetch'
2647   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
2648   echomsg ':Nsource http[s]://[user@]machine/path        uses http  wget'
2649   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
2650   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
2651   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
2652   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2653   sleep 4
2654  else
2655   let i= 1
2656   while i <= a:0
2657    call netrw#NetRead(3,a:{i})
2658"    call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2659    if s:FileReadable(s:netrw_tmpfile)
2660"     call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2661     exe "so ".fnameescape(s:netrw_tmpfile)
2662"     call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2663     if delete(s:netrw_tmpfile)
2664      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2665     endif
2666     unlet s:netrw_tmpfile
2667    else
2668     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2669    endif
2670    let i= i + 1
2671   endwhile
2672  endif
2673"  call Dret("netrw#NetSource")
2674endfun
2675
2676" ---------------------------------------------------------------------
2677" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2678"                   (implements the :Ntree command)
2679fun! netrw#SetTreetop(...)
2680"  call Dfunc("netrw#SetTreetop(".((a:0 > 0)? a:1 : "").") a:0=".a:0)
2681
2682  " clear out the current tree
2683  if exists("w:netrw_treetop")
2684"   call Decho("clearing out current tree",'~'.expand("<slnum>"))
2685   let inittreetop= w:netrw_treetop
2686   unlet w:netrw_treetop
2687  endif
2688  if exists("w:netrw_treedict")
2689"   call Decho("freeing w:netrw_treedict",'~'.expand("<slnum>"))
2690   unlet w:netrw_treedict
2691  endif
2692
2693  if a:1 == "" && exists("inittreetop")
2694   let treedir= s:NetrwTreePath(inittreetop)
2695"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2696  else
2697   if isdirectory(s:NetrwFile(a:1))
2698"    call Decho("a:1<".a:1."> is a directory",'~'.expand("<slnum>"))
2699    let treedir= a:1
2700   elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2701    let treedir= b:netrw_curdir."/".a:1
2702"    call Decho("a:1<".a:1."> is NOT a directory, trying treedir<".treedir.">",'~'.expand("<slnum>"))
2703   else
2704    " normally the cursor is left in the message window.
2705    " However, here this results in the directory being listed in the message window, which is not wanted.
2706    let netrwbuf= bufnr("%")
2707    call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2708    exe bufwinnr(netrwbuf)."wincmd w"
2709    let treedir= "."
2710   endif
2711  endif
2712"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
2713  let islocal= expand("%") !~ '^\a\{3,}://'
2714"  call Decho("islocal=".islocal,'~'.expand("<slnum>"))
2715  if islocal
2716   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir))
2717  else
2718   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir))
2719  endif
2720"  call Dret("netrw#SetTreetop")
2721endfun
2722
2723" ===========================================
2724" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
2725"    readcmd == %r : replace buffer with newly read file
2726"            == 0r : read file at top of buffer
2727"            == r  : read file after current line
2728"            == t  : leave file in temporary form (ie. don't read into buffer)
2729fun! s:NetrwGetFile(readcmd, tfile, method)
2730"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
2731
2732  " readcmd=='t': simply do nothing
2733  if a:readcmd == 't'
2734"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2735"   call Dret("NetrwGetFile : skip read of <".a:tfile.">")
2736   return
2737  endif
2738
2739  " get name of remote filename (ie. url and all)
2740  let rfile= bufname("%")
2741"  call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
2742
2743  if exists("*NetReadFixup")
2744   " for the use of NetReadFixup (not otherwise used internally)
2745   let line2= line("$")
2746  endif
2747
2748  if a:readcmd[0] == '%'
2749  " get file into buffer
2750"   call Decho("get file into buffer",'~'.expand("<slnum>"))
2751
2752   " rename the current buffer to the temp file (ie. tfile)
2753   if g:netrw_cygwin
2754    let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2755   else
2756    let tfile= a:tfile
2757   endif
2758"   call Decho("exe sil! keepalt file ".fnameescape(tfile),'~'.expand("<slnum>"))
2759   exe "sil! keepalt file ".fnameescape(tfile)
2760
2761   " edit temporary file (ie. read the temporary file in)
2762   if     rfile =~ '\.zip$'
2763"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2764    call zip#Browse(tfile)
2765   elseif rfile =~ '\.tar$'
2766"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2767    call tar#Browse(tfile)
2768   elseif rfile =~ '\.tar\.gz$'
2769"    call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2770    call tar#Browse(tfile)
2771   elseif rfile =~ '\.tar\.bz2$'
2772"    call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2773    call tar#Browse(tfile)
2774   elseif rfile =~ '\.tar\.xz$'
2775"    call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2776    call tar#Browse(tfile)
2777   elseif rfile =~ '\.txz$'
2778"    call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2779    call tar#Browse(tfile)
2780   else
2781"    call Decho("edit temporary file",'~'.expand("<slnum>"))
2782    NetrwKeepj e!
2783   endif
2784
2785   " rename buffer back to remote filename
2786"   call Decho("exe sil! keepalt file ".fnameescape(rfile),'~'.expand("<slnum>"))
2787   exe "sil! NetrwKeepj keepalt file ".fnameescape(rfile)
2788
2789   " Detect filetype of local version of remote file.
2790   " Note that isk must not include a "/" for scripts.vim
2791   " to process this detection correctly.
2792"   call Decho("detect filetype of local version of remote file",'~'.expand("<slnum>"))
2793   let iskkeep= &l:isk
2794   setl isk-=/
2795   let &l:isk= iskkeep
2796"   call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!")
2797   let line1 = 1
2798   let line2 = line("$")
2799
2800  elseif !&ma
2801   " attempting to read a file after the current line in the file, but the buffer is not modifiable
2802   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2803"   call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2804   return
2805
2806  elseif s:FileReadable(a:tfile)
2807   " read file after current line
2808"   call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2809   let curline = line(".")
2810   let lastline= line("$")
2811"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline,'~'.expand("<slnum>"))
2812   exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2813   let line1= curline + 1
2814   let line2= line("$") - lastline + 1
2815
2816  else
2817   " not readable
2818"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2819"   call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2820   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2821"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2822   return
2823  endif
2824
2825  " User-provided (ie. optional) fix-it-up command
2826  if exists("*NetReadFixup")
2827"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2828   NetrwKeepj call NetReadFixup(a:method, line1, line2)
2829"  else " Decho
2830"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2831  endif
2832
2833  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
2834   " update the Buffers menu
2835   NetrwKeepj call s:UpdateBuffersMenu()
2836  endif
2837
2838"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
2839
2840 " make sure file is being displayed
2841"  redraw!
2842
2843"  call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2844"  call Dret("NetrwGetFile")
2845endfun
2846
2847" ------------------------------------------------------------------------
2848" s:NetrwMethod:  determine method of transfer {{{2
2849" Input:
2850"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
2851" Output:
2852"  b:netrw_method= 1: rcp
2853"                  2: ftp + <.netrc>
2854"	           3: ftp + machine, id, password, and [path]filename
2855"	           4: scp
2856"	           5: http[s] (wget)
2857"	           6: dav
2858"	           7: rsync
2859"	           8: fetch
2860"	           9: sftp
2861"	          10: file
2862"  g:netrw_machine= hostname
2863"  b:netrw_fname  = filename
2864"  g:netrw_port   = optional port number (for ftp)
2865"  g:netrw_choice = copy of input url (choice)
2866fun! s:NetrwMethod(choice)
2867"   call Dfunc("NetrwMethod(a:choice<".a:choice.">)")
2868
2869   " sanity check: choice should have at least three slashes in it
2870   if strlen(substitute(a:choice,'[^/]','','g')) < 3
2871    call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
2872    let b:netrw_method = -1
2873"    call Dret("NetrwMethod : incorrect url format<".a:choice.">")
2874    return
2875   endif
2876
2877   " record current g:netrw_machine, if any
2878   " curmachine used if protocol == ftp and no .netrc
2879   if exists("g:netrw_machine")
2880    let curmachine= g:netrw_machine
2881"    call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
2882   else
2883    let curmachine= "N O T A HOST"
2884   endif
2885   if exists("g:netrw_port")
2886    let netrw_port= g:netrw_port
2887   endif
2888
2889   " insure that netrw_ftp_cmd starts off every method determination
2890   " with the current g:netrw_ftp_cmd
2891   let s:netrw_ftp_cmd= g:netrw_ftp_cmd
2892
2893  " initialization
2894  let b:netrw_method  = 0
2895  let g:netrw_machine = ""
2896  let b:netrw_fname   = ""
2897  let g:netrw_port    = ""
2898  let g:netrw_choice  = a:choice
2899
2900  " Patterns:
2901  " mipf     : a:machine a:id password filename	     Use ftp
2902  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
2903  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
2904  " rcpurm   : rcp://[user@]host/filename	     Use rcp
2905  " rcphf    : [user@]host:filename		     Use rcp
2906  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
2907  " httpurm  : http[s]://[user@]host/filename	     Use wget
2908  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
2909  " rsyncurm : rsync://host[:port]/path              Use rsync
2910  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
2911  " sftpurm  : sftp://[user@]host/filename  Use scp
2912  " fileurm  : file://[user@]host/filename	     Use elinks or links
2913  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
2914  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
2915  let ftpurm   = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
2916  let rcpurm   = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
2917  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
2918  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
2919  let httpurm  = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
2920  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
2921  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
2922  let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
2923  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
2924  let fileurm  = '^file\=://\(.*\)$'
2925
2926"  call Decho("determine method:",'~'.expand("<slnum>"))
2927  " Determine Method
2928  " Method#1: rcp://user@hostname/...path-to-file {{{3
2929  if match(a:choice,rcpurm) == 0
2930"   call Decho("rcp://...",'~'.expand("<slnum>"))
2931   let b:netrw_method  = 1
2932   let userid          = substitute(a:choice,rcpurm,'\1',"")
2933   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
2934   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
2935   if userid != ""
2936    let g:netrw_uid= userid
2937   endif
2938
2939  " Method#4: scp://user@hostname/...path-to-file {{{3
2940  elseif match(a:choice,scpurm) == 0
2941"   call Decho("scp://...",'~'.expand("<slnum>"))
2942   let b:netrw_method  = 4
2943   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
2944   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
2945   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
2946
2947  " Method#5: http[s]://user@hostname/...path-to-file {{{3
2948  elseif match(a:choice,httpurm) == 0
2949"   call Decho("http[s]://...",'~'.expand("<slnum>"))
2950   let b:netrw_method = 5
2951   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
2952   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
2953   let b:netrw_http   = (a:choice =~ '^https:')? "https" : "http"
2954
2955  " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
2956  elseif match(a:choice,davurm) == 0
2957"   call Decho("dav://...",'~'.expand("<slnum>"))
2958   let b:netrw_method= 6
2959   if a:choice =~ 'davs:'
2960    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
2961   else
2962    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
2963   endif
2964   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
2965
2966   " Method#7: rsync://user@hostname/...path-to-file {{{3
2967  elseif match(a:choice,rsyncurm) == 0
2968"   call Decho("rsync://...",'~'.expand("<slnum>"))
2969   let b:netrw_method = 7
2970   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
2971   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
2972
2973   " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
2974  elseif match(a:choice,ftpurm) == 0
2975"   call Decho("ftp://...",'~'.expand("<slnum>"))
2976   let userid	      = substitute(a:choice,ftpurm,'\2',"")
2977   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
2978   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
2979   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
2980"   call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
2981   if userid != ""
2982    let g:netrw_uid= userid
2983   endif
2984
2985   if curmachine != g:netrw_machine
2986    if exists("s:netwr_hup[".g:netrw_machine."]")
2987     call NetUserPass("ftp:".g:netrw_machine)
2988    elseif exists("s:netrw_passwd")
2989     " if there's a change in hostname, require password re-entry
2990     unlet s:netrw_passwd
2991    endif
2992    if exists("netrw_port")
2993     unlet netrw_port
2994    endif
2995   endif
2996
2997   if exists("g:netrw_uid") && exists("s:netrw_passwd")
2998    let b:netrw_method = 3
2999   else
3000    let host= substitute(g:netrw_machine,'\..*$','','')
3001    if exists("s:netrw_hup[host]")
3002     call NetUserPass("ftp:".host)
3003
3004    elseif (has("win32") || has("win95") || has("win64") || has("win16")) && s:netrw_ftp_cmd =~# '-[sS]:'
3005"     call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3006"     call Decho("          g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3007     if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
3008      let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3009"      call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3010     endif
3011     let b:netrw_method= 2
3012    elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3013"     call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3014     let b:netrw_method= 2
3015    else
3016     if !exists("g:netrw_uid") || g:netrw_uid == ""
3017      call NetUserPass()
3018     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3019      call NetUserPass(g:netrw_uid)
3020    " else just use current g:netrw_uid and s:netrw_passwd
3021     endif
3022     let b:netrw_method= 3
3023    endif
3024   endif
3025
3026  " Method#8: fetch {{{3
3027  elseif match(a:choice,fetchurm) == 0
3028"   call Decho("fetch://...",'~'.expand("<slnum>"))
3029   let b:netrw_method = 8
3030   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3031   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3032   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3033   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
3034
3035   " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
3036  elseif match(a:choice,mipf) == 0
3037"   call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
3038   let b:netrw_method  = 3
3039   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3040   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
3041   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
3042   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
3043   call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
3044
3045  " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3046  elseif match(a:choice,mf) == 0
3047"   call Decho("(ftp) host file",'~'.expand("<slnum>"))
3048   if exists("g:netrw_uid") && exists("s:netrw_passwd")
3049    let b:netrw_method  = 3
3050    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3051    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3052
3053   elseif s:FileReadable(expand("$HOME/.netrc"))
3054    let b:netrw_method  = 2
3055    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3056    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
3057   endif
3058
3059  " Method#9: sftp://user@hostname/...path-to-file {{{3
3060  elseif match(a:choice,sftpurm) == 0
3061"   call Decho("sftp://...",'~'.expand("<slnum>"))
3062   let b:netrw_method = 9
3063   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3064   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
3065
3066  " Method#1: Issue an rcp: hostname:filename"  (this one should be last) {{{3
3067  elseif match(a:choice,rcphf) == 0
3068"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3069   let b:netrw_method  = 1
3070   let userid          = substitute(a:choice,rcphf,'\2',"")
3071   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3072   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
3073"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3074"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3075"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3076"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3077   if userid != ""
3078    let g:netrw_uid= userid
3079   endif
3080
3081   " Method#10: file://user@hostname/...path-to-file {{{3
3082  elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
3083"   call Decho("http[s]://...",'~'.expand("<slnum>"))
3084   let b:netrw_method = 10
3085   let b:netrw_fname  = substitute(a:choice,fileurm,'\1',"")
3086"   call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
3087
3088  " Cannot Determine Method {{{3
3089  else
3090   if !exists("g:netrw_quiet")
3091    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3092   endif
3093   let b:netrw_method  = -1
3094  endif
3095  "}}}3
3096
3097  if g:netrw_port != ""
3098   " remove any leading [:#] from port number
3099   let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
3100  elseif exists("netrw_port")
3101   " retain port number as implicit for subsequent ftp operations
3102   let g:netrw_port= netrw_port
3103  endif
3104
3105"  call Decho("a:choice       <".a:choice.">",'~'.expand("<slnum>"))
3106"  call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3107"  call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3108"  call Decho("g:netrw_port   <".g:netrw_port.">",'~'.expand("<slnum>"))
3109"  if exists("g:netrw_uid")		"Decho
3110"   call Decho("g:netrw_uid    <".g:netrw_uid.">",'~'.expand("<slnum>"))
3111"  endif					"Decho
3112"  if exists("s:netrw_passwd")		"Decho
3113"   call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3114"  endif					"Decho
3115"  call Decho("b:netrw_fname  <".b:netrw_fname.">",'~'.expand("<slnum>"))
3116"  call Dret("NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
3117endfun
3118
3119" ------------------------------------------------------------------------
3120" NetReadFixup: this sort of function is typically written by the user {{{2
3121"               to handle extra junk that their system's ftp dumps
3122"               into the transfer.  This function is provided as an
3123"               example and as a fix for a Windows 95 problem: in my
3124"               experience, win95's ftp always dumped four blank lines
3125"               at the end of the transfer.
3126if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
3127 fun! NetReadFixup(method, line1, line2)
3128"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
3129
3130   " sanity checks -- attempt to convert inputs to integers
3131   let method = a:method + 0
3132   let line1  = a:line1 + 0
3133   let line2  = a:line2 + 0
3134   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
3135"    call Dret("NetReadFixup")
3136    return
3137   endif
3138
3139   if method == 3   " ftp (no <.netrc>)
3140    let fourblanklines= line2 - 3
3141    if fourblanklines >= line1
3142     exe "sil NetrwKeepj ".fourblanklines.",".line2."g/^\s*$/d"
3143     call histdel("/",-1)
3144    endif
3145   endif
3146
3147"   call Dret("NetReadFixup")
3148 endfun
3149endif
3150
3151" ---------------------------------------------------------------------
3152" NetUserPass: set username and password for subsequent ftp transfer {{{2
3153"   Usage:  :call NetUserPass()		               -- will prompt for userid and password
3154"	    :call NetUserPass("uid")	               -- will prompt for password
3155"	    :call NetUserPass("uid","password")        -- sets global userid and password
3156"	    :call NetUserPass("ftp:host")              -- looks up userid and password using hup dictionary
3157"	    :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
3158fun! NetUserPass(...)
3159
3160" call Dfunc("NetUserPass() a:0=".a:0)
3161
3162 if !exists('s:netrw_hup')
3163  let s:netrw_hup= {}
3164 endif
3165
3166 if a:0 == 0
3167  " case: no input arguments
3168
3169  " change host and username if not previously entered; get new password
3170  if !exists("g:netrw_machine")
3171   let g:netrw_machine= input('Enter hostname: ')
3172  endif
3173  if !exists("g:netrw_uid") || g:netrw_uid == ""
3174   " get username (user-id) via prompt
3175   let g:netrw_uid= input('Enter username: ')
3176  endif
3177  " get password via prompting
3178  let s:netrw_passwd= inputsecret("Enter Password: ")
3179
3180  " set up hup database
3181  let host = substitute(g:netrw_machine,'\..*$','','')
3182  if !exists('s:netrw_hup[host]')
3183   let s:netrw_hup[host]= {}
3184  endif
3185  let s:netrw_hup[host].uid    = g:netrw_uid
3186  let s:netrw_hup[host].passwd = s:netrw_passwd
3187
3188 elseif a:0 == 1
3189  " case: one input argument
3190
3191  if a:1 =~ '^ftp:'
3192   " get host from ftp:... url
3193   " access userid and password from hup (host-user-passwd) dictionary
3194"   call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3195   let host = substitute(a:1,'^ftp:','','')
3196   let host = substitute(host,'\..*','','')
3197   if exists("s:netrw_hup[host]")
3198    let g:netrw_uid    = s:netrw_hup[host].uid
3199    let s:netrw_passwd = s:netrw_hup[host].passwd
3200"    call Decho("get s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3201"    call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3202   else
3203    let g:netrw_uid    = input("Enter UserId: ")
3204    let s:netrw_passwd = inputsecret("Enter Password: ")
3205   endif
3206
3207  else
3208   " case: one input argument, not an url.  Using it as a new user-id.
3209"   call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3210   if exists("g:netrw_machine")
3211    if g:netrw_machine =~ '[0-9.]\+'
3212     let host= g:netrw_machine
3213    else
3214     let host= substitute(g:netrw_machine,'\..*$','','')
3215    endif
3216   else
3217    let g:netrw_machine= input('Enter hostname: ')
3218   endif
3219   let g:netrw_uid = a:1
3220"   call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3221   if exists("g:netrw_passwd")
3222    " ask for password if one not previously entered
3223    let s:netrw_passwd= g:netrw_passwd
3224   else
3225    let s:netrw_passwd = inputsecret("Enter Password: ")
3226   endif
3227  endif
3228
3229"  call Decho("host<".host.">",'~'.expand("<slnum>"))
3230  if exists("host")
3231   if !exists('s:netrw_hup[host]')
3232    let s:netrw_hup[host]= {}
3233   endif
3234   let s:netrw_hup[host].uid    = g:netrw_uid
3235   let s:netrw_hup[host].passwd = s:netrw_passwd
3236  endif
3237
3238 elseif a:0 == 2
3239  let g:netrw_uid    = a:1
3240  let s:netrw_passwd = a:2
3241
3242 elseif a:0 == 3
3243  " enter hostname, user-id, and password into the hup dictionary
3244  let host = substitute(a:1,'^\a\+:','','')
3245  let host = substitute(host,'\..*$','','')
3246  if !exists('s:netrw_hup[host]')
3247   let s:netrw_hup[host]= {}
3248  endif
3249  let s:netrw_hup[host].uid    = a:2
3250  let s:netrw_hup[host].passwd = a:3
3251  let g:netrw_uid              = s:netrw_hup[host].uid
3252  let s:netrw_passwd           = s:netrw_hup[host].passwd
3253"  call Decho("set s:netrw_hup[".host."].uid   <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3254"  call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3255 endif
3256
3257" call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
3258endfun
3259
3260" ===========================================
3261"  Shared Browsing Support:    {{{1
3262" ===========================================
3263
3264" ---------------------------------------------------------------------
3265" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3266fun! s:ExplorePatHls(pattern)
3267"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
3268  let repat= substitute(a:pattern,'^**/\{1,2}','','')
3269"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3270  let repat= escape(repat,'][.\')
3271"  call Decho("repat<".repat.">",'~'.expand("<slnum>"))
3272  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
3273"  call Dret("s:ExplorePatHls repat<".repat.">")
3274  return repat
3275endfun
3276
3277" ---------------------------------------------------------------------
3278"  s:NetrwBookHistHandler: {{{2
3279"    0: (user: <mb>)   bookmark current directory
3280"    1: (user: <gb>)   change to the bookmarked directory
3281"    2: (user: <qb>)   list bookmarks
3282"    3: (browsing)     records current directory history
3283"    4: (user: <u>)    go up   (previous) directory, using history
3284"    5: (user: <U>)    go down (next)     directory, using history
3285"    6: (user: <mB>)   delete bookmark
3286fun! s:NetrwBookHistHandler(chg,curdir)
3287"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhist_cnt." histmax=".g:netrw_dirhistmax)
3288  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3289"   "  call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3290   return
3291  endif
3292
3293  let ykeep    = @@
3294  let curbufnr = bufnr("%")
3295
3296  if a:chg == 0
3297   " bookmark the current directory
3298"   call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3299   if exists("s:netrwmarkfilelist_{curbufnr}")
3300    call s:NetrwBookmark(0)
3301    echo "bookmarked marked files"
3302   else
3303    call s:MakeBookmark(a:curdir)
3304    echo "bookmarked the current directory"
3305   endif
3306
3307  elseif a:chg == 1
3308   " change to the bookmarked directory
3309"   call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3310   if exists("g:netrw_bookmarklist[v:count-1]")
3311"    call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3312    exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3313   else
3314    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3315   endif
3316
3317  elseif a:chg == 2
3318"   redraw!
3319   let didwork= 0
3320   " list user's bookmarks
3321"   call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3322   if exists("g:netrw_bookmarklist")
3323"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3324    let cnt= 1
3325    for bmd in g:netrw_bookmarklist
3326"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3327     echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3328     let didwork = 1
3329     let cnt     = cnt + 1
3330    endfor
3331   endif
3332
3333   " list directory history
3334   let cnt     = g:netrw_dirhist_cnt
3335   let first   = 1
3336   let histcnt = 0
3337   if g:netrw_dirhistmax > 0
3338    while ( first || cnt != g:netrw_dirhist_cnt )
3339"    call Decho("first=".first." cnt=".cnt." dirhist_cnt=".g:netrw_dirhist_cnt,'~'.expand("<slnum>"))
3340     if exists("g:netrw_dirhist_{cnt}")
3341"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3342      echo printf("Netrw  History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3343      let didwork= 1
3344     endif
3345     let histcnt = histcnt + 1
3346     let first   = 0
3347     let cnt     = ( cnt - 1 ) % g:netrw_dirhistmax
3348     if cnt < 0
3349      let cnt= cnt + g:netrw_dirhistmax
3350     endif
3351    endwhile
3352   else
3353    let g:netrw_dirhist_cnt= 0
3354   endif
3355   if didwork
3356    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3357   endif
3358
3359  elseif a:chg == 3
3360   " saves most recently visited directories (when they differ)
3361"   call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3362   if !exists("g:netrw_dirhist_cnt") || !exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") || g:netrw_dirhist_{g:netrw_dirhist_cnt} != a:curdir
3363    if g:netrw_dirhistmax > 0
3364     let g:netrw_dirhist_cnt                   = ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
3365     let g:netrw_dirhist_{g:netrw_dirhist_cnt} = a:curdir
3366    endif
3367"    call Decho("save dirhist#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3368   endif
3369
3370  elseif a:chg == 4
3371   " u: change to the previous directory stored on the history list
3372"   call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
3373   if g:netrw_dirhistmax > 0
3374    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - v:count1 ) % g:netrw_dirhistmax
3375    if g:netrw_dirhist_cnt < 0
3376     let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
3377    endif
3378   else
3379    let g:netrw_dirhist_cnt= 0
3380   endif
3381   if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
3382"    call Decho("changedir u#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3383    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3384     setl ma noro
3385"     call Decho("setl ma noro",'~'.expand("<slnum>"))
3386     sil! NetrwKeepj %d _
3387     setl nomod
3388"     call Decho("setl nomod",'~'.expand("<slnum>"))
3389"     call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3390    endif
3391"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("<slnum>"))
3392    exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
3393   else
3394    if g:netrw_dirhistmax > 0
3395     let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + v:count1 ) % g:netrw_dirhistmax
3396    else
3397     let g:netrw_dirhist_cnt= 0
3398    endif
3399    echo "Sorry, no predecessor directory exists yet"
3400   endif
3401
3402  elseif a:chg == 5
3403   " U: change to the subsequent directory stored on the history list
3404"   call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3405   if g:netrw_dirhistmax > 0
3406    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
3407    if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
3408"    call Decho("changedir U#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">",'~'.expand("<slnum>"))
3409     if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3410"      call Decho("setl ma noro",'~'.expand("<slnum>"))
3411      setl ma noro
3412      sil! NetrwKeepj %d _
3413"      call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3414"      call Decho("setl nomod",'~'.expand("<slnum>"))
3415      setl nomod
3416"      call Decho("(set nomod)  ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3417     endif
3418"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}),'~'.expand("<slnum>"))
3419     exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
3420    else
3421     let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax
3422     if g:netrw_dirhist_cnt < 0
3423      let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
3424     endif
3425     echo "Sorry, no successor directory exists yet"
3426    endif
3427   else
3428    let g:netrw_dirhist_cnt= 0
3429    echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
3430   endif
3431
3432  elseif a:chg == 6
3433"   call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3434   if exists("s:netrwmarkfilelist_{curbufnr}")
3435    call s:NetrwBookmark(1)
3436    echo "removed marked files from bookmarks"
3437   else
3438    " delete the v:count'th bookmark
3439    let iremove = v:count
3440    let dremove = g:netrw_bookmarklist[iremove - 1]
3441"    call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3442    call s:MergeBookmarks()
3443"    call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3444    NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3445    echo "removed ".dremove." from g:netrw_bookmarklist"
3446"    call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3447   endif
3448"   call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3449  endif
3450  call s:NetrwBookmarkMenu()
3451  call s:NetrwTgtMenu()
3452  let @@= ykeep
3453"  call Dret("s:NetrwBookHistHandler")
3454endfun
3455
3456" ---------------------------------------------------------------------
3457" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
3458"  Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
3459"                      Sister function: s:NetrwBookHistSave()
3460fun! s:NetrwBookHistRead()
3461"  call Dfunc("s:NetrwBookHistRead()")
3462  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3463"   "  call Dret("s:NetrwBookHistRead - suppressed due to g:netrw_dirhistmax")
3464   return
3465  endif
3466  let ykeep= @@
3467  if !exists("s:netrw_initbookhist")
3468   let home    = s:NetrwHome()
3469   let savefile= home."/.netrwbook"
3470   if filereadable(s:NetrwFile(savefile))
3471"    call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3472    exe "keepalt NetrwKeepj so ".savefile
3473   endif
3474   if g:netrw_dirhistmax > 0
3475    let savefile= home."/.netrwhist"
3476    if filereadable(s:NetrwFile(savefile))
3477"    call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3478     exe "keepalt NetrwKeepj so ".savefile
3479    endif
3480    let s:netrw_initbookhist= 1
3481    au VimLeave * call s:NetrwBookHistSave()
3482   endif
3483  endif
3484  let @@= ykeep
3485"  call Dret("s:NetrwBookHistRead")
3486endfun
3487
3488" ---------------------------------------------------------------------
3489" s:NetrwBookHistSave: this function saves bookmarks and history {{{2
3490"                      Sister function: s:NetrwBookHistRead()
3491"                      I used to do this via viminfo but that appears to
3492"                      be unreliable for long-term storage
3493"                      If g:netrw_dirhistmax is <= 0, no history or bookmarks
3494"                      will be saved.
3495fun! s:NetrwBookHistSave()
3496"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax)
3497  if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
3498"   call Dret("s:NetrwBookHistSave : dirhistmax=".g:netrw_dirhistmax)
3499   return
3500  endif
3501
3502  let savefile= s:NetrwHome()."/.netrwhist"
3503  1split
3504  call s:NetrwEnew()
3505  if g:netrw_use_noswf
3506   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
3507  else
3508   setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
3509  endif
3510  setl nocin noai noci magic nospell nohid wig= noaw
3511  setl ma noro write
3512  if exists("+acd") | setl noacd | endif
3513  sil! NetrwKeepj keepalt %d _
3514
3515  " save .netrwhist -- no attempt to merge
3516  sil! keepalt file .netrwhist
3517  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
3518  call setline(2,"let g:netrw_dirhist_cnt =".g:netrw_dirhist_cnt)
3519  let lastline = line("$")
3520  let cnt      = 1
3521  while cnt <= g:netrw_dirhist_cnt
3522   call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3523   let cnt= cnt + 1
3524  endwhile
3525  exe "sil! w! ".savefile
3526
3527  sil NetrwKeepj %d _
3528  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
3529   " merge and write .netrwbook
3530   let savefile= s:NetrwHome()."/.netrwbook"
3531
3532   if filereadable(s:NetrwFile(savefile))
3533    let booklist= deepcopy(g:netrw_bookmarklist)
3534    exe "sil NetrwKeepj keepalt so ".savefile
3535    for bdm in booklist
3536     if index(g:netrw_bookmarklist,bdm) == -1
3537      call add(g:netrw_bookmarklist,bdm)
3538     endif
3539    endfor
3540    call sort(g:netrw_bookmarklist)
3541   endif
3542
3543   " construct and save .netrwbook
3544   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3545   exe "sil! w! ".savefile
3546  endif
3547  let bgone= bufnr("%")
3548  q!
3549  exe "keepalt ".bgone."bwipe!"
3550
3551"  call Dret("s:NetrwBookHistSave")
3552endfun
3553
3554" ---------------------------------------------------------------------
3555" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3556"  list of the contents of a local or remote directory.  It is assumed that the
3557"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3558"  with the requested remote hostname first.
3559"    Often called via:  Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
3560fun! s:NetrwBrowse(islocal,dirname)
3561  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
3562"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
3563"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
3564"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3565"  call Dredir("ls!")
3566
3567  " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3568  " This is useful when one edits a local file, then :e ., then :Rex
3569  if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
3570   let w:netrw_rexfile= bufname("#")
3571"   call Decho("setting w:netrw_rexfile<".w:netrw_rexfile."> win#".winnr(),'~'.expand("<slnum>"))
3572  endif
3573
3574  " s:NetrwBrowse : initialize history {{{3
3575  if !exists("s:netrw_initbookhist")
3576   NetrwKeepj call s:NetrwBookHistRead()
3577  endif
3578
3579  " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
3580  if a:dirname !~ '^\a\{3,}://'
3581   let dirname= simplify(a:dirname)
3582  else
3583   let dirname= a:dirname
3584  endif
3585
3586  if exists("s:netrw_skipbrowse")
3587   unlet s:netrw_skipbrowse
3588"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." filename<".expand("%")."> win#".winnr()." ft<".&ft.">",'~'.expand("<slnum>"))
3589"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse existed")
3590   return
3591  endif
3592
3593  " s:NetrwBrowse : sanity checks: {{{3
3594  if !exists("*shellescape")
3595   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3596"   call Dret("s:NetrwBrowse : missing shellescape()")
3597   return
3598  endif
3599  if !exists("*fnameescape")
3600   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3601"   call Dret("s:NetrwBrowse : missing fnameescape()")
3602   return
3603  endif
3604
3605  " s:NetrwBrowse : save options: {{{3
3606  call s:NetrwOptionSave("w:")
3607
3608  " s:NetrwBrowse : re-instate any marked files {{{3
3609  if exists("s:netrwmarkfilelist_{bufnr('%')}")
3610"   call Decho("clearing marked files",'~'.expand("<slnum>"))
3611   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3612  endif
3613
3614  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
3615   " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3616"   call Decho("handle w:netrw_acdkeep:",'~'.expand("<slnum>"))
3617"   call Decho("NetrwKeepj lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")",'~'.expand("<slnum>"))
3618   call s:NetrwLcd(dirname)
3619   call s:NetrwSafeOptions()
3620"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
3621
3622  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
3623   " s:NetrwBrowse :  remote regular file handler {{{3
3624"   call Decho("handle remote regular file: dirname<".dirname.">",'~'.expand("<slnum>"))
3625   if bufname(dirname) != ""
3626"    call Decho("edit buf#".bufname(dirname)." in win#".winnr(),'~'.expand("<slnum>"))
3627    exe "NetrwKeepj b ".bufname(dirname)
3628   else
3629    " attempt transfer of remote regular file
3630"    call Decho("attempt transfer as regular file<".dirname.">",'~'.expand("<slnum>"))
3631
3632    " remove any filetype indicator from end of dirname, except for the
3633    " "this is a directory" indicator (/).
3634    " There shouldn't be one of those here, anyway.
3635    let path= substitute(dirname,'[*=@|]\r\=$','','e')
3636"    call Decho("new path<".path.">",'~'.expand("<slnum>"))
3637    call s:RemotePathAnalysis(dirname)
3638
3639    " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3640    call s:NetrwEnew(dirname)
3641    call s:NetrwSafeOptions()
3642    setl ma noro
3643"    call Decho("setl ma noro",'~'.expand("<slnum>"))
3644    let b:netrw_curdir = dirname
3645    let url            = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3646"    call Decho("exe sil! keepalt file ".fnameescape(url)." (bt=".&bt.")",'~'.expand("<slnum>"))
3647    exe "sil! NetrwKeepj keepalt file ".fnameescape(url)
3648    exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3649    sil call netrw#NetRead(2,url)
3650    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3651"    call Decho("url<".url.">",'~'.expand("<slnum>"))
3652"    call Decho("s:path<".s:path.">",'~'.expand("<slnum>"))
3653"    call Decho("s:fname<".s:fname.">",'~'.expand("<slnum>"))
3654    if s:path =~ '.bz2'
3655     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3656    elseif s:path =~ '.gz'
3657     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3658    elseif s:path =~ '.gz'
3659     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3660    else
3661     exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3662    endif
3663   endif
3664
3665   " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3666   call s:SetBufWinVars()
3667   call s:NetrwOptionRestore("w:")
3668"   call Decho("setl ma nomod",'~'.expand("<slnum>"))
3669   setl ma nomod noro
3670"   call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3671
3672"   call Dret("s:NetrwBrowse : file<".s:fname.">")
3673   return
3674  endif
3675
3676  " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
3677  call s:UseBufWinVars()
3678
3679  " set up some variables {{{3
3680  let b:netrw_browser_active = 1
3681  let dirname                = dirname
3682  let s:last_sort_by         = g:netrw_sort_by
3683
3684  " set up menu {{{3
3685  NetrwKeepj call s:NetrwMenu(1)
3686
3687  " get/set-up buffer {{{3
3688"  call Decho("saving position across a buffer refresh",'~'.expand("<slnum>"))
3689  let svpos  = winsaveview()
3690"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3691  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
3692
3693  " maintain markfile highlighting
3694  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3695"   call Decho("bufnr(%)=".bufnr('%'),'~'.expand("<slnum>"))
3696"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
3697   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3698  else
3699"   call Decho("2match none",'~'.expand("<slnum>"))
3700   2match none
3701  endif
3702  if reusing && line("$") > 1
3703   call s:NetrwOptionRestore("w:")
3704"   call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3705   setl noma nomod nowrap
3706"   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>"))
3707"   call Dret("s:NetrwBrowse : re-using not-cleared buffer")
3708   return
3709  endif
3710
3711  " set b:netrw_curdir to the new directory name {{{3
3712"  call Decho("set b:netrw_curdir to the new directory name<".dirname."> (buf#".bufnr("%").")",'~'.expand("<slnum>"))
3713  let b:netrw_curdir= dirname
3714  if b:netrw_curdir =~ '[/\\]$'
3715   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
3716  endif
3717  if b:netrw_curdir =~ '\a:$' && (has("win32") || has("win95") || has("win64") || has("win16"))
3718   let b:netrw_curdir= b:netrw_curdir."/"
3719  endif
3720  if b:netrw_curdir == ''
3721   if has("amiga")
3722    " On the Amiga, the empty string connotes the current directory
3723    let b:netrw_curdir= getcwd()
3724   else
3725    " under unix, when the root directory is encountered, the result
3726    " from the preceding substitute is an empty string.
3727    let b:netrw_curdir= '/'
3728   endif
3729  endif
3730  if !a:islocal && b:netrw_curdir !~ '/$'
3731   let b:netrw_curdir= b:netrw_curdir.'/'
3732  endif
3733"  call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
3734
3735  " ------------
3736  " (local only) {{{3
3737  " ------------
3738  if a:islocal
3739"   call Decho("local only:",'~'.expand("<slnum>"))
3740
3741   " Set up ShellCmdPost handling.  Append current buffer to browselist
3742   call s:LocalFastBrowser()
3743
3744  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3745   if !g:netrw_keepdir
3746"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
3747"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"),'~'.expand("<slnum>"))
3748    if !exists("&l:acd") || !&l:acd
3749     call s:NetrwLcd(b:netrw_curdir)
3750    endif
3751   endif
3752
3753  " --------------------------------
3754  " remote handling: {{{3
3755  " --------------------------------
3756  else
3757"   call Decho("remote only:",'~'.expand("<slnum>"))
3758
3759   " analyze dirname and g:netrw_list_cmd {{{3
3760"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">",'~'.expand("<slnum>"))
3761   if dirname =~# "^NetrwTreeListing\>"
3762    let dirname= b:netrw_curdir
3763"    call Decho("(dirname was <NetrwTreeListing>) dirname<".dirname.">",'~'.expand("<slnum>"))
3764   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3765    let dirname= substitute(b:netrw_curdir,'\\','/','g')
3766    if dirname !~ '/$'
3767     let dirname= dirname.'/'
3768    endif
3769    let b:netrw_curdir = dirname
3770"    call Decho("(liststyle is TREELIST) dirname<".dirname.">",'~'.expand("<slnum>"))
3771   else
3772    let dirname = substitute(dirname,'\\','/','g')
3773"    call Decho("(normal) dirname<".dirname.">",'~'.expand("<slnum>"))
3774   endif
3775
3776   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3777   if dirname !~ dirpat
3778    if !exists("g:netrw_quiet")
3779     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3780    endif
3781    NetrwKeepj call s:NetrwOptionRestore("w:")
3782"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
3783    setl noma nomod nowrap
3784"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3785"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
3786    return
3787   endif
3788   let b:netrw_curdir= dirname
3789"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)",'~'.expand("<slnum>"))
3790  endif  " (additional remote handling)
3791
3792  " -----------------------
3793  " Directory Listing: {{{3
3794  " -----------------------
3795  NetrwKeepj call s:NetrwMaps(a:islocal)
3796  NetrwKeepj call s:NetrwCommands(a:islocal)
3797  NetrwKeepj call s:PerformListing(a:islocal)
3798
3799  " restore option(s)
3800  call s:NetrwOptionRestore("w:")
3801"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3802
3803  " If there is a rexposn: restore position with rexposn
3804  " Otherwise            : set rexposn
3805  if exists("s:rexposn_".bufnr("%"))
3806"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
3807   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
3808   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
3809    NetrwKeepj exe w:netrw_bannercnt
3810   endif
3811  else
3812   NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
3813  endif
3814  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
3815   let &l:bexpr= "netrw#BalloonHelp()"
3816"   call Decho("set up balloon help: l:bexpr=".&l:bexpr,'~'.expand("<slnum>"))
3817   setl beval
3818  endif
3819
3820  " restore position
3821  if reusing
3822"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
3823   call winrestview(svpos)
3824  endif
3825
3826  " The s:LocalBrowseRefresh() function is called by an autocmd
3827  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow, medium speed).
3828  " However, s:NetrwBrowse() causes the FocusGained event to fire the firstt time.
3829"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
3830"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3831"  call Dret("s:NetrwBrowse : did PerformListing  ft<".&ft.">")
3832  return
3833endfun
3834
3835" ---------------------------------------------------------------------
3836" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
3837" may not apply correctly; ie. netrw's idea of the current directory may
3838" differ from vim's.  This function insures that netrw's idea of the current
3839" directory is used.
3840fun! s:NetrwFile(fname)
3841"  call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
3842"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
3843"  call Decho("g:netrw_cygwin   =".(exists("g:netrw_cygwin")?    g:netrw_cygwin    : 'n/a'),'~'.expand("<slnum>"))
3844"  call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
3845"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
3846
3847  " clean up any leading treedepthstring
3848  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
3849   let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
3850"   call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>"))
3851  else
3852   let fname= a:fname
3853  endif
3854
3855  if g:netrw_keepdir
3856   " vim's idea of the current directory possibly may differ from netrw's
3857   if !exists("b:netrw_curdir")
3858    let b:netrw_curdir= getcwd()
3859   endif
3860
3861   if !exists("g:netrw_cygwin") && (has("win32") || has("win95") || has("win64") || has("win16"))
3862    if fname =~ '^\' || fname =~ '^\a:\'
3863     " windows, but full path given
3864     let ret= fname
3865"     call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3866    else
3867     " windows, relative path given
3868     let ret= s:ComposePath(b:netrw_curdir,fname)
3869"     call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3870    endif
3871
3872   elseif fname =~ '^/'
3873    " not windows, full path given
3874    let ret= fname
3875"    call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3876   else
3877    " not windows, relative path given
3878    let ret= s:ComposePath(b:netrw_curdir,fname)
3879"    call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3880   endif
3881  else
3882   " vim and netrw agree on the current directory
3883   let ret= fname
3884"   call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
3885"   call Decho("vim   directory: ".getcwd(),'~'.expand("<slnum>"))
3886"   call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>"))
3887  endif
3888
3889"  call Dret("s:NetrwFile ".ret)
3890  return ret
3891endfun
3892
3893" ---------------------------------------------------------------------
3894" s:NetrwFileInfo: supports qf (query for file information) {{{2
3895fun! s:NetrwFileInfo(islocal,fname)
3896"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
3897  let ykeep= @@
3898  if a:islocal
3899   let lsopt= "-lsad"
3900   if g:netrw_sizestyle =~# 'H'
3901    let lsopt= "-lsadh"
3902   elseif g:netrw_sizestyle =~# 'h'
3903    let lsopt= "-lsadh --si"
3904   endif
3905   if (has("unix") || has("macunix")) && executable("/bin/ls")
3906
3907    if getline(".") == "../"
3908     echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
3909"     call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
3910
3911    elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
3912     echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
3913"     call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
3914
3915    elseif exists("b:netrw_curdir")
3916      echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
3917"      call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
3918
3919    else
3920"     call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
3921     echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
3922"     call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
3923    endif
3924   else
3925    " use vim functions to return information about file below cursor
3926"    call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
3927    if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
3928     let fname= substitute(a:fname,".$","","")
3929    else
3930     let fname= a:fname
3931    endif
3932    let t  = getftime(s:NetrwFile(fname))
3933    let sz = getfsize(s:NetrwFile(fname))
3934    if g:netrw_sizestyle =~# "[hH]"
3935     let sz= s:NetrwHumanReadable(sz)
3936    endif
3937    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
3938"    call Decho("fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
3939   endif
3940  else
3941   echo "sorry, \"qf\" not supported yet for remote files"
3942  endif
3943  let @@= ykeep
3944"  call Dret("s:NetrwFileInfo")
3945endfun
3946
3947" ---------------------------------------------------------------------
3948" s:NetrwFullPath: returns the full path to a directory and/or file {{{2
3949fun! s:NetrwFullPath(filename)
3950"  " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)")
3951  let filename= a:filename
3952  if filename !~ '^/'
3953   let filename= resolve(getcwd().'/'.filename)
3954  endif
3955  if filename != "/" && filename =~ '/$'
3956   let filename= substitute(filename,'/$','','')
3957  endif
3958"  " call Dret("s:NetrwFullPath <".filename.">")
3959  return filename
3960endfun
3961
3962" ---------------------------------------------------------------------
3963" s:NetrwGetBuffer: {{{2
3964"   returns 0=cleared buffer
3965"           1=re-used buffer (buffer not cleared)
3966fun! s:NetrwGetBuffer(islocal,dirname)
3967"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
3968"  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>"))
3969"  call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
3970  let dirname= a:dirname
3971
3972  " re-use buffer if possible {{{3
3973"  call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
3974  if !exists("s:netrwbuf")
3975   let s:netrwbuf= {}
3976  endif
3977  if has_key(s:netrwbuf,s:NetrwFullPath(dirname))
3978   let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
3979"   call Decho("lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum)
3980   if !bufexists(bufnum)
3981    call remove(s:netrwbuf,s:NetrwFullPath(dirname))
3982    let bufnum= -1
3983   endif
3984  else
3985"   call Decho("lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key")
3986   let bufnum= -1
3987  endif
3988
3989  " get enew buffer and name it -or- re-use buffer {{{3
3990  if bufnum < 0      " get enew buffer and name it
3991"   call Decho("--get enew buffer and name it  (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
3992   call s:NetrwEnew(dirname)
3993"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
3994   " name the buffer
3995   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
3996    " Got enew buffer; transform into a NetrwTreeListing
3997"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
3998    if !exists("s:netrw_treelistnum")
3999     let s:netrw_treelistnum= 1
4000    else
4001     let s:netrw_treelistnum= s:netrw_treelistnum + 1
4002    endif
4003    let w:netrw_treebufnr= bufnr("%")
4004"    call Decho("  exe sil! keepalt file NetrwTreeListing ".fnameescape(s:netrw_treelistnum),'~'.expand("<slnum>"))
4005    exe 'sil! keepalt file NetrwTreeListing\ '.fnameescape(s:netrw_treelistnum)
4006    if g:netrw_use_noswf
4007     setl nobl bt=nofile noswf
4008    else
4009     setl nobl bt=nofile
4010    endif
4011    nnoremap <silent> <buffer> [[       :sil call <SID>TreeListMove('[[')<cr>
4012    nnoremap <silent> <buffer> ]]       :sil call <SID>TreeListMove(']]')<cr>
4013    nnoremap <silent> <buffer> []       :sil call <SID>TreeListMove('[]')<cr>
4014    nnoremap <silent> <buffer> ][       :sil call <SID>TreeListMove('][')<cr>
4015"    call Decho("  tree listing#".s:netrw_treelistnum." bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
4016   else
4017"    let v:errmsg   = "" " Decho
4018    let escdirname = fnameescape(dirname)
4019"    call Decho("  errmsg<".v:errmsg."> bufnr(escdirname<".escdirname.">)=".bufnr(escdirname)." bufname()<".bufname(bufnr(escdirname)).">",'~'.expand("<slnum>"))
4020"    call Decho('  exe sil! keepalt file '.escdirname,'~'.expand("<slnum>"))
4021"    let v:errmsg= "" " Decho
4022    exe 'sil! keepj keepalt file '.escdirname
4023"    call Decho("  errmsg<".v:errmsg."> bufnr(".escdirname.")=".bufnr(escdirname)."<".bufname(bufnr(escdirname)).">",'~'.expand("<slnum>"))
4024    " enter the new buffer into the s:netrwbuf dictionary
4025    let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%")
4026"    call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>"))
4027"    call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
4028   endif
4029"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4030
4031  else " Re-use the buffer
4032"   call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4033   let eikeep= &ei
4034   setl ei=all
4035   if getline(2) =~# '^" Netrw Directory Listing'
4036"    call Decho("  getline(2)<".getline(2).'> matches "Netrw Directory Listing" : using keepalt b '.bufnum,'~'.expand("<slnum>"))
4037    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4038   else
4039"    call Decho("  getline(2)<".getline(2).'> does not match "Netrw Directory Listing" : using b '.bufnum,'~'.expand("<slnum>"))
4040    exe "sil! NetrwKeepj noswapfile keepalt b ".bufnum
4041   endif
4042"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
4043   if bufname("%") == '.'
4044"    call Decho("exe sil! keepalt file ".fnameescape(getcwd()),'~'.expand("<slnum>"))
4045    exe "sil! NetrwKeepj keepalt file ".fnameescape(getcwd())
4046   endif
4047   let &ei= eikeep
4048
4049   if line("$") <= 1 && getline(1) == ""
4050    " empty buffer
4051    NetrwKeepj call s:NetrwListSettings(a:islocal)
4052"    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>"))
4053"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4054"    call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4055    return 0
4056
4057   elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4058"    call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4059    NetrwKeepj call s:NetrwListSettings(a:islocal)
4060    sil NetrwKeepj %d _
4061"    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>"))
4062"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4063"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4064    return 0
4065
4066   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4067"    call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4068"    call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4069    sil NetrwKeepj %d _
4070    NetrwKeepj call s:NetrwListSettings(a:islocal)
4071"    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>"))
4072"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4073"    call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4074    return 0
4075
4076   else
4077"    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>"))
4078"    call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4079"    call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4080    return 1
4081   endif
4082  endif
4083
4084  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4085  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
4086  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
4087  "  med    1         D      H
4088  "  fast   2         H      H
4089"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
4090  let fname= expand("%")
4091  NetrwKeepj call s:NetrwListSettings(a:islocal)
4092"  call Decho("exe sil! keepalt file ".fnameescape(fname),'~'.expand("<slnum>"))
4093  exe "sil! NetrwKeepj keepalt file ".fnameescape(fname)
4094
4095  " delete all lines from buffer {{{3
4096"  call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4097"  call Decho("  clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4098  sil! keepalt NetrwKeepj %d _
4099
4100"  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>"))
4101"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4102"  call Dret("s:NetrwGetBuffer 0<cleared buffer>")
4103  return 0
4104endfun
4105
4106" ---------------------------------------------------------------------
4107" s:NetrwGetcwd: get the current directory. {{{2
4108"   Change backslashes to forward slashes, if any.
4109"   If doesc is true, escape certain troublesome characters
4110fun! s:NetrwGetcwd(doesc)
4111"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
4112  let curdir= substitute(getcwd(),'\\','/','ge')
4113  if curdir !~ '[\/]$'
4114   let curdir= curdir.'/'
4115  endif
4116  if a:doesc
4117   let curdir= fnameescape(curdir)
4118  endif
4119"  call Dret("NetrwGetcwd <".curdir.">")
4120  return curdir
4121endfun
4122
4123" ---------------------------------------------------------------------
4124"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4125fun! s:NetrwGetWord()
4126"  call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4127"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4128  let keepsol= &l:sol
4129  setl nosol
4130
4131  call s:UseBufWinVars()
4132
4133  " insure that w:netrw_liststyle is set up
4134  if !exists("w:netrw_liststyle")
4135   if exists("g:netrw_liststyle")
4136    let w:netrw_liststyle= g:netrw_liststyle
4137   else
4138    let w:netrw_liststyle= s:THINLIST
4139   endif
4140"   call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
4141  endif
4142
4143  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
4144   " Active Banner support
4145"   call Decho("active banner handling",'~'.expand("<slnum>"))
4146   NetrwKeepj norm! 0
4147   let dirname= "./"
4148   let curline= getline('.')
4149
4150   if curline =~# '"\s*Sorted by\s'
4151    NetrwKeepj norm s
4152    let s:netrw_skipbrowse= 1
4153    echo 'Pressing "s" also works'
4154
4155   elseif curline =~# '"\s*Sort sequence:'
4156    let s:netrw_skipbrowse= 1
4157    echo 'Press "S" to edit sorting sequence'
4158
4159   elseif curline =~# '"\s*Quick Help:'
4160    NetrwKeepj norm ?
4161    let s:netrw_skipbrowse= 1
4162
4163   elseif curline =~# '"\s*\%(Hiding\|Showing\):'
4164    NetrwKeepj norm a
4165    let s:netrw_skipbrowse= 1
4166    echo 'Pressing "a" also works'
4167
4168   elseif line("$") > w:netrw_bannercnt
4169    exe 'sil NetrwKeepj '.w:netrw_bannercnt
4170   endif
4171
4172  elseif w:netrw_liststyle == s:THINLIST
4173"   call Decho("thin column handling",'~'.expand("<slnum>"))
4174   NetrwKeepj norm! 0
4175   let dirname= substitute(getline('.'),'\t -->.*$','','')
4176
4177  elseif w:netrw_liststyle == s:LONGLIST
4178"   call Decho("long column handling",'~'.expand("<slnum>"))
4179   NetrwKeepj norm! 0
4180   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
4181
4182  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4183"   call Decho("treelist handling",'~'.expand("<slnum>"))
4184   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4185   let dirname= substitute(dirname,'\t -->.*$','','')
4186
4187  else
4188"   call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4189   let dirname= getline('.')
4190
4191   if !exists("b:netrw_cpf")
4192    let b:netrw_cpf= 0
4193    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
4194    call histdel("/",-1)
4195"   "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4196   endif
4197
4198"   call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4199   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4200"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4201"   call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4202   if filestart == 0
4203    NetrwKeepj norm! 0ma
4204   else
4205    call cursor(line("."),filestart+1)
4206    NetrwKeepj norm! ma
4207   endif
4208   let rega= @a
4209   let eofname= filestart + b:netrw_cpf + 1
4210   if eofname <= col("$")
4211    call cursor(line("."),filestart+b:netrw_cpf+1)
4212    NetrwKeepj norm! "ay`a
4213   else
4214    NetrwKeepj norm! "ay$
4215   endif
4216   let dirname = @a
4217   let @a      = rega
4218"   call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4219   let dirname= substitute(dirname,'\s\+$','','e')
4220"   call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4221  endif
4222
4223  " symlinks are indicated by a trailing "@".  Remove it before further processing.
4224  let dirname= substitute(dirname,"@$","","")
4225
4226  " executables are indicated by a trailing "*".  Remove it before further processing.
4227  let dirname= substitute(dirname,"\*$","","")
4228
4229  let &l:sol= keepsol
4230
4231"  call Dret("s:NetrwGetWord <".dirname.">")
4232  return dirname
4233endfun
4234
4235" ---------------------------------------------------------------------
4236" s:NetrwListSettings: make standard settings for a netrw listing {{{2
4237fun! s:NetrwListSettings(islocal)
4238"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4239"  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>"))
4240  let fname= bufname("%")
4241"  "  call Decho("(NetrwListSettings) setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
4242  setl bt=nofile nobl ma nonu nowrap noro nornu
4243"  call Decho("(NetrwListSettings) exe sil! keepalt file ".fnameescape(fname),'~'.expand("<slnum>"))
4244  exe "sil! keepalt file ".fnameescape(fname)
4245  if g:netrw_use_noswf
4246   setl noswf
4247  endif
4248"  call Dredir("ls!")
4249"  call Decho("(NetrwListSettings) exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
4250  exe "setl ts=".(g:netrw_maxfilenamelen+1)
4251  setl isk+=.,~,-
4252  if g:netrw_fastbrowse > a:islocal
4253   setl bh=hide
4254  else
4255   setl bh=delete
4256  endif
4257"  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>"))
4258"  call Dret("s:NetrwListSettings")
4259endfun
4260
4261" ---------------------------------------------------------------------
4262"  s:NetrwListStyle: {{{2
4263"  islocal=0: remote browsing
4264"         =1: local browsing
4265fun! s:NetrwListStyle(islocal)
4266"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
4267
4268  let ykeep             = @@
4269  let fname             = s:NetrwGetWord()
4270  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
4271  let svpos            = winsaveview()
4272"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4273  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
4274"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
4275"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle,'~'.expand("<slnum>"))
4276"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
4277
4278  if w:netrw_liststyle == s:THINLIST
4279   " use one column listing
4280"   call Decho("use one column list",'~'.expand("<slnum>"))
4281   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4282
4283  elseif w:netrw_liststyle == s:LONGLIST
4284   " use long list
4285"   call Decho("use long list",'~'.expand("<slnum>"))
4286   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
4287
4288  elseif w:netrw_liststyle == s:WIDELIST
4289   " give wide list
4290"   call Decho("use wide list",'~'.expand("<slnum>"))
4291   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4292
4293  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4294"   call Decho("use tree list",'~'.expand("<slnum>"))
4295   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
4296
4297  else
4298   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4299   let g:netrw_liststyle = s:THINLIST
4300   let w:netrw_liststyle = g:netrw_liststyle
4301   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
4302  endif
4303  setl ma noro
4304"  call Decho("setl ma noro",'~'.expand("<slnum>"))
4305
4306  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
4307"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4308  sil! NetrwKeepj %d _
4309  " following prevents tree listing buffer from being marked "modified"
4310"  call Decho("setl nomod",'~'.expand("<slnum>"))
4311  setl nomod
4312"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4313
4314  " refresh the listing
4315"  call Decho("refresh the listing",'~'.expand("<slnum>"))
4316  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4317  NetrwKeepj call s:NetrwCursor()
4318
4319  " restore position; keep cursor on the filename
4320"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4321  NetrwKeepj call winrestview(svpos)
4322  let @@= ykeep
4323
4324"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
4325endfun
4326
4327" ---------------------------------------------------------------------
4328" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4329fun! s:NetrwBannerCtrl(islocal)
4330"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
4331
4332  let ykeep= @@
4333  " toggle the banner (enable/suppress)
4334  let g:netrw_banner= !g:netrw_banner
4335
4336  " refresh the listing
4337  let svpos= winsaveview()
4338"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4339  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4340
4341  " keep cursor on the filename
4342  let fname= s:NetrwGetWord()
4343  sil NetrwKeepj $
4344  let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4345"  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4346  if result <= 0 && exists("w:netrw_bannercnt")
4347   exe "NetrwKeepj ".w:netrw_bannercnt
4348  endif
4349  let @@= ykeep
4350"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
4351endfun
4352
4353" ---------------------------------------------------------------------
4354" s:NetrwBookmark: supports :NetrwMB[!] [file]s                 {{{2
4355"
4356"  No bang: enters files/directories into Netrw's bookmark system
4357"   No argument and in netrw buffer:
4358"     if there are marked files: bookmark marked files
4359"     otherwise                : bookmark file/directory under cursor
4360"   No argument and not in netrw buffer: bookmarks current open file
4361"   Has arguments: globs them individually and bookmarks them
4362"
4363"  With bang: deletes files/directories from Netrw's bookmark system
4364fun! s:NetrwBookmark(del,...)
4365"  call Dfunc("s:NetrwBookmark(del=".a:del.",...) a:0=".a:0)
4366  if a:0 == 0
4367   if &ft == "netrw"
4368    let curbufnr = bufnr("%")
4369
4370    if exists("s:netrwmarkfilelist_{curbufnr}")
4371     " for every filename in the marked list
4372"     call Decho("bookmark every filename in marked list",'~'.expand("<slnum>"))
4373     let svpos  = winsaveview()
4374"     call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4375     let islocal= expand("%") !~ '^\a\{3,}://'
4376     for fname in s:netrwmarkfilelist_{curbufnr}
4377      if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4378     endfor
4379     let curdir  = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4380     call s:NetrwUnmarkList(curbufnr,curdir)
4381     NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./'))
4382"     call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
4383     NetrwKeepj call winrestview(svpos)
4384    else
4385     let fname= s:NetrwGetWord()
4386     if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4387    endif
4388
4389   else
4390    " bookmark currently open file
4391"    call Decho("bookmark currently open file",'~'.expand("<slnum>"))
4392    let fname= expand("%")
4393    if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4394   endif
4395
4396  else
4397   " bookmark specified files
4398   "  attempts to infer if working remote or local
4399   "  by deciding if the current file begins with an url
4400   "  Globbing cannot be done remotely.
4401   let islocal= expand("%") !~ '^\a\{3,}://'
4402"   call Decho("bookmark specified file".((a:0>1)? "s" : ""),'~'.expand("<slnum>"))
4403   let i = 1
4404   while i <= a:0
4405    if islocal
4406     if v:version > 704 || (v:version == 704 && has("patch656"))
4407      let mbfiles= glob(fnameescape(a:{i}),0,1,1)
4408     else
4409      let mbfiles= glob(fnameescape(a:{i}),0,1)
4410     endif
4411    else
4412     let mbfiles= [a:{i}]
4413    endif
4414"    call Decho("mbfiles".string(mbfiles),'~'.expand("<slnum>"))
4415    for mbfile in mbfiles
4416"     call Decho("mbfile<".mbfile.">",'~'.expand("<slnum>"))
4417     if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4418    endfor
4419    let i= i + 1
4420   endwhile
4421  endif
4422
4423  " update the menu
4424  call s:NetrwBookmarkMenu()
4425
4426"  call Dret("s:NetrwBookmark")
4427endfun
4428
4429" ---------------------------------------------------------------------
4430" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4431"                      .2.[cnt] for bookmarks, and
4432"                      .3.[cnt] for history
4433"                      (see s:NetrwMenu())
4434fun! s:NetrwBookmarkMenu()
4435  if !exists("s:netrw_menucnt")
4436   return
4437  endif
4438"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhist_cnt." menucnt=".s:netrw_menucnt)
4439
4440  " the following test assures that gvim is running, has menus available, and has menus enabled.
4441  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
4442   if exists("g:NetrwTopLvlMenu")
4443"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4444    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4445    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4446   endif
4447   if !exists("s:netrw_initbookhist")
4448    call s:NetrwBookHistRead()
4449   endif
4450
4451   " show bookmarked places
4452   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4453    let cnt= 1
4454    for bmd in g:netrw_bookmarklist
4455"     call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd,'~'.expand("<slnum>"))
4456     let bmd= escape(bmd,g:netrw_menu_escape)
4457
4458     " show bookmarks for goto menu
4459     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
4460
4461     " show bookmarks for deletion menu
4462     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
4463     let cnt= cnt + 1
4464    endfor
4465
4466   endif
4467
4468   " show directory browsing history
4469   if g:netrw_dirhistmax > 0
4470    let cnt     = g:netrw_dirhist_cnt
4471    let first   = 1
4472    let histcnt = 0
4473    while ( first || cnt != g:netrw_dirhist_cnt )
4474     let histcnt  = histcnt + 1
4475     let priority = g:netrw_dirhist_cnt + histcnt
4476     if exists("g:netrw_dirhist_{cnt}")
4477      let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4478"     call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir,'~'.expand("<slnum>"))
4479      exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
4480     endif
4481     let first = 0
4482     let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
4483     if cnt < 0
4484      let cnt= cnt + g:netrw_dirhistmax
4485     endif
4486    endwhile
4487   endif
4488
4489  endif
4490"  call Dret("NetrwBookmarkMenu")
4491endfun
4492
4493" ---------------------------------------------------------------------
4494"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4495"                       directory and a new directory name.  Also, if the
4496"                       "new directory name" is actually a file,
4497"                       NetrwBrowseChgDir() edits the file.
4498fun! s:NetrwBrowseChgDir(islocal,newdir,...)
4499"  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 : "").">")
4500"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4501
4502  let ykeep= @@
4503  if !exists("b:netrw_curdir")
4504   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4505   " and the current window is the NetrwMessage window.
4506   let @@= ykeep
4507"   call Decho("b:netrw_curdir doesn't exist!",'~'.expand("<slnum>"))
4508"   call Decho("getcwd<".getcwd().">",'~'.expand("<slnum>"))
4509"   call Dredir("ls!")
4510"   call Dret("s:NetrwBrowseChgDir")
4511   return
4512  endif
4513"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
4514
4515  " NetrwBrowseChgDir: save options and initialize {{{3
4516"  call Decho("saving options",'~'.expand("<slnum>"))
4517  call s:SavePosn(s:netrw_nbcd)
4518  NetrwKeepj call s:NetrwOptionSave("s:")
4519  NetrwKeepj call s:NetrwSafeOptions()
4520  if (has("win32") || has("win95") || has("win64") || has("win16"))
4521   let dirname = substitute(b:netrw_curdir,'\\','/','ge')
4522  else
4523   let dirname = b:netrw_curdir
4524  endif
4525  let newdir    = a:newdir
4526  let dolockout = 0
4527  let dorestore = 1
4528"  call Decho("dirname<".dirname.">",'~'.expand("<slnum>"))
4529
4530  " ignore <cr>s when done in the banner
4531"  call Decho('ignore [return]s when done in banner (g:netrw_banner='.g:netrw_banner.")",'~'.expand("<slnum>"))
4532  if g:netrw_banner
4533"   call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." line(.)#".line('.')." line($)#".line("#"),'~'.expand("<slnum>"))
4534   if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4535    if getline(".") =~# 'Quick Help'
4536"     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>"))
4537     let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4538"     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>"))
4539     setl ma noro nowrap
4540     NetrwKeepj call setline(line('.'),'"   Quick Help: <F1>:help  '.s:QuickHelp[g:netrw_quickhelp])
4541     setl noma nomod nowrap
4542     call s:RestorePosn(s:netrw_nbcd)
4543     NetrwKeepj call s:NetrwOptionRestore("s:")
4544"     call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4545    endif
4546   endif
4547"  else " Decho
4548"   call Decho("(s:NetrwBrowseChgdir) g:netrw_banner=".g:netrw_banner." (no banner)",'~'.expand("<slnum>"))
4549  endif
4550
4551  " set up o/s-dependent directory recognition pattern
4552  if has("amiga")
4553   let dirpat= '[\/:]$'
4554  else
4555   let dirpat= '[\/]$'
4556  endif
4557"  call Decho("set up o/s-dependent directory recognition pattern: dirname<".dirname.">  dirpat<".dirpat.">",'~'.expand("<slnum>"))
4558
4559  if dirname !~ dirpat
4560   " apparently vim is "recognizing" that it is in a directory and
4561   " is removing the trailing "/".  Bad idea, so let's put it back.
4562   let dirname= dirname.'/'
4563"   call Decho("adjusting dirname<".dirname.'>  (put trailing "/" back)','~'.expand("<slnum>"))
4564  endif
4565
4566"  call Decho("[newdir<".newdir."> ".((newdir =~ dirpat)? "=~" : "!~")." dirpat<".dirpat.">] && [islocal=".a:islocal."] && [newdir is ".(isdirectory(s:NetrwFile(newdir))? "" : "not ")."a directory]",'~'.expand("<slnum>"))
4567  if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
4568   " ------------------------------
4569   " NetrwBrowseChgDir: edit a file {{{3
4570   " ------------------------------
4571"   call Decho('edit-a-file: case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">",'~'.expand("<slnum>"))
4572
4573   " save position for benefit of Rexplore
4574   let s:rexposn_{bufnr("%")}= winsaveview()
4575"   call Decho("edit-a-file: saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
4576"   call Decho("edit-a-file: win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
4577"   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>"))
4578
4579   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4580"    call Decho("edit-a-file: handle tree listing: w:netrw_treedict<".(exists("w:netrw_treedict")? string(w:netrw_treedict) : 'n/a').">",'~'.expand("<slnum>"))
4581"    call Decho("edit-a-file: newdir<".newdir.">",'~'.expand("<slnum>"))
4582    let dirname= s:NetrwTreeDir(a:islocal)
4583    if dirname =~ '/$'
4584     let dirname= dirname.newdir
4585    else
4586     let dirname= dirname."/".newdir
4587    endif
4588"    call Decho("edit-a-file: dirname<".dirname.">",'~'.expand("<slnum>"))
4589"    call Decho("edit-a-file: tree listing",'~'.expand("<slnum>"))
4590   elseif newdir =~ '^\(/\|\a:\)'
4591"    call Decho("edit-a-file: handle an url or path starting with /: <".newdir.">",'~'.expand("<slnum>"))
4592    let dirname= newdir
4593   else
4594    let dirname= s:ComposePath(dirname,newdir)
4595   endif
4596"   call Decho("edit-a-file: handling a file: dirname<".dirname."> (a:0=".a:0.")",'~'.expand("<slnum>"))
4597   " this lets netrw#BrowseX avoid the edit
4598   if a:0 < 1
4599"    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>"))
4600    NetrwKeepj call s:NetrwOptionRestore("s:")
4601    let curdir= b:netrw_curdir
4602    if !exists("s:didsplit")
4603"     call Decho("edit-a-file: s:didsplit does not exist; g:netrw_browse_split=".string(g:netrw_browse_split)." win#".winnr(),'~'.expand("<slnum>"))
4604     if type(g:netrw_browse_split) == 3
4605      " open file in server
4606      " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4607"      call Decho("edit-a-file: open file in server",'~'.expand("<slnum>"))
4608      call s:NetrwServerEdit(a:islocal,dirname)
4609"      call Dret("s:NetrwBrowseChgDir")
4610      return
4611     elseif g:netrw_browse_split == 1
4612      " horizontally splitting the window first
4613"      call Decho("edit-a-file: horizontally splitting window prior to edit",'~'.expand("<slnum>"))
4614      keepalt new
4615      if !&ea
4616       keepalt wincmd _
4617      endif
4618      call s:SetRexDir(a:islocal,curdir)
4619     elseif g:netrw_browse_split == 2
4620      " vertically splitting the window first
4621"      call Decho("edit-a-file: vertically splitting window prior to edit",'~'.expand("<slnum>"))
4622      keepalt rightb vert new
4623      if !&ea
4624       keepalt wincmd |
4625      endif
4626      call s:SetRexDir(a:islocal,curdir)
4627     elseif g:netrw_browse_split == 3
4628      " open file in new tab
4629"      call Decho("edit-a-file: opening new tab prior to edit",'~'.expand("<slnum>"))
4630      keepalt tabnew
4631      if !exists("b:netrw_curdir")
4632       let b:netrw_curdir= getcwd()
4633      endif
4634      call s:SetRexDir(a:islocal,curdir)
4635     elseif g:netrw_browse_split == 4
4636      " act like "P" (ie. open previous window)
4637"      call Decho("edit-a-file: use previous window for edit",'~'.expand("<slnum>"))
4638      if s:NetrwPrevWinOpen(2) == 3
4639       let @@= ykeep
4640"       call Dret("s:NetrwBrowseChgDir")
4641       return
4642      endif
4643      call s:SetRexDir(a:islocal,curdir)
4644     else
4645      " handling a file, didn't split, so remove menu
4646"      call Decho("edit-a-file: handling a file+didn't split, so remove menu",'~'.expand("<slnum>"))
4647      call s:NetrwMenu(0)
4648      " optional change to window
4649      if g:netrw_chgwin >= 1
4650"       call Decho("edit-a-file: changing window to #".g:netrw_chgwin,'~'.expand("<slnum>"))
4651       if winnr("$")+1 == g:netrw_chgwin
4652	" if g:netrw_chgwin is set to one more than the last window, then
4653	" vertically split the last window to make that window available.
4654	let curwin= winnr()
4655	exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4656	vs
4657	exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4658       endif
4659       exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4660      endif
4661      call s:SetRexDir(a:islocal,curdir)
4662     endif
4663    endif
4664
4665    " the point where netrw actually edits the (local) file
4666    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4667    " no keepalt to support  :e #  to return to a directory listing
4668    if a:islocal
4669"     call Decho("edit-a-file: edit local file: exe e! ".fnameescape(dirname),'~'.expand("<slnum>"))
4670     " some like c-^ to return to the last edited file
4671     " others like c-^ to return to the netrw buffer
4672     if exists("g:netrw_altfile") && g:netrw_altfile
4673      exe "NetrwKeepj keepalt e! ".fnameescape(dirname)
4674     else
4675      exe "NetrwKeepj e! ".fnameescape(dirname)
4676     endif
4677"     call Decho("edit-a-file: after e! ".dirname.": hidden=".&hidden." bufhidden<".&bufhidden."> mod=".&mod,'~'.expand("<slnum>"))
4678     call s:NetrwCursor()
4679     if &hidden || &bufhidden == "hide"
4680      " file came from vim's hidden storage.  Don't "restore" options with it.
4681      let dorestore= 0
4682     endif
4683    else
4684"     call Decho("edit-a-file: remote file: NetrwBrowse will edit it",'~'.expand("<slnum>"))
4685    endif
4686    let dolockout= 1
4687
4688    " handle g:Netrw_funcref -- call external-to-netrw functions
4689    "   This code will handle g:Netrw_funcref as an individual function reference
4690    "   or as a list of function references.  It will ignore anything that's not
4691    "   a function reference.  See  :help Funcref  for information about function references.
4692    if exists("g:Netrw_funcref")
4693"     call Decho("edit-a-file: handle optional Funcrefs",'~'.expand("<slnum>"))
4694     if type(g:Netrw_funcref) == 2
4695"      call Decho("edit-a-file: handling a g:Netrw_funcref",'~'.expand("<slnum>"))
4696      NetrwKeepj call g:Netrw_funcref()
4697     elseif type(g:Netrw_funcref) == 3
4698"      call Decho("edit-a-file: handling a list of g:Netrw_funcrefs",'~'.expand("<slnum>"))
4699      for Fncref in g:Netrw_funcref
4700       if type(FncRef) == 2
4701        NetrwKeepj call FncRef()
4702       endif
4703      endfor
4704     endif
4705    endif
4706   endif
4707
4708  elseif newdir =~ '^/'
4709   " ----------------------------------------------------
4710   " NetrwBrowseChgDir: just go to the new directory spec {{{3
4711   " ----------------------------------------------------
4712"   call Decho('goto-newdir: case "just go to new directory spec": newdir<'.newdir.'>','~'.expand("<slnum>"))
4713   let dirname = newdir
4714   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4715   NetrwKeepj call s:NetrwOptionRestore("s:")
4716   norm! m`
4717
4718  elseif newdir == './'
4719   " ---------------------------------------------
4720   " NetrwBrowseChgDir: refresh the directory list {{{3
4721   " ---------------------------------------------
4722"   call Decho('refresh-dirlist: case "refresh directory listing": newdir == "./"','~'.expand("<slnum>"))
4723   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4724   norm! m`
4725
4726  elseif newdir == '../'
4727   " --------------------------------------
4728   " NetrwBrowseChgDir: go up one directory {{{3
4729   " --------------------------------------
4730"   call Decho('go-up: case "go up one directory": newdir == "../"','~'.expand("<slnum>"))
4731
4732   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4733    " force a refresh
4734"    call Decho("go-up: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4735"    call Decho("go-up: setl noro ma",'~'.expand("<slnum>"))
4736    setl noro ma
4737    NetrwKeepj %d _
4738   endif
4739
4740   if has("amiga")
4741    " amiga
4742"    call Decho('go-up: case "go up one directory": newdir == "../" and amiga','~'.expand("<slnum>"))
4743    if a:islocal
4744     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
4745     let dirname= substitute(dirname,'/$','','')
4746    else
4747     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
4748    endif
4749"    call Decho("go-up: amiga: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4750
4751   elseif !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
4752    " windows
4753    if a:islocal
4754     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4755     if dirname == ""
4756      let dirname= '/'
4757     endif
4758    else
4759     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4760    endif
4761    if dirname =~ '^\a:$'
4762     let dirname= dirname.'/'
4763    endif
4764"    call Decho("go-up: windows: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4765
4766   else
4767    " unix or cygwin
4768"    call Decho('go-up: case "go up one directory": newdir == "../" and unix or cygwin','~'.expand("<slnum>"))
4769    if a:islocal
4770     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4771     if dirname == ""
4772      let dirname= '/'
4773     endif
4774    else
4775     let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4776    endif
4777"    call Decho("go-up: unix: dirname<".dirname."> (go up one dir)",'~'.expand("<slnum>"))
4778   endif
4779   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4780   norm m`
4781
4782  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4783   " --------------------------------------
4784   " NetrwBrowseChgDir: Handle Tree Listing {{{3
4785   " --------------------------------------
4786"   call Decho('tree-list: case liststyle is TREELIST and w:netrw_treedict exists','~'.expand("<slnum>"))
4787   " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
4788"   call Decho("tree-list: setl noro ma",'~'.expand("<slnum>"))
4789   setl noro ma
4790   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
4791"    call Decho("tree-list: clear buffer<".expand("%")."> with :%d  (force refresh)",'~'.expand("<slnum>"))
4792    NetrwKeepj %d _
4793   endif
4794   let treedir      = s:NetrwTreeDir(a:islocal)
4795"   call Decho("tree-list: treedir<".treedir.">",'~'.expand("<slnum>"))
4796   let s:treecurpos = winsaveview()
4797   let haskey       = 0
4798"   call Decho("tree-list: w:netrw_treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
4799
4800   " search treedict for tree dir as-is
4801"   call Decho("tree-list: search treedict for tree dir as-is",'~'.expand("<slnum>"))
4802   if has_key(w:netrw_treedict,treedir)
4803"    call Decho('tree-list: ....searched for treedir<'.treedir.'> : found it!','~'.expand("<slnum>"))
4804    let haskey= 1
4805   else
4806"    call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
4807   endif
4808
4809   " search treedict for treedir with a [/@] appended
4810"   call Decho("tree-list: search treedict for treedir with a [/@] appended",'~'.expand("<slnum>"))
4811   if !haskey && treedir !~ '[/@]$'
4812    if has_key(w:netrw_treedict,treedir."/")
4813     let treedir= treedir."/"
4814"     call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
4815     let haskey = 1
4816    else
4817"     call Decho('tree-list: ....searched for treedir<'.treedir.'/> : not found','~'.expand("<slnum>"))
4818    endif
4819   endif
4820
4821   " search treedict for treedir with any trailing / elided
4822"   call Decho("tree-list: search treedict for treedir with any trailing / elided",'~'.expand("<slnum>"))
4823   if !haskey && treedir =~ '/$'
4824    let treedir= substitute(treedir,'/$','','')
4825    if has_key(w:netrw_treedict,treedir)
4826"     call Decho('tree-list: ....searched.for treedir<'.treedir.'> found it!','~'.expand("<slnum>"))
4827     let haskey = 1
4828    else
4829"     call Decho('tree-list: ....searched for treedir<'.treedir.'> : not found','~'.expand("<slnum>"))
4830    endif
4831   endif
4832
4833"   call Decho("haskey=".haskey,'~'.expand("<slnum>"))
4834   if haskey
4835    " close tree listing for selected subdirectory
4836"    call Decho("tree-list: closing selected subdirectory<".dirname.">",'~'.expand("<slnum>"))
4837    call remove(w:netrw_treedict,treedir)
4838"    call Decho("tree-list: removed     entry<".treedir."> from treedict",'~'.expand("<slnum>"))
4839"    call Decho("tree-list: yielding treedict<".string(w:netrw_treedict).">",'~'.expand("<slnum>"))
4840    let dirname= w:netrw_treetop
4841   else
4842    " go down one directory
4843    let dirname= substitute(treedir,'/*$','/','')
4844"    call Decho("tree-list: go down one dir: treedir<".treedir.">",'~'.expand("<slnum>"))
4845"    call Decho("tree-list: ...            : dirname<".dirname.">",'~'.expand("<slnum>"))
4846   endif
4847   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4848"   call Decho("setting s:treeforceredraw to true",'~'.expand("<slnum>"))
4849   let s:treeforceredraw = 1
4850
4851  else
4852   " ----------------------------------------
4853   " NetrwBrowseChgDir: Go down one directory {{{3
4854   " ----------------------------------------
4855   let dirname    = s:ComposePath(dirname,newdir)
4856"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">",'~'.expand("<slnum>"))
4857   NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4858   norm m`
4859  endif
4860
4861 " --------------------------------------
4862 " NetrwBrowseChgDir: Restore and Cleanup {{{3
4863 " --------------------------------------
4864  if dorestore
4865   " dorestore is zero'd when a local file was hidden or bufhidden;
4866   " in such a case, we want to keep whatever settings it may have.
4867"   call Decho("doing option restore (dorestore=".dorestore.")",'~'.expand("<slnum>"))
4868   NetrwKeepj call s:NetrwOptionRestore("s:")
4869"  else " Decho
4870"   call Decho("skipping option restore (dorestore==0): hidden=".&hidden." bufhidden=".&bufhidden." mod=".&mod,'~'.expand("<slnum>"))
4871  endif
4872  call s:RestorePosn(s:netrw_nbcd)
4873  if dolockout && dorestore
4874"   call Decho("restore: filewritable(dirname<".dirname.">)=".filewritable(dirname),'~'.expand("<slnum>"))
4875   if filewritable(dirname)
4876"    call Decho("restore: doing modification lockout settings: ma nomod noro",'~'.expand("<slnum>"))
4877"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
4878    setl ma noro nomod
4879"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4880   else
4881"    call Decho("restore: doing modification lockout settings: ma nomod ro",'~'.expand("<slnum>"))
4882"    call Decho("restore: setl ma nomod noro",'~'.expand("<slnum>"))
4883    setl ma ro nomod
4884"    call Decho("restore: ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
4885   endif
4886  endif
4887  let @@= ykeep
4888
4889"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
4890  return dirname
4891endfun
4892
4893" ---------------------------------------------------------------------
4894" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
4895"    for thin, long, and wide: cursor placed just after banner
4896"    for tree, keeps cursor on current filename
4897fun! s:NetrwBrowseUpDir(islocal)
4898"  call Dfunc("s:NetrwBrowseUpDir(islocal=".a:islocal.")")
4899  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
4900   " this test needed because occasionally this function seems to be incorrectly called
4901   " when multiple leftmouse clicks are taken when atop the one line help in the banner.
4902   " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
4903   " directories.
4904"   call Dret("s:NetrwBrowseUpDir : cursor not in file area")
4905   return
4906  endif
4907
4908  if !exists("w:netrw_liststyle") || w:netrw_liststyle != s:TREELIST
4909   call s:SavePosn(s:netrw_nbcd)
4910  endif
4911
4912  norm! 0
4913  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4914"   call Decho("case: treestyle",'~'.expand("<slnum>"))
4915   let curline= getline(".")
4916   let swwline= winline() - 1
4917   if exists("w:netrw_treetop")
4918    let b:netrw_curdir= w:netrw_treetop
4919   endif
4920   let curdir= b:netrw_curdir
4921   if a:islocal
4922    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
4923   else
4924    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
4925   endif
4926   if !search('\c^'.s:treedepthstring.curline,'cw')
4927    if !search('\c^'.curline,'cw')
4928     sil! NetrwKeepj 1
4929    endif
4930   endif
4931   exe "sil! NetrwKeepj norm! z\<cr>"
4932   while winline() < swwline
4933    let curwinline= winline()
4934    exe "sil! NetrwKeepj norm! \<c-y>"
4935    if curwinline == winline()
4936     break
4937    endif
4938   endwhile
4939  else
4940"   call Decho("case: not treestyle",'~'.expand("<slnum>"))
4941   if exists("b:netrw_curdir")
4942    let curdir= b:netrw_curdir
4943   else
4944    let curdir= expand(getcwd())
4945   endif
4946   if a:islocal
4947    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../'))
4948   else
4949    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../'))
4950   endif
4951   if has_key(s:netrw_nbcd,bufnr("%"))
4952    call s:RestorePosn(s:netrw_nbcd)
4953   elseif exists("w:netrw_bannercnt")
4954"    call Decho("moving to line#".w:netrw_bannercnt,'~'.expand("<slnum>"))
4955    exe w:netrw_bannercnt
4956   else
4957    1
4958   endif
4959  endif
4960  let curdir= substitute(curdir,'^.*[\/]','','')
4961  call search('\<'.curdir.'\>','wc')
4962"  call Dret("s:NetrwBrowseUpDir")
4963endfun
4964
4965" ---------------------------------------------------------------------
4966" netrw#BrowseX:  (implements "x") executes a special "viewer" script or program for the {{{2
4967"              given filename; typically this means given their extension.
4968"              0=local, 1=remote
4969fun! netrw#BrowseX(fname,remote)
4970"  call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.")")
4971
4972  " if its really just a directory, then do a "gf" instead
4973  if (a:remote == 0 && isdirectory(a:fname)) || (a:remote == 1 && fname =~ '/$' && fname !~ '^https\=:')
4974   norm! gf
4975"   call Dret("netrw#BrowseX : did gf instead")
4976  endif
4977
4978
4979  let ykeep      = @@
4980  let screenposn = winsaveview()
4981"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
4982
4983  " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
4984  let awkeep     = &aw
4985  set noaw
4986
4987  " special core dump handler
4988  if a:fname =~ '/core\(\.\d\+\)\=$'
4989   if exists("g:Netrw_corehandler")
4990    if type(g:Netrw_corehandler) == 2
4991     " g:Netrw_corehandler is a function reference (see :help Funcref)
4992"     call Decho("g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
4993     call g:Netrw_corehandler(s:NetrwFile(a:fname))
4994    elseif type(g:Netrw_corehandler) == 3
4995     " g:Netrw_corehandler is a List of function references (see :help Funcref)
4996"     call Decho("g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
4997     for Fncref in g:Netrw_corehandler
4998      if type(FncRef) == 2
4999       call FncRef(a:fname)
5000      endif
5001     endfor
5002    endif
5003"    call Decho("restoring posn to screenposn<".string(screenposn).">,'~'.expand("<slnum>"))"
5004    call winrestview(screenposn)
5005    let @@= ykeep
5006    let &aw= awkeep
5007"    call Dret("netrw#BrowseX : coredump handler invoked")
5008    return
5009   endif
5010  endif
5011
5012  " set up the filename
5013  " (lower case the extension, make a local copy of a remote file)
5014  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5015  if has("win32") || has("win95") || has("win64") || has("win16")
5016   let exten= substitute(exten,'^.*$','\L&\E','')
5017  endif
5018"  call Decho("exten<".exten.">",'~'.expand("<slnum>"))
5019
5020  if a:remote == 1
5021   " create a local copy
5022"   call Decho("remote: a:remote=".a:remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
5023   setl bh=delete
5024   call netrw#NetRead(3,a:fname)
5025   " attempt to rename tempfile
5026   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5027   let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5028"   call Decho("basename<".basename.">",'~'.expand("<slnum>"))
5029"   call Decho("newname <".newname.">",'~'.expand("<slnum>"))
5030   if rename(s:netrw_tmpfile,newname) == 0
5031    " renaming succeeded
5032    let fname= newname
5033   else
5034    " renaming failed
5035    let fname= s:netrw_tmpfile
5036   endif
5037  else
5038"   call Decho("local: a:remote=".a:remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
5039   let fname= a:fname
5040   " special ~ handler for local
5041   if fname =~ '^\~' && expand("$HOME") != ""
5042"    call Decho('invoking special ~ handler','~'.expand("<slnum>"))
5043    let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5044   endif
5045  endif
5046"  call Decho("fname<".fname.">",'~'.expand("<slnum>"))
5047"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
5048
5049  " set up redirection (avoids browser messages)
5050  " by default, g:netrw_suppress_gx_mesg is true
5051  if g:netrw_suppress_gx_mesg
5052   if &srr =~ "%s"
5053    if (has("win32") || has("win95") || has("win64") || has("win16"))
5054     let redir= substitute(&srr,"%s","nul","")
5055    else
5056     let redir= substitute(&srr,"%s","/dev/null","")
5057    endif
5058   elseif (has("win32") || has("win95") || has("win64") || has("win16"))
5059    let redir= &srr . "nul"
5060   else
5061    let redir= &srr . "/dev/null"
5062   endif
5063  endif
5064"  call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
5065
5066  " extract any viewing options.  Assumes that they're set apart by quotes.
5067"  call Decho("extract any viewing options",'~'.expand("<slnum>"))
5068  if exists("g:netrw_browsex_viewer")
5069"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5070   if g:netrw_browsex_viewer =~ '\s'
5071    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5072    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5073    let oviewer = ''
5074    let cnt     = 1
5075    while !executable(viewer) && viewer != oviewer
5076     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5077     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5078     let cnt     = cnt + 1
5079     let oviewer = viewer
5080"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5081    endwhile
5082   else
5083    let viewer  = g:netrw_browsex_viewer
5084    let viewopt = ""
5085   endif
5086"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">",'~'.expand("<slnum>"))
5087  endif
5088
5089  " execute the file handler
5090"  call Decho("execute the file handler (if any)",'~'.expand("<slnum>"))
5091  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
5092"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5093   let ret= netrwFileHandlers#Invoke(exten,fname)
5094
5095  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
5096"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5097   call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
5098   let ret= v:shell_error
5099
5100  elseif has("win32") || has("win64")
5101"   call Decho("windows",'~'.expand("<slnum>"))
5102   if executable("start")
5103    call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5104   elseif executable("rundll32")
5105    call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
5106   else
5107    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5108   endif
5109   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
5110   let ret= v:shell_error
5111
5112  elseif has("win32unix")
5113   let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
5114"   call Decho("cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
5115   if executable("start")
5116    call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5117   elseif executable("rundll32")
5118    call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
5119   elseif executable("cygstart")
5120    call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
5121   else
5122    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
5123   endif
5124   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
5125   let ret= v:shell_error
5126
5127  elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
5128"   call Decho("unix and kfmclient",'~'.expand("<slnum>"))
5129   call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
5130   let ret= v:shell_error
5131
5132  elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
5133"   call Decho("unix, exo-open, xdg-open",'~'.expand("<slnum>"))
5134   call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir)
5135   let ret= v:shell_error
5136
5137  elseif has("unix") && executable("xdg-open")
5138"   call Decho("unix and xdg-open",'~'.expand("<slnum>"))
5139   call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir)
5140   let ret= v:shell_error
5141
5142  elseif has("macunix") && executable("open")
5143"   call Decho("macunix and open",'~'.expand("<slnum>"))
5144   call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
5145   let ret= v:shell_error
5146
5147  else
5148   " netrwFileHandlers#Invoke() always returns 0
5149   let ret= netrwFileHandlers#Invoke(exten,fname)
5150  endif
5151
5152  " if unsuccessful, attempt netrwFileHandlers#Invoke()
5153  if ret
5154   let ret= netrwFileHandlers#Invoke(exten,fname)
5155  endif
5156
5157  " restoring redraw! after external file handlers
5158  redraw!
5159
5160  " cleanup: remove temporary file,
5161  "          delete current buffer if success with handler,
5162  "          return to prior buffer (directory listing)
5163  "          Feb 12, 2008: had to de-activiate removal of
5164  "          temporary file because it wasn't getting seen.
5165"  if a:remote == 1 && fname != a:fname
5166""   call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
5167"   call s:NetrwDelete(fname)
5168"  endif
5169
5170  if a:remote == 1
5171   setl bh=delete bt=nofile
5172   if g:netrw_use_noswf
5173    setl noswf
5174   endif
5175   exe "sil! NetrwKeepj norm! \<c-o>"
5176"   redraw!
5177  endif
5178"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
5179  call winrestview(screenposn)
5180  let @@ = ykeep
5181  let &aw= awkeep
5182
5183"  call Dret("netrw#BrowseX")
5184endfun
5185
5186" ---------------------------------------------------------------------
5187" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5188fun! netrw#BrowseXVis()
5189"  call Dfunc("netrw#BrowseXVis()")
5190  let atkeep = @@
5191  norm! gvy
5192"  call Decho("@@<".@@.">",'~'.expand("<slnum>"))
5193  call netrw#BrowseX(@@,netrw#CheckIfRemote())
5194  let @@     = atkeep
5195"  call Dret("netrw#BrowseXVis")
5196endfun
5197
5198" ---------------------------------------------------------------------
5199" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5200fun! netrw#CheckIfRemote()
5201"  call Dfunc("netrw#CheckIfRemote()")
5202  if expand("%") =~ '^\a\{3,}://'
5203"   call Dret("netrw#CheckIfRemote 1")
5204   return 1
5205  else
5206"   call Dret("netrw#CheckIfRemote 0")
5207   return 0
5208  endif
5209endfun
5210
5211" ---------------------------------------------------------------------
5212" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5213fun! s:NetrwChgPerm(islocal,curdir)
5214"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
5215  let ykeep  = @@
5216  call inputsave()
5217  let newperm= input("Enter new permission: ")
5218  call inputrestore()
5219  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5220  let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5221"  call Decho("chgperm<".chgperm.">",'~'.expand("<slnum>"))
5222  call system(chgperm)
5223  if v:shell_error != 0
5224   NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5225  endif
5226  if a:islocal
5227   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5228  endif
5229  let @@= ykeep
5230"  call Dret("s:NetrwChgPerm")
5231endfun
5232
5233" ---------------------------------------------------------------------
5234" s:CheckIfKde: checks if kdeinit is running {{{2
5235"    Returns 0: kdeinit not running
5236"            1: kdeinit is  running
5237fun! s:CheckIfKde()
5238"  call Dfunc("s:CheckIfKde()")
5239  " seems kde systems often have gnome-open due to dependencies, even though
5240  " gnome-open's subsidiary display tools are largely absent.  Kde systems
5241  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
5242  if !exists("s:haskdeinit")
5243   if has("unix") && executable("ps") && !has("win32unix")
5244    let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5245    if v:shell_error
5246     let s:haskdeinit = 0
5247    endif
5248   else
5249    let s:haskdeinit= 0
5250   endif
5251"   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5252  endif
5253
5254"  call Dret("s:CheckIfKde ".s:haskdeinit)
5255  return s:haskdeinit
5256endfun
5257
5258" ---------------------------------------------------------------------
5259" s:NetrwClearExplore: clear explore variables (if any) {{{2
5260fun! s:NetrwClearExplore()
5261"  call Dfunc("s:NetrwClearExplore()")
5262  2match none
5263  if exists("s:explore_match")        |unlet s:explore_match        |endif
5264  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
5265  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5266  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
5267  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
5268  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
5269  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5270  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
5271  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
5272"   redraw!
5273  echo " "
5274  echo " "
5275"  call Dret("s:NetrwClearExplore")
5276endfun
5277
5278" ---------------------------------------------------------------------
5279" s:NetrwExploreListUniq: {{{2
5280fun! s:NetrwExploreListUniq(explist)
5281"  call Dfunc("s:NetrwExploreListUniq(explist<".string(a:explist).">)")
5282
5283  " this assumes that the list is already sorted
5284  let newexplist= []
5285  for member in a:explist
5286   if !exists("uniqmember") || member != uniqmember
5287    let uniqmember = member
5288    let newexplist = newexplist + [ member ]
5289   endif
5290  endfor
5291
5292"  call Dret("s:NetrwExploreListUniq newexplist<".string(newexplist).">")
5293  return newexplist
5294endfun
5295
5296" ---------------------------------------------------------------------
5297" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5298fun! s:NetrwForceChgDir(islocal,newdir)
5299"  call Dfunc("s:NetrwForceChgDir(islocal=".a:islocal." newdir<".a:newdir.">)")
5300  let ykeep= @@
5301  if a:newdir !~ '/$'
5302   " ok, looks like force is needed to get directory-style treatment
5303   if a:newdir =~ '@$'
5304    let newdir= substitute(a:newdir,'@$','/','')
5305   elseif a:newdir =~ '[*=|\\]$'
5306    let newdir= substitute(a:newdir,'.$','/','')
5307   else
5308    let newdir= a:newdir.'/'
5309   endif
5310"   call Decho("adjusting newdir<".newdir."> due to gd",'~'.expand("<slnum>"))
5311  else
5312   " should already be getting treatment as a directory
5313   let newdir= a:newdir
5314  endif
5315  let newdir= s:NetrwBrowseChgDir(a:islocal,newdir)
5316  call s:NetrwBrowse(a:islocal,newdir)
5317  let @@= ykeep
5318"  call Dret("s:NetrwForceChgDir")
5319endfun
5320
5321" ---------------------------------------------------------------------
5322" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5323"     direntry: this is the name of the directory.  Will be fnameescape'd to prevent wildcard handling by glob()
5324"     expr    : this is the expression to follow the directory.  Will use s:ComposePath()
5325"     pare    =1: remove the current directory from the resulting glob() filelist
5326"             =0: leave  the current directory   in the resulting glob() filelist
5327fun! s:NetrwGlob(direntry,expr,pare)
5328"  call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")")
5329  if netrw#CheckIfRemote()
5330   keepalt 1sp
5331   keepalt enew
5332   let keep_liststyle    = w:netrw_liststyle
5333   let w:netrw_liststyle = s:THINLIST
5334   if s:NetrwRemoteListing() == 0
5335    keepj keepalt %s@/@@
5336    let filelist= getline(1,$)
5337    q!
5338   else
5339    " remote listing error -- leave treedict unchanged
5340    let filelist= w:netrw_treedict[a:direntry]
5341   endif
5342   let w:netrw_liststyle= keep_liststyle
5343  elseif v:version > 704 || (v:version == 704 && has("patch656"))
5344   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1,1)
5345   if a:pare
5346    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5347   endif
5348  else
5349   let filelist= glob(s:ComposePath(fnameescape(a:direntry),a:expr),0,1)
5350   if a:pare
5351    let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5352   endif
5353  endif
5354"  call Dret("s:NetrwGlob ".string(filelist))
5355  return filelist
5356endfun
5357
5358" ---------------------------------------------------------------------
5359" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5360fun! s:NetrwForceFile(islocal,newfile)
5361"  call Dfunc("s:NetrwForceFile(islocal=".a:islocal." newdir<".a:newfile.">)")
5362  if a:newfile =~ '[/@*=|\\]$'
5363   let newfile= substitute(a:newfile,'.$','','')
5364  else
5365   let newfile= a:newfile
5366  endif
5367  if a:islocal
5368   call s:NetrwBrowseChgDir(a:islocal,newfile)
5369  else
5370   call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile))
5371  endif
5372"  call Dret("s:NetrwForceFile")
5373endfun
5374
5375" ---------------------------------------------------------------------
5376" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5377"          and switches the hiding mode.  The actual hiding is done by
5378"          s:NetrwListHide().
5379"             g:netrw_hide= 0: show all
5380"                           1: show not-hidden files
5381"                           2: show hidden files only
5382fun! s:NetrwHide(islocal)
5383"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
5384  let ykeep= @@
5385  let svpos= winsaveview()
5386"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5387
5388  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5389"   call Decho("((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">",'~'.expand("<slnum>"))
5390"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5391
5392   " hide the files in the markfile list
5393   for fname in s:netrwmarkfilelist_{bufnr("%")}
5394"    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>"))
5395    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5396     " remove fname from hiding list
5397     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5398     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5399     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5400"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5401    else
5402     " append fname to hiding list
5403     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5404      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5405     else
5406      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5407     endif
5408"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5409    endif
5410   endfor
5411   NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5412   let g:netrw_hide= 1
5413
5414  else
5415
5416   " switch between show-all/show-not-hidden/show-hidden
5417   let g:netrw_hide=(g:netrw_hide+1)%3
5418   exe "NetrwKeepj norm! 0"
5419   if g:netrw_hide && g:netrw_list_hide == ""
5420    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5421    let @@= ykeep
5422"    call Dret("NetrwHide")
5423    return
5424   endif
5425  endif
5426
5427  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5428"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5429  NetrwKeepj call winrestview(svpos)
5430  let @@= ykeep
5431"  call Dret("NetrwHide")
5432endfun
5433
5434" ---------------------------------------------------------------------
5435" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5436fun! s:NetrwHideEdit(islocal)
5437"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
5438
5439  let ykeep= @@
5440  " save current cursor position
5441  let svpos= winsaveview()
5442"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5443
5444  " get new hiding list from user
5445  call inputsave()
5446  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5447  call inputrestore()
5448  let g:netrw_list_hide= newhide
5449"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
5450
5451  " refresh the listing
5452  sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
5453
5454  " restore cursor position
5455"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5456  call winrestview(svpos)
5457  let @@= ykeep
5458
5459"  call Dret("NetrwHideEdit")
5460endfun
5461
5462" ---------------------------------------------------------------------
5463" s:NetrwHidden: invoked by "gh" {{{2
5464fun! s:NetrwHidden(islocal)
5465"  call Dfunc("s:NetrwHidden()")
5466  let ykeep= @@
5467  "  save current position
5468  let svpos= winsaveview()
5469"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5470
5471  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5472   " remove pattern from hiding list
5473   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5474  elseif s:Strlen(g:netrw_list_hide) >= 1
5475   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5476  else
5477   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5478  endif
5479
5480  " refresh screen and return to saved position
5481  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5482"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5483  NetrwKeepj call winrestview(svpos)
5484  let @@= ykeep
5485"  call Dret("s:NetrwHidden")
5486endfun
5487
5488" ---------------------------------------------------------------------
5489"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5490fun! s:NetrwHome()
5491  if exists("g:netrw_home")
5492   let home= g:netrw_home
5493  else
5494   " go to vim plugin home
5495   for home in split(&rtp,',') + ['']
5496    if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5497     let basehome= substitute(home,'[/\\]\.vim$','','')
5498     if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5499     let home= basehome."/.vim"
5500     break
5501    endif
5502   endfor
5503   if home == ""
5504    " just pick the first directory
5505    let home= substitute(&rtp,',.*$','','')
5506   endif
5507   if (has("win32") || has("win95") || has("win64") || has("win16"))
5508    let home= substitute(home,'/','\\','g')
5509   endif
5510  endif
5511  " insure that the home directory exists
5512  if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5513   if exists("g:netrw_mkdir")
5514    call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5515   else
5516    call mkdir(home)
5517   endif
5518  endif
5519  let g:netrw_home= home
5520  return home
5521endfun
5522
5523" ---------------------------------------------------------------------
5524" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5525fun! s:NetrwLeftmouse(islocal)
5526  if exists("s:netrwdrag")
5527   return
5528  endif
5529"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
5530
5531  let ykeep= @@
5532  " check if the status bar was clicked on instead of a file/directory name
5533  while getchar(0) != 0
5534   "clear the input stream
5535  endwhile
5536  call feedkeys("\<LeftMouse>")
5537  let c          = getchar()
5538  let mouse_lnum = v:mouse_lnum
5539  let wlastline  = line('w$')
5540  let lastline   = line('$')
5541"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr(),'~'.expand("<slnum>"))
5542"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0),'~'.expand("<slnum>"))
5543  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5544   " appears to be a status bar leftmouse click
5545   let @@= ykeep
5546"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
5547   return
5548  endif
5549   " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5550   " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5551   " without this test when its disabled.
5552   " May 26, 2014: edit file, :Lex, resize window -- causes refresh.  Reinstated a modified test.  See if problems develop.
5553"   call Decho("v:mouse_col=".v:mouse_col." col#".col('.')." virtcol#".virtcol('.')." col($)#".col("$")." virtcol($)#".virtcol("$"),'~'.expand("<slnum>"))
5554   if v:mouse_col > virtcol('.')
5555    let @@= ykeep
5556"    call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
5557    return
5558   endif
5559
5560  if a:islocal
5561   if exists("b:netrw_curdir")
5562    NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
5563   endif
5564  else
5565   if exists("b:netrw_curdir")
5566    NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5567   endif
5568  endif
5569  let @@= ykeep
5570"  call Dret("s:NetrwLeftmouse")
5571endfun
5572
5573" ---------------------------------------------------------------------
5574" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5575fun! s:NetrwCLeftmouse(islocal)
5576"  call Dfunc("s:NetrwCLeftmouse(islocal=".a:islocal.")")
5577  call s:NetrwMarkFileTgt(a:islocal)
5578"  call Dret("s:NetrwCLeftmouse")
5579endfun
5580
5581" ---------------------------------------------------------------------
5582" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER  (implements <c-r>){{{2
5583"   a:islocal=0 : <c-r> not used, remote
5584"   a:islocal=1 : <c-r> no  used, local
5585"   a:islocal=2 : <c-r>     used, remote
5586"   a:islocal=3 : <c-r>     used, local
5587fun! s:NetrwServerEdit(islocal,fname)
5588"  call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5589  let islocal = a:islocal%2      " =0: remote           =1: local
5590  let ctrlr   = a:islocal >= 2   " =0: <c-r> not used   =1: <c-r> used
5591"  call Decho("islocal=".islocal." ctrlr=".ctrlr,'~'.expand("<slnum>"))
5592
5593  if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5594   " handle directories in the local window -- not in the remote vim server
5595   " user must have closed the NETRWSERVER window.  Treat as normal editing from netrw.
5596"   call Decho("handling directory in client window",'~'.expand("<slnum>"))
5597   let g:netrw_browse_split= 0
5598   if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
5599    let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5600    unlet s:netrw_browse_split_{winnr()}
5601   endif
5602   call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5603"   call Dret("s:NetrwServerEdit")
5604   return
5605  endif
5606
5607"  call Decho("handling file in server window",'~'.expand("<slnum>"))
5608  if has("clientserver") && executable("gvim")
5609"   call Decho("has clientserver and gvim",'~'.expand("<slnum>"))
5610
5611    if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
5612"     call Decho("g:netrw_browse_split=".string(g:netrw_browse_split),'~'.expand("<slnum>"))
5613     let srvrname = g:netrw_browse_split[0]
5614     let tabnum   = g:netrw_browse_split[1]
5615     let winnum   = g:netrw_browse_split[2]
5616
5617     if serverlist() !~ '\<'.srvrname.'\>'
5618"      call Decho("server not available; ctrlr=".ctrlr,'~'.expand("<slnum>"))
5619
5620      if !ctrlr
5621       " user must have closed the server window and the user did not use <c-r>, but
5622       " used something like <cr>.
5623"       call Decho("user must have closed server AND did not use ctrl-r",'~'.expand("<slnum>"))
5624       if exists("g:netrw_browse_split")
5625	unlet g:netrw_browse_split
5626       endif
5627       let g:netrw_browse_split= 0
5628       if exists("s:netrw_browse_split_".winnr())
5629        let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5630       endif
5631       call s:NetrwBrowseChgDir(islocal,a:fname)
5632"       call Dret("s:NetrwServerEdit")
5633       return
5634
5635      elseif has("win32") && executable("start")
5636       " start up remote netrw server under windows
5637"       call Decho("starting up gvim server<".srvrname."> for windows",'~'.expand("<slnum>"))
5638       call system("start gvim --servername ".srvrname)
5639
5640      else
5641       " start up remote netrw server under linux
5642"       call Decho("starting up gvim server<".srvrname.">",'~'.expand("<slnum>"))
5643       call system("gvim --servername ".srvrname)
5644      endif
5645     endif
5646
5647"     call Decho("srvrname<".srvrname."> tabnum=".tabnum." winnum=".winnum." server-editing<".a:fname.">",'~'.expand("<slnum>"))
5648     call remote_send(srvrname,":tabn ".tabnum."\<cr>")
5649     call remote_send(srvrname,":".winnum."wincmd w\<cr>")
5650     call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5651
5652    else
5653
5654     if serverlist() !~ '\<'.g:netrw_servername.'\>'
5655
5656      if !ctrlr
5657"       call Decho("server<".g:netrw_servername."> not available and ctrl-r not used",'~'.expand("<slnum>"))
5658       if exists("g:netrw_browse_split")
5659	unlet g:netrw_browse_split
5660       endif
5661       let g:netrw_browse_split= 0
5662       call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname))
5663"       call Dret("s:NetrwServerEdit")
5664       return
5665
5666      else
5667"       call Decho("server<".g:netrw_servername."> not available but ctrl-r used",'~'.expand("<slnum>"))
5668       if has("win32") && executable("start")
5669        " start up remote netrw server under windows
5670"        call Decho("starting up gvim server<".g:netrw_servername."> for windows",'~'.expand("<slnum>"))
5671        call system("start gvim --servername ".g:netrw_servername)
5672       else
5673        " start up remote netrw server under linux
5674"        call Decho("starting up gvim server<".g:netrw_servername.">",'~'.expand("<slnum>"))
5675        call system("gvim --servername ".g:netrw_servername)
5676       endif
5677      endif
5678     endif
5679
5680     while 1
5681      try
5682"       call Decho("remote-send: e ".a:fname,'~'.expand("<slnum>"))
5683       call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5684       break
5685      catch /^Vim\%((\a\+)\)\=:E241/
5686       sleep 200m
5687      endtry
5688     endwhile
5689
5690     if exists("g:netrw_browse_split")
5691      if type(g:netrw_browse_split) != 3
5692        let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
5693       endif
5694      unlet g:netrw_browse_split
5695     endif
5696     let g:netrw_browse_split= [g:netrw_servername,1,1]
5697    endif
5698
5699   else
5700    call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
5701   endif
5702
5703"  call Dret("s:NetrwServerEdit")
5704endfun
5705
5706" ---------------------------------------------------------------------
5707" s:NetrwSLeftmouse: marks the file under the cursor.  May be dragged to select additional files {{{2
5708fun! s:NetrwSLeftmouse(islocal)
5709"  call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
5710
5711  let s:ngw= s:NetrwGetWord()
5712  call s:NetrwMarkFile(a:islocal,s:ngw)
5713
5714"  call Dret("s:NetrwSLeftmouse")
5715endfun
5716
5717" ---------------------------------------------------------------------
5718" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
5719"                   Used to mark multiple files.
5720fun! s:NetrwSLeftdrag(islocal)
5721"  call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
5722  if !exists("s:netrwdrag")
5723   let s:netrwdrag = winnr()
5724   if a:islocal
5725    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
5726   else
5727    nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
5728   endif
5729  endif
5730  let ngw = s:NetrwGetWord()
5731  if !exists("s:ngw") || s:ngw != ngw
5732   call s:NetrwMarkFile(a:islocal,ngw)
5733  endif
5734  let s:ngw= ngw
5735"  call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5736endfun
5737
5738" ---------------------------------------------------------------------
5739" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
5740fun! s:NetrwSLeftrelease(islocal)
5741"  call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5742  if exists("s:netrwdrag")
5743   nunmap <s-leftrelease>
5744   let ngw = s:NetrwGetWord()
5745   if !exists("s:ngw") || s:ngw != ngw
5746    call s:NetrwMarkFile(a:islocal,ngw)
5747   endif
5748   if exists("s:ngw")
5749    unlet s:ngw
5750   endif
5751   unlet s:netrwdrag
5752  endif
5753"  call Dret("s:NetrwSLeftrelease")
5754endfun
5755
5756" ---------------------------------------------------------------------
5757" s:NetrwListHide: uses [range]g~...~d to delete files that match comma {{{2
5758" separated patterns given in g:netrw_list_hide
5759fun! s:NetrwListHide()
5760"  call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
5761  let ykeep= @@
5762
5763  " find a character not in the "hide" string to use as a separator for :g and :v commands
5764  " How-it-works: take the hiding command, convert it into a range.  Duplicate
5765  " characters don't matter.  Remove all such characters from the '/~...90'
5766  " string.  Use the first character left as a separator character.
5767  let listhide= g:netrw_list_hide
5768  let sep     = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
5769"  call Decho("sep=".sep,'~'.expand("<slnum>"))
5770
5771  while listhide != ""
5772   if listhide =~ ','
5773    let hide     = substitute(listhide,',.*$','','e')
5774    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
5775   else
5776    let hide     = listhide
5777    let listhide = ""
5778   endif
5779
5780   " Prune the list by hiding any files which match
5781   if g:netrw_hide == 1
5782"    call Decho("hiding<".hide."> listhide<".listhide.">",'~'.expand("<slnum>"))
5783    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
5784   elseif g:netrw_hide == 2
5785"    call Decho("showing<".hide."> listhide<".listhide.">",'~'.expand("<slnum>"))
5786    exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
5787   endif
5788  endwhile
5789  if g:netrw_hide == 2
5790   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
5791   exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
5792  endif
5793
5794  " remove any blank lines that have somehow remained.
5795  " This seems to happen under Windows.
5796  exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
5797
5798  let @@= ykeep
5799"  call Dret("s:NetrwListHide")
5800endfun
5801
5802" ---------------------------------------------------------------------
5803" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
5804"                 implements the "d" mapping.
5805fun! s:NetrwMakeDir(usrhost)
5806"  call Dfunc("s:NetrwMakeDir(usrhost<".a:usrhost.">)")
5807
5808  let ykeep= @@
5809  " get name of new directory from user.  A bare <CR> will skip.
5810  " if its currently a directory, also request will be skipped, but with
5811  " a message.
5812  call inputsave()
5813  let newdirname= input("Please give directory name: ")
5814  call inputrestore()
5815"  call Decho("newdirname<".newdirname.">",'~'.expand("<slnum>"))
5816
5817  if newdirname == ""
5818   let @@= ykeep
5819"   call Dret("s:NetrwMakeDir : user aborted with bare <cr>")
5820   return
5821  endif
5822
5823  if a:usrhost == ""
5824"   call Decho("local mkdir",'~'.expand("<slnum>"))
5825
5826   " Local mkdir:
5827   " sanity checks
5828   let fullnewdir= b:netrw_curdir.'/'.newdirname
5829"   call Decho("fullnewdir<".fullnewdir.">",'~'.expand("<slnum>"))
5830   if isdirectory(s:NetrwFile(fullnewdir))
5831    if !exists("g:netrw_quiet")
5832     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
5833    endif
5834    let @@= ykeep
5835"    call Dret("s:NetrwMakeDir : directory<".newdirname."> exists previously")
5836    return
5837   endif
5838   if s:FileReadable(fullnewdir)
5839    if !exists("g:netrw_quiet")
5840     NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
5841    endif
5842    let @@= ykeep
5843"    call Dret("s:NetrwMakeDir : file<".newdirname."> exists previously")
5844    return
5845   endif
5846
5847   " requested new local directory is neither a pre-existing file or
5848   " directory, so make it!
5849   if exists("*mkdir")
5850    if has("unix")
5851     call mkdir(fullnewdir,"p",xor(0777, system("umask")))
5852    else
5853     call mkdir(fullnewdir,"p")
5854    endif
5855   else
5856    let netrw_origdir= s:NetrwGetcwd(1)
5857    call s:NetrwLcd(b:netrw_curdir)
5858"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">",'~'.expand("<slnum>"))
5859    call s:NetrwExe("sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
5860    if v:shell_error != 0
5861     let @@= ykeep
5862     call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
5863"     call Dret("s:NetrwMakeDir : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(newdirname,1))
5864     return
5865    endif
5866    if !g:netrw_keepdir
5867"     call Decho("restoring netrw_origdir since g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
5868     call s:NetrwLcd(netrw_origdir)
5869    endif
5870   endif
5871
5872   if v:shell_error == 0
5873    " refresh listing
5874"    call Decho("refresh listing",'~'.expand("<slnum>"))
5875    let svpos= winsaveview()
5876"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5877    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
5878"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5879    call winrestview(svpos)
5880   elseif !exists("g:netrw_quiet")
5881    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
5882   endif
5883"   redraw!
5884
5885  elseif !exists("b:netrw_method") || b:netrw_method == 4
5886   " Remote mkdir:  using ssh
5887"   call Decho("remote mkdir",'~'.expand("<slnum>"))
5888   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
5889   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
5890   call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
5891   if v:shell_error == 0
5892    " refresh listing
5893    let svpos= winsaveview()
5894"    call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5895    NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5896"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5897    NetrwKeepj call winrestview(svpos)
5898   elseif !exists("g:netrw_quiet")
5899    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
5900   endif
5901"   redraw!
5902
5903  elseif b:netrw_method == 2
5904   " Remote mkdir:  using ftp+.netrc
5905   let svpos= winsaveview()
5906"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5907"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
5908   if exists("b:netrw_fname")
5909"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
5910    let remotepath= b:netrw_fname
5911   else
5912    let remotepath= ""
5913   endif
5914   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
5915   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5916"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5917   NetrwKeepj call winrestview(svpos)
5918
5919  elseif b:netrw_method == 3
5920   " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
5921   let svpos= winsaveview()
5922"   call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5923"   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
5924   if exists("b:netrw_fname")
5925"    call Decho("b:netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
5926    let remotepath= b:netrw_fname
5927   else
5928    let remotepath= ""
5929   endif
5930   call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
5931   NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
5932"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
5933   NetrwKeepj call winrestview(svpos)
5934  endif
5935
5936  let @@= ykeep
5937"  call Dret("s:NetrwMakeDir")
5938endfun
5939
5940" ---------------------------------------------------------------------
5941" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
5942fun! s:TreeSqueezeDir(islocal)
5943"  call Dfunc("s:TreeSqueezeDir(islocal=".a:islocal.")")
5944  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
5945   " its a tree-listing style
5946   let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
5947   let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
5948   let depth    = strchars(substitute(curdepth,' ','','g'))
5949   let srch     = -1
5950"   call Decho("curdepth<".curdepth.'>','~'.expand("<slnum>"))
5951"   call Decho("depth   =".depth,'~'.expand("<slnum>"))
5952"   call Decho("stopline#".stopline,'~'.expand("<slnum>"))
5953"   call Decho("curline#".line(".")."<".getline('.').'>','~'.expand("<slnum>"))
5954   if depth >= 2
5955    NetrwKeepj norm! 0
5956    let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
5957    let srch      = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
5958"    call Decho("curdepthm1<".curdepthm1.'>','~'.expand("<slnum>"))
5959"    call Decho("case depth>=2: srch<".srch.'>','~'.expand("<slnum>"))
5960   elseif depth == 1
5961    NetrwKeepj norm! 0
5962    let treedepthchr= substitute(s:treedepthstring,' ','','')
5963    let srch        = search('^[^'.treedepthchr.']','bW',stopline)
5964"    call Decho("case depth==1: srch<".srch.'>','~'.expand("<slnum>"))
5965   endif
5966   if srch > 0
5967"    call Decho("squeezing at line#".line(".").": ".getline('.'),'~'.expand("<slnum>"))
5968    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord()))
5969    exe srch
5970   endif
5971  endif
5972"  call Dret("s:TreeSqueezeDir")
5973endfun
5974
5975" ---------------------------------------------------------------------
5976" s:NetrwMaps: {{{2
5977fun! s:NetrwMaps(islocal)
5978"  call Dfunc("s:NetrwMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
5979
5980  if g:netrw_mousemaps && g:netrw_retmap
5981"   call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
5982   if !hasmapto("<Plug>NetrwReturn")
5983    if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
5984"     call Decho("making map for 2-leftmouse",'~'.expand("<slnum>"))
5985     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
5986    elseif maparg("<c-leftmouse>","n") == ""
5987"     call Decho("making map for c-leftmouse",'~'.expand("<slnum>"))
5988     nmap <unique> <silent> <c-leftmouse>	<Plug>NetrwReturn
5989    endif
5990   endif
5991   nno <silent> <Plug>NetrwReturn	:Rexplore<cr>
5992"   call Decho("made <Plug>NetrwReturn map",'~'.expand("<slnum>"))
5993  endif
5994
5995  if a:islocal
5996"   call Decho("make local maps",'~'.expand("<slnum>"))
5997   " local normal-mode maps
5998   nnoremap <buffer> <silent> <nowait> a	:<c-u>call <SID>NetrwHide(1)<cr>
5999   nnoremap <buffer> <silent> <nowait> -	:<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6000   nnoremap <buffer> <silent> <nowait> %	:<c-u>call <SID>NetrwOpenFile(1)<cr>
6001   nnoremap <buffer> <silent> <nowait> c	:<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6002   nnoremap <buffer> <silent> <nowait> C	:<c-u>call <SID>NetrwSetChgwin()<cr>
6003   nnoremap <buffer> <silent> <nowait> <cr>	:<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6004   nnoremap <buffer> <silent> <nowait> <c-r>	:<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6005   nnoremap <buffer> <silent> <nowait> d	:<c-u>call <SID>NetrwMakeDir("")<cr>
6006   nnoremap <buffer> <silent> <nowait> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6007   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6008   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6009   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
6010   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr>
6011   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6012   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6013   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(1)<cr>
6014   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6015   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6016   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6017   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6018   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6019   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6020   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6021   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6022   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6023   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6024   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6025   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6026   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6027   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6028   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6029   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6030   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6031   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6032   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6033   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6034   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6035   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6036   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(1)<cr>
6037   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(3)<cr>
6038   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6039   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6040   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6041   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6042   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6043   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6044   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>
6045   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(1)<cr>
6046   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(1)<cr>
6047   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6048   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(4)<cr>
6049   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6050   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6051   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6052   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(5)<cr>
6053   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6054   nnoremap <buffer> <silent> <nowait> X	:<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6055"   " local insert-mode maps
6056"   inoremap <buffer> <silent> <nowait> a	<c-o>:call <SID>NetrwHide(1)<cr>
6057"   inoremap <buffer> <silent> <nowait> c	<c-o>:exe "NetrwKeepj lcd ".fnameescape(b:netrw_curdir)<cr>
6058"   inoremap <buffer> <silent> <nowait> c	<c-o>:call <SID>NetrwLcd(b:netrw_curdir)<cr>
6059"   inoremap <buffer> <silent> <nowait> C	<c-o>:call <SID>NetrwSetChgwin()<cr>
6060"   inoremap <buffer> <silent> <nowait> %	<c-o>:call <SID>NetrwOpenFile(1)<cr>
6061"   inoremap <buffer> <silent> <nowait> -	<c-o>:call <SID>NetrwBrowseUpDir(1)<cr>
6062"   inoremap <buffer> <silent> <nowait> <cr>	<c-o>:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
6063"   inoremap <buffer> <silent> <nowait> d	<c-o>:call <SID>NetrwMakeDir("")<cr>
6064"   inoremap <buffer> <silent> <nowait> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6065"   inoremap <buffer> <silent> <nowait> gh	<c-o>:<c-u>call <SID>NetrwHidden(1)<cr>
6066"   nnoremap <buffer> <silent> <nowait> gn	:<c-u>call netrw#SetTreetop(<SID>NetrwGetWord())<cr>
6067"   inoremap <buffer> <silent> <nowait> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6068"   inoremap <buffer> <silent> <nowait> I	<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
6069"   inoremap <buffer> <silent> <nowait> i	<c-o>:call <SID>NetrwListStyle(1)<cr>
6070"   inoremap <buffer> <silent> <nowait> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6071"   inoremap <buffer> <silent> <nowait> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6072"   inoremap <buffer> <silent> <nowait> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6073"   inoremap <buffer> <silent> <nowait> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6074"   inoremap <buffer> <silent> <nowait> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6075"   inoremap <buffer> <silent> <nowait> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6076"   inoremap <buffer> <silent> <nowait> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6077"   inoremap <buffer> <silent> <nowait> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6078"   inoremap <buffer> <silent> <nowait> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6079"   inoremap <buffer> <silent> <nowait> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6080"   inoremap <buffer> <silent> <nowait> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6081"   inoremap <buffer> <silent> <nowait> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6082"   inoremap <buffer> <silent> <nowait> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6083"   inoremap <buffer> <silent> <nowait> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6084"   inoremap <buffer> <silent> <nowait> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6085"   inoremap <buffer> <silent> <nowait> mv	<c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6086"   inoremap <buffer> <silent> <nowait> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6087"   inoremap <buffer> <silent> <nowait> mX	<c-o>:<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6088"   inoremap <buffer> <silent> <nowait> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6089"   inoremap <buffer> <silent> <nowait> O	<c-o>:call <SID>NetrwObtain(1)<cr>
6090"   inoremap <buffer> <silent> <nowait> o	<c-o>:call <SID>NetrwSplit(3)<cr>
6091"   inoremap <buffer> <silent> <nowait> p	<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6092"   inoremap <buffer> <silent> <nowait> P	<c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
6093"   inoremap <buffer> <silent> <nowait> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6094"   inoremap <buffer> <silent> <nowait> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6095"   inoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6096"   inoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6097"   inoremap <buffer> <silent> <nowait> r	<c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr>
6098"   inoremap <buffer> <silent> <nowait> s	<c-o>:call <SID>NetrwSortStyle(1)<cr>
6099"   inoremap <buffer> <silent> <nowait> S	<c-o>:call <SID>NetSortSequence(1)<cr>
6100"   inoremap <buffer> <silent> <nowait> t	<c-o>:call <SID>NetrwSplit(4)<cr>
6101"   inoremap <buffer> <silent> <nowait> Tb	<c-o>:<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6102"   inoremap <buffer> <silent> <nowait> Th	<c-o>:<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6103"   inoremap <buffer> <silent> <nowait> u	<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6104"   inoremap <buffer> <silent> <nowait> U	<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6105"   inoremap <buffer> <silent> <nowait> v	<c-o>:call <SID>NetrwSplit(5)<cr>
6106"   inoremap <buffer> <silent> <nowait> x	<c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
6107   if !hasmapto('<Plug>NetrwHideEdit')
6108    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6109"    imap <buffer> <unique> <c-h> <c-o><Plug>NetrwHideEdit
6110   endif
6111   nnoremap <buffer> <silent> <Plug>NetrwHideEdit		:call <SID>NetrwHideEdit(1)<cr>
6112   if !hasmapto('<Plug>NetrwRefresh')
6113    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6114"    imap <buffer> <unique> <c-l> <c-o><Plug>NetrwRefresh
6115   endif
6116   nnoremap <buffer> <silent> <Plug>NetrwRefresh		<c-l>:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(w:netrw_liststyle == 3)? w:netrw_treetop : './'))<cr>
6117   if s:didstarstar || !mapcheck("<s-down>","n")
6118    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
6119"    inoremap <buffer> <silent> <s-down>	<c-o>:Nexplore<cr>
6120   endif
6121   if s:didstarstar || !mapcheck("<s-up>","n")
6122    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
6123"    inoremap <buffer> <silent> <s-up>	<c-o>:Pexplore<cr>
6124   endif
6125   if !hasmapto('<Plug>NetrwTreeSqueeze')
6126    nmap <buffer> <silent> <nowait> <s-cr>			<Plug>NetrwTreeSqueeze
6127"    imap <buffer> <silent> <nowait> <s-cr>			<c-o><Plug>NetrwTreeSqueeze
6128   endif
6129   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze		:call <SID>TreeSqueezeDir(1)<cr>
6130   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6131   if g:netrw_mousemaps == 1
6132    nmap <buffer> <leftmouse>   				<Plug>NetrwLeftmouse
6133    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
6134    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6135    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(1)<cr>
6136    nmap <buffer> <middlemouse>		<Plug>NetrwMiddlemouse
6137    nno  <buffer> <silent>		<Plug>NetrwMiddlemouse	<leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
6138    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6139    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(1)<cr>
6140    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6141    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(1)<cr>
6142    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6143    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6144    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6145"    ino  <buffer> <silent>		<Plug>ILeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(1)<cr>
6146    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6147"    ino  <buffer> <silent>		<Plug>IMiddlemouse	<c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
6148"    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6149"    ino  <buffer> <silent>		<Plug>ISLeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6150    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6151    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6152"    exe 'inoremap <buffer> <silent> <rightmouse>  <c-o><leftmouse><c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6153   endif
6154   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6155   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6156   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6157   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("")<cr>'
6158   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6159   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6160   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6161"   exe 'inoremap <buffer> <silent> <nowait> <del>	<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6162"   exe 'inoremap <buffer> <silent> <nowait> D		<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6163"   exe 'inoremap <buffer> <silent> <nowait> R		<c-o>:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6164"   exe 'inoremap <buffer> <silent> <nowait> d		<c-o>:call <SID>NetrwMakeDir("")<cr>'
6165   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6166
6167   " support user-specified maps
6168   call netrw#UserMaps(1)
6169
6170  else " remote
6171"   call Decho("make remote maps",'~'.expand("<slnum>"))
6172   call s:RemotePathAnalysis(b:netrw_curdir)
6173   " remote normal-mode maps
6174   nnoremap <buffer> <silent> <nowait> a	:<c-u>call <SID>NetrwHide(0)<cr>
6175   nnoremap <buffer> <silent> <nowait> -	:<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6176   nnoremap <buffer> <silent> <nowait> %	:<c-u>call <SID>NetrwOpenFile(0)<cr>
6177   nnoremap <buffer> <silent> <nowait> C	:<c-u>call <SID>NetrwSetChgwin()<cr>
6178   nnoremap <buffer> <silent> <nowait> <c-l>	:<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6179   nnoremap <buffer> <silent> <nowait> <cr>	:<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6180   nnoremap <buffer> <silent> <nowait> <c-r>	:<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6181   nnoremap <buffer> <silent> <nowait> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6182   nnoremap <buffer> <silent> <nowait> gd	:<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6183   nnoremap <buffer> <silent> <nowait> gf	:<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6184   nnoremap <buffer> <silent> <nowait> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
6185   nnoremap <buffer> <silent> <nowait> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6186   nnoremap <buffer> <silent> <nowait> I	:<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6187   nnoremap <buffer> <silent> <nowait> i	:<c-u>call <SID>NetrwListStyle(0)<cr>
6188   nnoremap <buffer> <silent> <nowait> ma	:<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6189   nnoremap <buffer> <silent> <nowait> mA	:<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6190   nnoremap <buffer> <silent> <nowait> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6191   nnoremap <buffer> <silent> <nowait> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6192   nnoremap <buffer> <silent> <nowait> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6193   nnoremap <buffer> <silent> <nowait> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6194   nnoremap <buffer> <silent> <nowait> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6195   nnoremap <buffer> <silent> <nowait> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6196   nnoremap <buffer> <silent> <nowait> mF	:<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6197   nnoremap <buffer> <silent> <nowait> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6198   nnoremap <buffer> <silent> <nowait> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6199   nnoremap <buffer> <silent> <nowait> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6200   nnoremap <buffer> <silent> <nowait> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6201   nnoremap <buffer> <silent> <nowait> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6202   nnoremap <buffer> <silent> <nowait> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6203   nnoremap <buffer> <silent> <nowait> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6204   nnoremap <buffer> <silent> <nowait> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6205   nnoremap <buffer> <silent> <nowait> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6206   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6207   nnoremap <buffer> <silent> <nowait> mx	:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6208   nnoremap <buffer> <silent> <nowait> mX	:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6209   nnoremap <buffer> <silent> <nowait> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6210   nnoremap <buffer> <silent> <nowait> O	:<c-u>call <SID>NetrwObtain(0)<cr>
6211   nnoremap <buffer> <silent> <nowait> o	:call <SID>NetrwSplit(0)<cr>
6212   nnoremap <buffer> <silent> <nowait> p	:<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6213   nnoremap <buffer> <silent> <nowait> P	:<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6214   nnoremap <buffer> <silent> <nowait> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6215   nnoremap <buffer> <silent> <nowait> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6216   nnoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6217   nnoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6218   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>
6219   nnoremap <buffer> <silent> <nowait> s	:call <SID>NetrwSortStyle(0)<cr>
6220   nnoremap <buffer> <silent> <nowait> S	:<c-u>call <SID>NetSortSequence(0)<cr>
6221   nnoremap <buffer> <silent> <nowait> Tb	:<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6222   nnoremap <buffer> <silent> <nowait> t	:call <SID>NetrwSplit(1)<cr>
6223   nnoremap <buffer> <silent> <nowait> Th	:<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6224   nnoremap <buffer> <silent> <nowait> u	:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6225   nnoremap <buffer> <silent> <nowait> U	:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6226   nnoremap <buffer> <silent> <nowait> v	:call <SID>NetrwSplit(2)<cr>
6227   nnoremap <buffer> <silent> <nowait> x	:<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6228"   " remote insert-mode maps
6229"   inoremap <buffer> <silent> <nowait> <cr>	<c-o>:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
6230"   inoremap <buffer> <silent> <nowait> <c-l>	<c-o>:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6231"   inoremap <buffer> <silent> <nowait> <s-cr>	<c-o>:call <SID>TreeSqueezeDir(0)<cr>
6232"   inoremap <buffer> <silent> <nowait> -		<c-o>:call <SID>NetrwBrowseUpDir(0)<cr>
6233"   inoremap <buffer> <silent> <nowait> a		<c-o>:call <SID>NetrwHide(0)<cr>
6234"   inoremap <buffer> <silent> <nowait> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6235"   inoremap <buffer> <silent> <nowait> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6236"   inoremap <buffer> <silent> <nowait> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6237"   inoremap <buffer> <silent> <nowait> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6238"   inoremap <buffer> <silent> <nowait> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6239"   inoremap <buffer> <silent> <nowait> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6240"   inoremap <buffer> <silent> <nowait> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6241"   inoremap <buffer> <silent> <nowait> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6242"   inoremap <buffer> <silent> <nowait> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6243"   inoremap <buffer> <silent> <nowait> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6244"   inoremap <buffer> <silent> <nowait> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6245"   inoremap <buffer> <silent> <nowait> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6246"   inoremap <buffer> <silent> <nowait> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6247"   inoremap <buffer> <silent> <nowait> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6248"   nnoremap <buffer> <silent> <nowait> mv	:<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6249"   inoremap <buffer> <silent> <nowait> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6250"   inoremap <buffer> <silent> <nowait> mX	<c-o>:<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6251"   inoremap <buffer> <silent> <nowait> mv	<c-o>:<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6252"   inoremap <buffer> <silent> <nowait> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6253"   inoremap <buffer> <silent> <nowait> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6254"   inoremap <buffer> <silent> <nowait> gh	<c-o>:<c-u>call <SID>NetrwHidden(0)<cr>
6255"   inoremap <buffer> <silent> <nowait> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6256"   inoremap <buffer> <silent> <nowait> C		<c-o>:call <SID>NetrwSetChgwin()<cr>
6257"   inoremap <buffer> <silent> <nowait> i		<c-o>:call <SID>NetrwListStyle(0)<cr>
6258"   inoremap <buffer> <silent> <nowait> I		<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
6259"   inoremap <buffer> <silent> <nowait> o		<c-o>:call <SID>NetrwSplit(0)<cr>
6260"   inoremap <buffer> <silent> <nowait> O		<c-o>:call <SID>NetrwObtain(0)<cr>
6261"   inoremap <buffer> <silent> <nowait> p		<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6262"   inoremap <buffer> <silent> <nowait> P		<c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
6263"   inoremap <buffer> <silent> <nowait> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6264"   inoremap <buffer> <silent> <nowait> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6265"   inoremap <buffer> <silent> <nowait> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6266"   inoremap <buffer> <silent> <nowait> qF	:<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6267"   inoremap <buffer> <silent> <nowait> qL	:<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6268"   inoremap <buffer> <silent> <nowait> r		<c-o>:let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6269"   inoremap <buffer> <silent> <nowait> s		<c-o>:call <SID>NetrwSortStyle(0)<cr>
6270"   inoremap <buffer> <silent> <nowait> S		<c-o>:call <SID>NetSortSequence(0)<cr>
6271"   inoremap <buffer> <silent> <nowait> t		<c-o>:call <SID>NetrwSplit(1)<cr>
6272"   inoremap <buffer> <silent> <nowait> Tb	<c-o>:<c-u>call <SID>NetrwSetTgt('b',v:count1)<cr>
6273"   inoremap <buffer> <silent> <nowait> Th	<c-o>:<c-u>call <SID>NetrwSetTgt('h',v:count)<cr>
6274"   inoremap <buffer> <silent> <nowait> u		<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6275"   inoremap <buffer> <silent> <nowait> U		<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6276"   inoremap <buffer> <silent> <nowait> v		<c-o>:call <SID>NetrwSplit(2)<cr>
6277"   inoremap <buffer> <silent> <nowait> x		<c-o>:call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
6278"   inoremap <buffer> <silent> <nowait> %		<c-o>:call <SID>NetrwOpenFile(0)<cr>
6279   if !hasmapto('<Plug>NetrwHideEdit')
6280    nmap <buffer> <c-h> <Plug>NetrwHideEdit
6281"    imap <buffer> <c-h> <Plug>NetrwHideEdit
6282   endif
6283   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
6284   if !hasmapto('<Plug>NetrwRefresh')
6285    nmap <buffer> <c-l> <Plug>NetrwRefresh
6286"    imap <buffer> <c-l> <Plug>NetrwRefresh
6287   endif
6288   if !hasmapto('<Plug>NetrwTreeSqueeze')
6289    nmap <buffer> <silent> <nowait> <s-cr>	<Plug>NetrwTreeSqueeze
6290"    imap <buffer> <silent> <nowait> <s-cr>	<c-o><Plug>NetrwTreeSqueeze
6291   endif
6292   nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze	:call <SID>TreeSqueezeDir(0)<cr>
6293
6294   let mapsafepath     = escape(s:path, s:netrw_map_escape)
6295   let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6296
6297   nnoremap <buffer> <silent> <Plug>NetrwRefresh	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
6298   if g:netrw_mousemaps == 1
6299    nmap <buffer> <leftmouse>		<Plug>NetrwLeftmouse
6300    nno  <buffer> <silent>		<Plug>NetrwLeftmouse	<leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
6301    nmap <buffer> <c-leftmouse>		<Plug>NetrwCLeftmouse
6302    nno  <buffer> <silent>		<Plug>NetrwCLeftmouse	<leftmouse>:call <SID>NetrwCLeftmouse(0)<cr>
6303    nmap <buffer> <s-leftmouse>		<Plug>NetrwSLeftmouse
6304    nno  <buffer> <silent>		<Plug>NetrwSLeftmouse 	<leftmouse>:call <SID>NetrwSLeftmouse(0)<cr>
6305    nmap <buffer> <s-leftdrag>		<Plug>NetrwSLeftdrag
6306    nno  <buffer> <silent>		<Plug>NetrwSLeftdrag	<leftmouse>:call <SID>NetrwSLeftdrag(0)<cr>
6307    nmap <middlemouse>			<Plug>NetrwMiddlemouse
6308    nno  <buffer> <silent>		<middlemouse>		<Plug>NetrwMiddlemouse <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
6309    nmap <buffer> <2-leftmouse>		<Plug>Netrw2Leftmouse
6310    nmap <buffer> <silent>		<Plug>Netrw2Leftmouse	-
6311    imap <buffer> <leftmouse>		<Plug>ILeftmouse
6312"    ino  <buffer> <silent>		<Plug>ILeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(0)<cr>
6313    imap <buffer> <middlemouse>		<Plug>IMiddlemouse
6314"    ino  <buffer> <silent>		<Plug>IMiddlemouse	<c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
6315    imap <buffer> <s-leftmouse>		<Plug>ISLeftmouse
6316"    ino  <buffer> <silent>		<Plug>ISLeftmouse	<c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6317    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6318    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6319"    exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6320   endif
6321   exe 'nnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6322   exe 'nnoremap <buffer> <silent> <nowait> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6323   exe 'nnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6324   exe 'nnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6325   exe 'vnoremap <buffer> <silent> <nowait> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6326   exe 'vnoremap <buffer> <silent> <nowait> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6327   exe 'vnoremap <buffer> <silent> <nowait> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6328"   exe 'inoremap <buffer> <silent> <nowait> <del>	<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6329"   exe 'inoremap <buffer> <silent> <nowait> d		<c-o>:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6330"   exe 'inoremap <buffer> <silent> <nowait> D		<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6331"   exe 'inoremap <buffer> <silent> <nowait> R		<c-o>:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6332   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
6333"   inoremap <buffer> <F1>			<c-o>:he netrw-quickhelp<cr>
6334
6335   " support user-specified maps
6336   call netrw#UserMaps(0)
6337  endif
6338
6339"  call Dret("s:NetrwMaps")
6340endfun
6341
6342" ---------------------------------------------------------------------
6343" s:NetrwCommands: set up commands 				{{{2
6344"  If -buffer, the command is only available from within netrw buffers
6345"  Otherwise, the command is available from any window, so long as netrw
6346"  has been used at least once in the session.
6347fun! s:NetrwCommands(islocal)
6348"  call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6349
6350  com! -nargs=* -complete=file -bang	NetrwMB	call s:NetrwBookmark(<bang>0,<f-args>)
6351  com! -nargs=*			    	NetrwC	call s:NetrwSetChgwin(<q-args>)
6352  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
6353  if a:islocal
6354   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(1,<f-args>)
6355  else
6356   com! -buffer -nargs=+ -complete=file	MF	call s:NetrwMarkFiles(0,<f-args>)
6357  endif
6358  com! -buffer -nargs=? -complete=file	MT	call s:NetrwMarkTarget(<q-args>)
6359
6360"  call Dret("s:NetrwCommands")
6361endfun
6362
6363" ---------------------------------------------------------------------
6364" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6365"                   glob()ing only works with local files
6366fun! s:NetrwMarkFiles(islocal,...)
6367"  call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6368  let curdir = s:NetrwGetCurdir(a:islocal)
6369  let i      = 1
6370  while i <= a:0
6371   if a:islocal
6372    if v:version > 704 || (v:version == 704 && has("patch656"))
6373     let mffiles= glob(fnameescape(a:{i}),0,1,1)
6374    else
6375     let mffiles= glob(fnameescape(a:{i}),0,1)
6376    endif
6377   else
6378    let mffiles= [a:{i}]
6379   endif
6380"   call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6381   for mffile in mffiles
6382"    call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6383    call s:NetrwMarkFile(a:islocal,mffile)
6384   endfor
6385   let i= i + 1
6386  endwhile
6387"  call Dret("s:NetrwMarkFiles")
6388endfun
6389
6390" ---------------------------------------------------------------------
6391" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6392fun! s:NetrwMarkTarget(...)
6393"  call Dfunc("s:NetrwMarkTarget() a:0=".a:0)
6394  if a:0 == 0 || (a:0 == 1 && a:1 == "")
6395   let curdir = s:NetrwGetCurdir(1)
6396   let tgt    = b:netrw_curdir
6397  else
6398   let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6399   let tgt    = a:1
6400  endif
6401"  call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
6402  let s:netrwmftgt         = tgt
6403  let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6404  let curislocal           = b:netrw_curdir !~ '^\a\{3,}://'
6405  let svpos                = winsaveview()
6406"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6407  call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./'))
6408"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6409  call winrestview(svpos)
6410"  call Dret("s:NetrwMarkTarget")
6411endfun
6412
6413" ---------------------------------------------------------------------
6414" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6415"                  mark and unmark files.  If a markfile list exists,
6416"                  then the rename and delete functions will use it instead
6417"                  of whatever may happen to be under the cursor at that
6418"                  moment.  When the mouse and gui are available,
6419"                  shift-leftmouse may also be used to mark files.
6420"
6421"  Creates two lists
6422"    s:netrwmarkfilelist    -- holds complete paths to all marked files
6423"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
6424"
6425"  Creates a marked file match string
6426"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
6427"
6428"  Creates a buffer version of islocal
6429"    b:netrw_islocal
6430fun! s:NetrwMarkFile(islocal,fname)
6431"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6432"  call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6433
6434  " sanity check
6435  if empty(a:fname)
6436"   call Dret("s:NetrwMarkFile : emtpy fname")
6437   return
6438  endif
6439  let curdir = s:NetrwGetCurdir(a:islocal)
6440
6441  let ykeep   = @@
6442  let curbufnr= bufnr("%")
6443  if a:fname =~ '^\a'
6444   let leader= '\<'
6445  else
6446   let leader= ''
6447  endif
6448  if a:fname =~ '\a$'
6449   let trailer = '\>[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6450  else
6451   let trailer = '[@=|\/\*]\=\ze\%(  \|\t\|$\)'
6452  endif
6453
6454  if exists("s:netrwmarkfilelist_".curbufnr)
6455   " markfile list pre-exists
6456"   call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6457"   call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6458"   call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6459   let b:netrw_islocal= a:islocal
6460
6461   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6462    " append filename to buffer's markfilelist
6463"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6464    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6465    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6466
6467   else
6468    " remove filename from buffer's markfilelist
6469"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6470    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6471    if s:netrwmarkfilelist_{curbufnr} == []
6472     " local markfilelist is empty; remove it entirely
6473"     call Decho("markfile list now empty",'~'.expand("<slnum>"))
6474     call s:NetrwUnmarkList(curbufnr,curdir)
6475    else
6476     " rebuild match list to display markings correctly
6477"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6478     let s:netrwmarkfilemtch_{curbufnr}= ""
6479     let first                         = 1
6480     for fname in s:netrwmarkfilelist_{curbufnr}
6481      if first
6482       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6483      else
6484       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6485      endif
6486      let first= 0
6487     endfor
6488"     call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6489    endif
6490   endif
6491
6492  else
6493   " initialize new markfilelist
6494"   call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6495
6496"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6497   let s:netrwmarkfilelist_{curbufnr}= []
6498   call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6499"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6500
6501   " build initial markfile matching pattern
6502   if a:fname =~ '/$'
6503    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6504   else
6505    let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6506   endif
6507"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6508  endif
6509
6510  " handle global markfilelist
6511  if exists("s:netrwmarkfilelist")
6512   let dname= s:ComposePath(b:netrw_curdir,a:fname)
6513   if index(s:netrwmarkfilelist,dname) == -1
6514    " append new filename to global markfilelist
6515    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6516"    call Decho("append filename<".a:fname."> to global markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6517   else
6518    " remove new filename from global markfilelist
6519"    call Decho("filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6520    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6521"    call Decho("ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6522    if s:netrwmarkfilelist == []
6523     unlet s:netrwmarkfilelist
6524    endif
6525   endif
6526  else
6527   " initialize new global-directory markfilelist
6528   let s:netrwmarkfilelist= []
6529   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6530"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6531  endif
6532
6533  " set up 2match'ing to netrwmarkfilemtch_# list
6534  if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6535"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6536   if exists("g:did_drchip_netrwlist_syntax")
6537    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6538   endif
6539  else
6540"   call Decho("2match none",'~'.expand("<slnum>"))
6541   2match none
6542  endif
6543  let @@= ykeep
6544"  call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">")
6545endfun
6546
6547" ---------------------------------------------------------------------
6548" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6549"                         mA: move the argument list to marked file list     (tomflist=1)
6550"                            Uses the global marked file list
6551fun! s:NetrwMarkFileArgList(islocal,tomflist)
6552"  call Dfunc("s:NetrwMarkFileArgList(islocal=".a:islocal.",tomflist=".a:tomflist.")")
6553
6554  let svpos    = winsaveview()
6555"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6556  let curdir   = s:NetrwGetCurdir(a:islocal)
6557  let curbufnr = bufnr("%")
6558
6559  if a:tomflist
6560   " mA: move argument list to marked file list
6561   while argc()
6562    let fname= argv(0)
6563"    call Decho("exe argdel ".fname,'~'.expand("<slnum>"))
6564    exe "argdel ".fnameescape(fname)
6565    call s:NetrwMarkFile(a:islocal,fname)
6566   endwhile
6567
6568  else
6569   " ma: move marked file list to argument list
6570   if exists("s:netrwmarkfilelist")
6571
6572    " for every filename in the marked list
6573    for fname in s:netrwmarkfilelist
6574"     call Decho("exe argadd ".fname,'~'.expand("<slnum>"))
6575     exe "argadd ".fnameescape(fname)
6576    endfor	" for every file in the marked list
6577
6578    " unmark list and refresh
6579    call s:NetrwUnmarkList(curbufnr,curdir)
6580    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6581"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6582    NetrwKeepj call winrestview(svpos)
6583   endif
6584  endif
6585
6586"  call Dret("s:NetrwMarkFileArgList")
6587endfun
6588
6589" ---------------------------------------------------------------------
6590" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6591"                          compress/decompress files using the programs
6592"                          in g:netrw_compress and g:netrw_uncompress,
6593"                          using g:netrw_compress_suffix to know which to
6594"                          do.  By default:
6595"                            g:netrw_compress        = "gzip"
6596"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6597fun! s:NetrwMarkFileCompress(islocal)
6598"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
6599  let svpos    = winsaveview()
6600"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6601  let curdir   = s:NetrwGetCurdir(a:islocal)
6602  let curbufnr = bufnr("%")
6603
6604  " sanity check
6605  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6606   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6607"   call Dret("s:NetrwMarkFileCompress")
6608   return
6609  endif
6610"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6611
6612  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6613
6614   " for every filename in the marked list
6615   for fname in s:netrwmarkfilelist_{curbufnr}
6616    let sfx= substitute(fname,'^.\{-}\(\.\a\+\)$','\1','')
6617"    call Decho("extracted sfx<".sfx.">",'~'.expand("<slnum>"))
6618    if exists("g:netrw_decompress['".sfx."']")
6619     " fname has a suffix indicating that its compressed; apply associated decompression routine
6620     let exe= g:netrw_decompress[sfx]
6621"     call Decho("fname<".fname."> is compressed so decompress with <".exe.">",'~'.expand("<slnum>"))
6622     let exe= netrw#WinPath(exe)
6623     if a:islocal
6624      if g:netrw_keepdir
6625       let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6626      endif
6627     else
6628      let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6629     endif
6630     if executable(exe)
6631      if a:islocal
6632       call system(exe." ".fname)
6633      else
6634       NetrwKeepj call s:RemoteSystem(exe." ".fname)
6635      endif
6636     else
6637      NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6638     endif
6639    endif
6640    unlet sfx
6641
6642    if exists("exe")
6643     unlet exe
6644    elseif a:islocal
6645     " fname not a compressed file, so compress it
6646     call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
6647    else
6648     " fname not a compressed file, so compress it
6649     NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
6650    endif
6651   endfor	" for every file in the marked list
6652
6653   call s:NetrwUnmarkList(curbufnr,curdir)
6654   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
6655"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
6656   NetrwKeepj call winrestview(svpos)
6657  endif
6658"  call Dret("s:NetrwMarkFileCompress")
6659endfun
6660
6661" ---------------------------------------------------------------------
6662" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
6663"                      If no marked files, then set up directory as the
6664"                      target.  Currently does not support copying entire
6665"                      directories.  Uses the local-buffer marked file list.
6666"                      Returns 1=success  (used by NetrwMarkFileMove())
6667"                              0=failure
6668fun! s:NetrwMarkFileCopy(islocal,...)
6669"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
6670
6671  let curdir   = s:NetrwGetCurdir(a:islocal)
6672  let curbufnr = bufnr("%")
6673  if b:netrw_curdir !~ '/$'
6674   if !exists("b:netrw_curdir")
6675    let b:netrw_curdir= curdir
6676   endif
6677   let b:netrw_curdir= b:netrw_curdir."/"
6678  endif
6679
6680  " sanity check
6681  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6682   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6683"   call Dret("s:NetrwMarkFileCopy")
6684   return
6685  endif
6686"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6687
6688  if !exists("s:netrwmftgt")
6689   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
6690"   call Dret("s:NetrwMarkFileCopy 0")
6691   return 0
6692  endif
6693"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
6694
6695  if a:islocal &&  s:netrwmftgt_islocal
6696   " Copy marked files, local directory to local directory
6697"   call Decho("copy from local to local",'~'.expand("<slnum>"))
6698   if !executable(g:netrw_localcopycmd) && g:netrw_localcopycmd !~ '^'.expand("$COMSPEC").'\s'
6699    call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
6700"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
6701    return
6702   endif
6703
6704   " copy marked files while within the same directory (ie. allow renaming)
6705   if simplify(s:netrwmftgt) == simplify(b:netrw_curdir)
6706    if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
6707     " only one marked file
6708"     call Decho("case: only one marked file",'~'.expand("<slnum>"))
6709     let args    = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
6710     let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
6711    elseif a:0 == 1
6712"     call Decho("case: handling one input argument",'~'.expand("<slnum>"))
6713     " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
6714     let args    = s:ShellEscape(b:netrw_curdir.a:1)
6715     let oldname = a:1
6716    else
6717     " copy multiple marked files inside the same directory
6718"     call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
6719     let s:recursive= 1
6720     for oldname in s:netrwmarkfilelist_{bufnr("%")}
6721      let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
6722      if ret == 0
6723       break
6724      endif
6725     endfor
6726     unlet s:recursive
6727     call s:NetrwUnmarkList(curbufnr,curdir)
6728"     call Dret("s:NetrwMarkFileCopy ".ret)
6729     return ret
6730    endif
6731
6732    call inputsave()
6733    let newname= input("Copy ".oldname." to : ",oldname,"file")
6734    call inputrestore()
6735    if newname == ""
6736"     call Dret("s:NetrwMarkFileCopy 0")
6737     return 0
6738    endif
6739    let args= s:ShellEscape(oldname)
6740    let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
6741   else
6742    let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
6743    let tgt = s:ShellEscape(s:netrwmftgt)
6744   endif
6745   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
6746    let args= substitute(args,'/','\\','g')
6747    let tgt = substitute(tgt, '/','\\','g')
6748   endif
6749   if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
6750   if tgt  =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
6751   if args =~ '//'|let args= substitute(args,'//','/','g')|endif
6752   if tgt  =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
6753"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
6754"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
6755   if isdirectory(s:NetrwFile(args))
6756"    call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
6757    let copycmd= g:netrw_localcopydircmd
6758"    call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
6759    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
6760     " window's xcopy doesn't copy a directory to a target properly.  Instead, it copies a directory's
6761     " contents to a target.  One must append the source directory name to the target to get xcopy to
6762     " do the right thing.
6763     let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
6764"     call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
6765    endif
6766   else
6767    let copycmd= g:netrw_localcopycmd
6768   endif
6769   if g:netrw_localcopycmd =~ '\s'
6770    let copycmd     = substitute(copycmd,'\s.*$','','')
6771    let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
6772    let copycmd     = netrw#WinPath(copycmd).copycmdargs
6773   else
6774    let copycmd = netrw#WinPath(copycmd)
6775   endif
6776"   call Decho("args   <".args.">",'~'.expand("<slnum>"))
6777"   call Decho("tgt    <".tgt.">",'~'.expand("<slnum>"))
6778"   call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
6779"   call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
6780   call system(copycmd." '".args."' '".tgt."'")
6781   if v:shell_error != 0
6782    if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
6783     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)
6784    else
6785     call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
6786    endif
6787"    call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
6788    return 0
6789   endif
6790
6791  elseif  a:islocal && !s:netrwmftgt_islocal
6792   " Copy marked files, local directory to remote directory
6793"   call Decho("copy from local to remote",'~'.expand("<slnum>"))
6794   NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6795
6796  elseif !a:islocal &&  s:netrwmftgt_islocal
6797   " Copy marked files, remote directory to local directory
6798"   call Decho("copy from remote to local",'~'.expand("<slnum>"))
6799   NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6800
6801  elseif !a:islocal && !s:netrwmftgt_islocal
6802   " Copy marked files, remote directory to remote directory
6803"   call Decho("copy from remote to remote",'~'.expand("<slnum>"))
6804   let curdir = getcwd()
6805   let tmpdir = s:GetTempfile("")
6806   if tmpdir !~ '/'
6807    let tmpdir= curdir."/".tmpdir
6808   endif
6809   if exists("*mkdir")
6810    call mkdir(tmpdir)
6811   else
6812    call s:NetrwExe("sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1))
6813    if v:shell_error != 0
6814     call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6815"     call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
6816     return
6817    endif
6818   endif
6819   if isdirectory(s:NetrwFile(tmpdir))
6820    call s:NetrwLcd(tmpdir)
6821    NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
6822    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
6823    NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
6824    if getcwd() == tmpdir
6825     for fname in s:netrwmarkfilelist_{bufnr('%')}
6826      NetrwKeepj call s:NetrwDelete(fname)
6827     endfor
6828     call s:NetrwLcd(curdir)
6829     if v:version < 704 || !has("patch1109")
6830      call s:NetrwExe("sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1))
6831      if v:shell_error != 0
6832       call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localrmdir<".g:netrw_localrmdir."> to something that works",80)
6833" "      call Dret("s:NetrwMarkFileCopy : failed: sil !".g:netrw_localrmdir." ".s:ShellEscape(tmpdir,1) )
6834       return
6835      endif
6836     else
6837      if delete(tmpdir,"d")
6838       call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
6839      endif
6840     endif
6841    else
6842     call s:NetrwLcd(curdir)
6843    endif
6844   endif
6845  endif
6846
6847  " -------
6848  " cleanup
6849  " -------
6850"  call Decho("cleanup",'~'.expand("<slnum>"))
6851  " remove markings from local buffer
6852  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
6853"  call Decho(" g:netrw_fastbrowse  =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
6854"  call Decho(" s:netrwmftgt        =".s:netrwmftgt,'~'.expand("<slnum>"))
6855"  call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
6856"  call Decho(" curdir              =".curdir,'~'.expand("<slnum>"))
6857"  call Decho(" a:islocal           =".a:islocal,'~'.expand("<slnum>"))
6858"  call Decho(" curbufnr            =".curbufnr,'~'.expand("<slnum>"))
6859  if exists("s:recursive")
6860"   call Decho(" s:recursive         =".s:recursive,'~'.expand("<slnum>"))
6861  else
6862"   call Decho(" s:recursive         =n/a",'~'.expand("<slnum>"))
6863  endif
6864  " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
6865  if g:netrw_fastbrowse <= 1
6866   NetrwKeepj call s:LocalBrowseRefresh()
6867  else
6868   " refresh local and targets for fast browsing
6869   if !exists("s:recursive")
6870    " remove markings from local buffer
6871"    call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
6872    NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
6873   endif
6874
6875   " refresh buffers
6876   if s:netrwmftgt_islocal
6877"    call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
6878    NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
6879   endif
6880   if a:islocal && s:netrwmftgt != curdir
6881"    call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
6882    NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
6883   endif
6884  endif
6885
6886"  call Dret("s:NetrwMarkFileCopy 1")
6887  return 1
6888endfun
6889
6890" ---------------------------------------------------------------------
6891" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
6892"                      invoke vim's diff mode on the marked files.
6893"                      Either two or three files can be so handled.
6894"                      Uses the global marked file list.
6895fun! s:NetrwMarkFileDiff(islocal)
6896"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6897  let curbufnr= bufnr("%")
6898
6899  " sanity check
6900  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6901   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6902"   call Dret("s:NetrwMarkFileDiff")
6903   return
6904  endif
6905  let curdir= s:NetrwGetCurdir(a:islocal)
6906"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6907
6908  if exists("s:netrwmarkfilelist_{".curbufnr."}")
6909   let cnt    = 0
6910   for fname in s:netrwmarkfilelist
6911    let cnt= cnt + 1
6912    if cnt == 1
6913"     call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
6914     exe "NetrwKeepj e ".fnameescape(fname)
6915     diffthis
6916    elseif cnt == 2 || cnt == 3
6917     vsplit
6918     wincmd l
6919"     call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
6920     exe "NetrwKeepj e ".fnameescape(fname)
6921     diffthis
6922    else
6923     break
6924    endif
6925   endfor
6926   call s:NetrwUnmarkList(curbufnr,curdir)
6927  endif
6928
6929"  call Dret("s:NetrwMarkFileDiff")
6930endfun
6931
6932" ---------------------------------------------------------------------
6933" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
6934"                       Uses global markfilelist
6935fun! s:NetrwMarkFileEdit(islocal)
6936"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
6937
6938  let curdir   = s:NetrwGetCurdir(a:islocal)
6939  let curbufnr = bufnr("%")
6940
6941  " sanity check
6942  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6943   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6944"   call Dret("s:NetrwMarkFileEdit")
6945   return
6946  endif
6947"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6948
6949  if exists("s:netrwmarkfilelist_{curbufnr}")
6950   call s:SetRexDir(a:islocal,curdir)
6951   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
6952   " unmark markedfile list
6953"   call s:NetrwUnmarkList(curbufnr,curdir)
6954   call s:NetrwUnmarkAll()
6955"   call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
6956   exe "sil args ".flist
6957  endif
6958  echo "(use :bn, :bp to navigate files; :Rex to return)"
6959
6960"  call Dret("s:NetrwMarkFileEdit")
6961endfun
6962
6963" ---------------------------------------------------------------------
6964" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
6965fun! s:NetrwMarkFileQFEL(islocal,qfel)
6966"  call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
6967  call s:NetrwUnmarkAll()
6968  let curbufnr= bufnr("%")
6969
6970  if !empty(a:qfel)
6971   for entry in a:qfel
6972    let bufnmbr= entry["bufnr"]
6973"    call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
6974    if !exists("s:netrwmarkfilelist_{curbufnr}")
6975"     call Decho("case: no marked file list",'~'.expand("<slnum>"))
6976     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
6977    elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
6978     " s:NetrwMarkFile will remove duplicate entries from the marked file list.
6979     " So, this test lets two or more hits on the same pattern to be ignored.
6980"     call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
6981     call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
6982    else
6983"     call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
6984    endif
6985   endfor
6986   echo "(use me to edit marked files)"
6987  else
6988   call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
6989  endif
6990
6991"  call Dret("s:NetrwMarkFileQFEL")
6992endfun
6993
6994" ---------------------------------------------------------------------
6995" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
6996"                     mx enbloc=0: Uses the local marked-file list, applies command to each file individually
6997"                     mX enbloc=1: Uses the global marked-file list, applies command to entire list
6998fun! s:NetrwMarkFileExe(islocal,enbloc)
6999"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.",enbloc=".a:enbloc.")")
7000  let svpos    = winsaveview()
7001"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7002  let curdir   = s:NetrwGetCurdir(a:islocal)
7003  let curbufnr = bufnr("%")
7004
7005  if a:enbloc == 0
7006   " individually apply command to files, one at a time
7007    " sanity check
7008    if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7009     NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7010"     call Dret("s:NetrwMarkFileExe")
7011     return
7012    endif
7013"    call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7014
7015    if exists("s:netrwmarkfilelist_{curbufnr}")
7016     " get the command
7017     call inputsave()
7018     let cmd= input("Enter command: ","","file")
7019     call inputrestore()
7020"     call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7021     if cmd == ""
7022"      call Dret("s:NetrwMarkFileExe : early exit, empty command")
7023      return
7024     endif
7025
7026     " apply command to marked files, individually.  Substitute: filename -> %
7027     " If no %, then append a space and the filename to the command
7028     for fname in s:netrwmarkfilelist_{curbufnr}
7029      if a:islocal
7030       if g:netrw_keepdir
7031	let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
7032       endif
7033      else
7034       let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
7035      endif
7036      if cmd =~ '%'
7037       let xcmd= substitute(cmd,'%',fname,'g')
7038      else
7039       let xcmd= cmd.' '.fname
7040      endif
7041      if a:islocal
7042"       call Decho("local: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7043       let ret= system(xcmd)
7044      else
7045"       call Decho("remote: xcmd<".xcmd.">",'~'.expand("<slnum>"))
7046       let ret= s:RemoteSystem(xcmd)
7047      endif
7048      if v:shell_error < 0
7049       NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7050       break
7051      else
7052       echo ret
7053      endif
7054     endfor
7055
7056   " unmark marked file list
7057   call s:NetrwUnmarkList(curbufnr,curdir)
7058
7059   " refresh the listing
7060   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7061"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7062   NetrwKeepj call winrestview(svpos)
7063  else
7064   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7065  endif
7066
7067 else " apply command to global list of files, en bloc
7068
7069  call inputsave()
7070  let cmd= input("Enter command: ","","file")
7071  call inputrestore()
7072"  call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7073  if cmd == ""
7074"   call Dret("s:NetrwMarkFileExe : early exit, empty command")
7075   return
7076  endif
7077  if cmd =~ '%'
7078   let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7079  else
7080   let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7081  endif
7082  if a:islocal
7083   call system(cmd)
7084   if v:shell_error < 0
7085    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7086   endif
7087  else
7088   let ret= s:RemoteSystem(cmd)
7089  endif
7090  call s:NetrwUnmarkAll()
7091
7092  " refresh the listing
7093  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7094"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7095  NetrwKeepj call winrestview(svpos)
7096
7097 endif
7098
7099"  call Dret("s:NetrwMarkFileExe")
7100endfun
7101
7102" ---------------------------------------------------------------------
7103" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7104"                  as the marked file(s) (toggles suffix presence)
7105"                  Uses the local marked file list.
7106fun! s:NetrwMarkHideSfx(islocal)
7107"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7108  let svpos    = winsaveview()
7109"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7110  let curbufnr = bufnr("%")
7111
7112  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7113  if exists("s:netrwmarkfilelist_{curbufnr}")
7114
7115   for fname in s:netrwmarkfilelist_{curbufnr}
7116"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7117     " construct suffix pattern
7118     if fname =~ '\.'
7119      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7120     else
7121      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7122     endif
7123     " determine if its in the hiding list or not
7124     let inhidelist= 0
7125     if g:netrw_list_hide != ""
7126      let itemnum = 0
7127      let hidelist= split(g:netrw_list_hide,',')
7128      for hidepat in hidelist
7129       if sfxpat == hidepat
7130        let inhidelist= 1
7131        break
7132       endif
7133       let itemnum= itemnum + 1
7134      endfor
7135     endif
7136"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7137     if inhidelist
7138      " remove sfxpat from list
7139      call remove(hidelist,itemnum)
7140      let g:netrw_list_hide= join(hidelist,",")
7141     elseif g:netrw_list_hide != ""
7142      " append sfxpat to non-empty list
7143      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7144     else
7145      " set hiding list to sfxpat
7146      let g:netrw_list_hide= sfxpat
7147     endif
7148    endfor
7149
7150   " refresh the listing
7151   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7152"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7153   NetrwKeepj call winrestview(svpos)
7154  else
7155   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7156  endif
7157
7158"  call Dret("s:NetrwMarkHideSfx")
7159endfun
7160
7161" ---------------------------------------------------------------------
7162" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7163"                     Uses the local marked-file list.
7164fun! s:NetrwMarkFileVimCmd(islocal)
7165"  call Dfunc("s:NetrwMarkFileVimCmd(islocal=".a:islocal.")")
7166  let svpos    = winsaveview()
7167"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7168  let curdir   = s:NetrwGetCurdir(a:islocal)
7169  let curbufnr = bufnr("%")
7170
7171  " sanity check
7172  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7173   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7174"   call Dret("s:NetrwMarkFileVimCmd")
7175   return
7176  endif
7177"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7178
7179  if exists("s:netrwmarkfilelist_{curbufnr}")
7180   " get the command
7181   call inputsave()
7182   let cmd= input("Enter vim command: ","","file")
7183   call inputrestore()
7184"   call Decho("cmd<".cmd.">",'~'.expand("<slnum>"))
7185   if cmd == ""
7186"    "   call Dret("s:NetrwMarkFileVimCmd : early exit, empty command")
7187    return
7188   endif
7189
7190   " apply command to marked files.  Substitute: filename -> %
7191   " If no %, then append a space and the filename to the command
7192   for fname in s:netrwmarkfilelist_{curbufnr}
7193"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7194    if a:islocal
7195     1split
7196     exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7197"     call Decho("local<".fname.">: exe ".cmd,'~'.expand("<slnum>"))
7198     exe cmd
7199     exe "sil! keepalt wq!"
7200    else
7201"     call Decho("remote<".fname.">: exe ".cmd." : NOT SUPPORTED YET",'~'.expand("<slnum>"))
7202     echo "sorry, \"mv\" not supported yet for remote files"
7203    endif
7204   endfor
7205
7206   " unmark marked file list
7207   call s:NetrwUnmarkList(curbufnr,curdir)
7208
7209   " refresh the listing
7210   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7211"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7212   NetrwKeepj call winrestview(svpos)
7213  else
7214   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7215  endif
7216
7217"  call Dret("s:NetrwMarkFileVimCmd")
7218endfun
7219
7220" ---------------------------------------------------------------------
7221" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7222"                  as the marked file(s) (toggles suffix presence)
7223"                  Uses the local marked file list.
7224fun! s:NetrwMarkHideSfx(islocal)
7225"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
7226  let svpos    = winsaveview()
7227"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7228  let curbufnr = bufnr("%")
7229
7230  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7231  if exists("s:netrwmarkfilelist_{curbufnr}")
7232
7233   for fname in s:netrwmarkfilelist_{curbufnr}
7234"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">",'~'.expand("<slnum>"))
7235     " construct suffix pattern
7236     if fname =~ '\.'
7237      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7238     else
7239      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7240     endif
7241     " determine if its in the hiding list or not
7242     let inhidelist= 0
7243     if g:netrw_list_hide != ""
7244      let itemnum = 0
7245      let hidelist= split(g:netrw_list_hide,',')
7246      for hidepat in hidelist
7247       if sfxpat == hidepat
7248        let inhidelist= 1
7249        break
7250       endif
7251       let itemnum= itemnum + 1
7252      endfor
7253     endif
7254"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">",'~'.expand("<slnum>"))
7255     if inhidelist
7256      " remove sfxpat from list
7257      call remove(hidelist,itemnum)
7258      let g:netrw_list_hide= join(hidelist,",")
7259     elseif g:netrw_list_hide != ""
7260      " append sfxpat to non-empty list
7261      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7262     else
7263      " set hiding list to sfxpat
7264      let g:netrw_list_hide= sfxpat
7265     endif
7266    endfor
7267
7268   " refresh the listing
7269   NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7270"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7271   NetrwKeepj call winrestview(svpos)
7272  else
7273   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7274  endif
7275
7276"  call Dret("s:NetrwMarkHideSfx")
7277endfun
7278
7279" ---------------------------------------------------------------------
7280" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7281"                     Uses the global markfilelist
7282fun! s:NetrwMarkFileGrep(islocal)
7283"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7284  let svpos    = winsaveview()
7285"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7286  let curbufnr = bufnr("%")
7287  let curdir   = s:NetrwGetCurdir(a:islocal)
7288
7289  if exists("s:netrwmarkfilelist")
7290"  call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7291   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7292   call s:NetrwUnmarkAll()
7293  else
7294"   call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7295   let netrwmarkfilelist= "*"
7296  endif
7297
7298  " ask user for pattern
7299  call inputsave()
7300  let pat= input("Enter pattern: ","")
7301  call inputrestore()
7302  let patbang = ""
7303  if pat =~ '^!'
7304   let patbang = "!"
7305   let pat     = strpart(pat,2)
7306  endif
7307  if pat =~ '^\i'
7308   let pat    = escape(pat,'/')
7309   let pat    = '/'.pat.'/'
7310  else
7311   let nonisi = pat[0]
7312  endif
7313
7314  " use vimgrep for both local and remote
7315"  call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7316  try
7317   exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7318  catch /^Vim\%((\a\+)\)\=:E480/
7319   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7320"   call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7321   return
7322  endtry
7323  echo "(use :cn, :cp to navigate, :Rex to return)"
7324
7325  2match none
7326"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7327  NetrwKeepj call winrestview(svpos)
7328
7329  if exists("nonisi")
7330   " original, user-supplied pattern did not begin with a character from isident
7331"   call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7332   if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7333    call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7334   endif
7335  endif
7336
7337"  call Dret("s:NetrwMarkFileGrep")
7338endfun
7339
7340" ---------------------------------------------------------------------
7341" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7342"                      uses the global marked file list
7343"                      s:netrwmfloc= 0: target directory is remote
7344"                                  = 1: target directory is local
7345fun! s:NetrwMarkFileMove(islocal)
7346"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7347  let curdir   = s:NetrwGetCurdir(a:islocal)
7348  let curbufnr = bufnr("%")
7349
7350  " sanity check
7351  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7352   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7353"   call Dret("s:NetrwMarkFileMove")
7354   return
7355  endif
7356"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7357
7358  if !exists("s:netrwmftgt")
7359   NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7360"   call Dret("s:NetrwMarkFileCopy 0")
7361   return 0
7362  endif
7363"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7364
7365  if      a:islocal &&  s:netrwmftgt_islocal
7366   " move: local -> local
7367"   call Decho("move from local to local",'~'.expand("<slnum>"))
7368"   call Decho("local to local move",'~'.expand("<slnum>"))
7369   if !executable(g:netrw_localmovecmd) && g:netrw_localmovecmd !~ '^'.expand("$COMSPEC").'\s'
7370    call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7371"    call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7372    return
7373   endif
7374   let tgt         = s:ShellEscape(s:netrwmftgt)
7375"   call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7376   if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7377    let tgt         = substitute(tgt, '/','\\','g')
7378"    call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7379    if g:netrw_localmovecmd =~ '\s'
7380     let movecmd     = substitute(g:netrw_localmovecmd,'\s.*$','','')
7381     let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7382     let movecmd     = netrw#WinPath(movecmd).movecmdargs
7383"     call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7384    else
7385     let movecmd = netrw#WinPath(movecmd)
7386"     call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7387    endif
7388   else
7389    let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7390"    call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7391   endif
7392   for fname in s:netrwmarkfilelist_{bufnr("%")}
7393    if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7394     let fname= substitute(fname,'/','\\','g')
7395    endif
7396"    call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7397    let ret= system(movecmd." ".s:ShellEscape(fname)." ".tgt)
7398    if v:shell_error != 0
7399     if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7400      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)
7401     else
7402      call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7403     endif
7404     break
7405    endif
7406   endfor
7407
7408  elseif  a:islocal && !s:netrwmftgt_islocal
7409   " move: local -> remote
7410"   call Decho("move from local to remote",'~'.expand("<slnum>"))
7411"   call Decho("copy",'~'.expand("<slnum>"))
7412   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7413   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7414"   call Decho("remove",'~'.expand("<slnum>"))
7415   for fname in mflist
7416    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7417    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7418   endfor
7419   unlet mflist
7420
7421  elseif !a:islocal &&  s:netrwmftgt_islocal
7422   " move: remote -> local
7423"   call Decho("move from remote to local",'~'.expand("<slnum>"))
7424"   call Decho("copy",'~'.expand("<slnum>"))
7425   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7426   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7427"   call Decho("remove",'~'.expand("<slnum>"))
7428   for fname in mflist
7429    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7430    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7431   endfor
7432   unlet mflist
7433
7434  elseif !a:islocal && !s:netrwmftgt_islocal
7435   " move: remote -> remote
7436"   call Decho("move from remote to remote",'~'.expand("<slnum>"))
7437"   call Decho("copy",'~'.expand("<slnum>"))
7438   let mflist= s:netrwmarkfilelist_{bufnr("%")}
7439   NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7440"   call Decho("remove",'~'.expand("<slnum>"))
7441   for fname in mflist
7442    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7443    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7444   endfor
7445   unlet mflist
7446  endif
7447
7448  " -------
7449  " cleanup
7450  " -------
7451"  call Decho("cleanup",'~'.expand("<slnum>"))
7452
7453  " remove markings from local buffer
7454  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
7455
7456  " refresh buffers
7457  if !s:netrwmftgt_islocal
7458"   call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7459   NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7460  endif
7461  if a:islocal
7462"   call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7463   NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7464  endif
7465  if g:netrw_fastbrowse <= 1
7466"   call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7467   NetrwKeepj call s:LocalBrowseRefresh()
7468  endif
7469
7470"  call Dret("s:NetrwMarkFileMove")
7471endfun
7472
7473" ---------------------------------------------------------------------
7474" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7475"                       using the hardcopy command.  Local marked-file list only.
7476fun! s:NetrwMarkFilePrint(islocal)
7477"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7478  let curbufnr= bufnr("%")
7479
7480  " sanity check
7481  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7482   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7483"   call Dret("s:NetrwMarkFilePrint")
7484   return
7485  endif
7486"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7487  let curdir= s:NetrwGetCurdir(a:islocal)
7488
7489  if exists("s:netrwmarkfilelist_{curbufnr}")
7490   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7491   call s:NetrwUnmarkList(curbufnr,curdir)
7492   for fname in netrwmarkfilelist
7493    if a:islocal
7494     if g:netrw_keepdir
7495      let fname= s:ComposePath(curdir,fname)
7496     endif
7497    else
7498     let fname= curdir.fname
7499    endif
7500    1split
7501    " the autocmds will handle both local and remote files
7502"    call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7503    exe "sil NetrwKeepj e ".fnameescape(fname)
7504"    call Decho("hardcopy",'~'.expand("<slnum>"))
7505    hardcopy
7506    q
7507   endfor
7508   2match none
7509  endif
7510"  call Dret("s:NetrwMarkFilePrint")
7511endfun
7512
7513" ---------------------------------------------------------------------
7514" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7515"                        files when given a regexp (for which a prompt is
7516"                        issued) (matches to name of files).
7517fun! s:NetrwMarkFileRegexp(islocal)
7518"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7519
7520  " get the regular expression
7521  call inputsave()
7522  let regexp= input("Enter regexp: ","","file")
7523  call inputrestore()
7524
7525  if a:islocal
7526   let curdir= s:NetrwGetCurdir(a:islocal)
7527   " get the matching list of files using local glob()
7528"   call Decho("handle local regexp",'~'.expand("<slnum>"))
7529   let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7530   if v:version > 704 || (v:version == 704 && has("patch656"))
7531    let files   = glob(s:ComposePath(dirname,regexp),0,0,1)
7532   else
7533    let files   = glob(s:ComposePath(dirname,regexp),0,0)
7534   endif
7535"   call Decho("files<".files.">",'~'.expand("<slnum>"))
7536   let filelist= split(files,"\n")
7537
7538  " mark the list of files
7539  for fname in filelist
7540"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7541   NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7542  endfor
7543
7544  else
7545"   call Decho("handle remote regexp",'~'.expand("<slnum>"))
7546
7547   " convert displayed listing into a filelist
7548   let eikeep = &ei
7549   let areg   = @a
7550   sil NetrwKeepj %y a
7551   setl ei=all ma
7552"   call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7553   1split
7554   NetrwKeepj call s:NetrwEnew()
7555   NetrwKeepj call s:NetrwSafeOptions()
7556   sil NetrwKeepj norm! "ap
7557   NetrwKeepj 2
7558   let bannercnt= search('^" =====','W')
7559   exe "sil NetrwKeepj 1,".bannercnt."d"
7560   setl bt=nofile
7561   if     g:netrw_liststyle == s:LONGLIST
7562    sil NetrwKeepj %s/\s\{2,}\S.*$//e
7563    call histdel("/",-1)
7564   elseif g:netrw_liststyle == s:WIDELIST
7565    sil NetrwKeepj %s/\s\{2,}/\r/ge
7566    call histdel("/",-1)
7567   elseif g:netrw_liststyle == s:TREELIST
7568    exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7569    sil! NetrwKeepj g/^ .*$/d
7570    call histdel("/",-1)
7571    call histdel("/",-1)
7572   endif
7573   " convert regexp into the more usual glob-style format
7574   let regexp= substitute(regexp,'\*','.*','g')
7575"   call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7576   exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7577   call histdel("/",-1)
7578   let filelist= getline(1,line("$"))
7579   q!
7580   for filename in filelist
7581    NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7582   endfor
7583   unlet filelist
7584   let @a  = areg
7585   let &ei = eikeep
7586  endif
7587  echo "  (use me to edit marked files)"
7588
7589"  call Dret("s:NetrwMarkFileRegexp")
7590endfun
7591
7592" ---------------------------------------------------------------------
7593" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7594"                        Uses the local marked file list.
7595fun! s:NetrwMarkFileSource(islocal)
7596"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7597  let curbufnr= bufnr("%")
7598
7599  " sanity check
7600  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7601   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7602"   call Dret("s:NetrwMarkFileSource")
7603   return
7604  endif
7605"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7606  let curdir= s:NetrwGetCurdir(a:islocal)
7607
7608  if exists("s:netrwmarkfilelist_{curbufnr}")
7609   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7610   call s:NetrwUnmarkList(curbufnr,curdir)
7611   for fname in netrwmarkfilelist
7612    if a:islocal
7613     if g:netrw_keepdir
7614      let fname= s:ComposePath(curdir,fname)
7615     endif
7616    else
7617     let fname= curdir.fname
7618    endif
7619    " the autocmds will handle sourcing both local and remote files
7620"    call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7621    exe "so ".fnameescape(fname)
7622   endfor
7623   2match none
7624  endif
7625"  call Dret("s:NetrwMarkFileSource")
7626endfun
7627
7628" ---------------------------------------------------------------------
7629" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
7630"                     Uses the global markfilelist
7631fun! s:NetrwMarkFileTag(islocal)
7632"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
7633  let svpos    = winsaveview()
7634"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7635  let curdir   = s:NetrwGetCurdir(a:islocal)
7636  let curbufnr = bufnr("%")
7637
7638  " sanity check
7639  if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7640   NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7641"   call Dret("s:NetrwMarkFileTag")
7642   return
7643  endif
7644"  call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7645
7646  if exists("s:netrwmarkfilelist")
7647"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7648   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
7649   call s:NetrwUnmarkAll()
7650
7651   if a:islocal
7652    if executable(g:netrw_ctags)
7653"     call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")",'~'.expand("<slnum>"))
7654     call system(g:netrw_ctags." ".netrwmarkfilelist)
7655    else
7656     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
7657    endif
7658   else
7659    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
7660    call netrw#Obtain(a:islocal,"tags")
7661    let curdir= b:netrw_curdir
7662    1split
7663    NetrwKeepj e tags
7664    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
7665"    call Decho("curdir<".curdir."> path<".path.">",'~'.expand("<slnum>"))
7666    exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
7667    call histdel("/",-1)
7668    wq!
7669   endif
7670   2match none
7671   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7672"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7673   call winrestview(svpos)
7674  endif
7675
7676"  call Dret("s:NetrwMarkFileTag")
7677endfun
7678
7679" ---------------------------------------------------------------------
7680" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
7681"   Sets up two variables,
7682"     s:netrwmftgt         : holds the target directory
7683"     s:netrwmftgt_islocal : 0=target directory is remote
7684"                            1=target directory is local
7685fun! s:NetrwMarkFileTgt(islocal)
7686" call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
7687  let svpos  = winsaveview()
7688"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7689  let curdir = s:NetrwGetCurdir(a:islocal)
7690  let hadtgt = exists("s:netrwmftgt")
7691  if !exists("w:netrw_bannercnt")
7692   let w:netrw_bannercnt= b:netrw_bannercnt
7693  endif
7694
7695  " set up target
7696  if line(".") < w:netrw_bannercnt
7697"   call Decho("set up target: line(.) < w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
7698   " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
7699   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
7700"    call Decho("cursor in banner region, and target already is <".b:netrw_curdir.">: removing target",'~'.expand("<slnum>"))
7701    unlet s:netrwmftgt s:netrwmftgt_islocal
7702    if g:netrw_fastbrowse <= 1
7703     call s:LocalBrowseRefresh()
7704    endif
7705    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7706"    call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7707    call winrestview(svpos)
7708"    call Dret("s:NetrwMarkFileTgt : removed target")
7709    return
7710   else
7711    let s:netrwmftgt= b:netrw_curdir
7712"    call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7713   endif
7714
7715  else
7716   " get word under cursor.
7717   "  * If directory, use it for the target.
7718   "  * If file, use b:netrw_curdir for the target
7719"   call Decho("get word under cursor",'~'.expand("<slnum>"))
7720   let curword= s:NetrwGetWord()
7721   let tgtdir = s:ComposePath(curdir,curword)
7722   if a:islocal && isdirectory(s:NetrwFile(tgtdir))
7723    let s:netrwmftgt = tgtdir
7724"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7725   elseif !a:islocal && tgtdir =~ '/$'
7726    let s:netrwmftgt = tgtdir
7727"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7728   else
7729    let s:netrwmftgt = curdir
7730"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7731   endif
7732  endif
7733  if a:islocal
7734   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
7735   let s:netrwmftgt= simplify(s:netrwmftgt)
7736"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7737  endif
7738  if g:netrw_cygwin
7739   let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
7740   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
7741  endif
7742  let s:netrwmftgt_islocal= a:islocal
7743
7744  " need to do refresh so that the banner will be updated
7745  "  s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
7746  if g:netrw_fastbrowse <= 1
7747"   call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse.", so refreshing all local netrw buffers",'~'.expand("<slnum>"))
7748   call s:LocalBrowseRefresh()
7749  endif
7750"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7751  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7752   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop))
7753  else
7754   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7755  endif
7756"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7757  call winrestview(svpos)
7758  if !hadtgt
7759   sil! NetrwKeepj norm! j
7760  endif
7761
7762"  call Decho("getmatches=".string(getmatches()),'~'.expand("<slnum>"))
7763"  call Decho("s:netrwmarkfilelist=".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : 'n/a'),'~'.expand("<slnum>"))
7764"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
7765endfun
7766
7767" ---------------------------------------------------------------------
7768" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
7769fun! s:NetrwGetCurdir(islocal)
7770"  call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
7771
7772  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7773   let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
7774"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
7775  elseif !exists("b:netrw_curdir")
7776   let b:netrw_curdir= getcwd()
7777"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
7778  endif
7779
7780"  call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>"))
7781  if b:netrw_curdir !~ '\<\a\{3,}://'
7782   let curdir= b:netrw_curdir
7783"   call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
7784   if g:netrw_keepdir == 0
7785    call s:NetrwLcd(curdir)
7786   endif
7787  endif
7788
7789"  call Dret("s:NetrwGetCurdir <".curdir.">")
7790  return b:netrw_curdir
7791endfun
7792
7793" ---------------------------------------------------------------------
7794" s:NetrwOpenFile: query user for a filename and open it {{{2
7795fun! s:NetrwOpenFile(islocal)
7796"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
7797  let ykeep= @@
7798  call inputsave()
7799  let fname= input("Enter filename: ")
7800  call inputrestore()
7801  if fname !~ '[/\\]'
7802   if exists("b:netrw_curdir")
7803    if exists("g:netrw_quiet")
7804     let netrw_quiet_keep = g:netrw_quiet
7805    endif
7806    let g:netrw_quiet = 1
7807    " save position for benefit of Rexplore
7808    let s:rexposn_{bufnr("%")}= winsaveview()
7809"    call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
7810    if b:netrw_curdir =~ '/$'
7811     exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
7812    else
7813     exe "e ".fnameescape(b:netrw_curdir."/".fname)
7814    endif
7815    if exists("netrw_quiet_keep")
7816     let g:netrw_quiet= netrw_quiet_keep
7817    else
7818     unlet g:netrw_quiet
7819    endif
7820   endif
7821  else
7822   exe "NetrwKeepj e ".fnameescape(fname)
7823  endif
7824  let @@= ykeep
7825"  call Dret("s:NetrwOpenFile")
7826endfun
7827
7828" ---------------------------------------------------------------------
7829" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
7830"               For the mapping to this function be made via
7831"               netrwPlugin, you'll need to have had
7832"               g:netrw_usetab set to non-zero.
7833fun! netrw#Shrink()
7834"  call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
7835  let curwin  = winnr()
7836  let wiwkeep = &wiw
7837  set wiw=1
7838
7839  if &ft == "netrw"
7840   if winwidth(0) > g:netrw_wiw
7841    let t:netrw_winwidth= winwidth(0)
7842    exe "vert resize ".g:netrw_wiw
7843    wincmd l
7844    if winnr() == curwin
7845     wincmd h
7846    endif
7847"    call Decho("vert resize 0",'~'.expand("<slnum>"))
7848   else
7849    exe "vert resize ".t:netrw_winwidth
7850"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7851   endif
7852
7853  elseif exists("t:netrw_lexbufnr")
7854   exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
7855   if     winwidth(bufwinnr(t:netrw_lexbufnr)) >  g:netrw_wiw
7856    let t:netrw_winwidth= winwidth(0)
7857    exe "vert resize ".g:netrw_wiw
7858    wincmd l
7859    if winnr() == curwin
7860     wincmd h
7861    endif
7862"    call Decho("vert resize 0",'~'.expand("<slnum>"))
7863   elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
7864    exe "vert resize ".t:netrw_winwidth
7865"    call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7866   else
7867    call netrw#Lexplore(0,0)
7868   endif
7869
7870  else
7871   call netrw#Lexplore(0,0)
7872  endif
7873  let wiw= wiwkeep
7874
7875"  call Dret("netrw#Shrink")
7876endfun
7877
7878" ---------------------------------------------------------------------
7879" s:NetSortSequence: allows user to edit the sorting sequence {{{2
7880fun! s:NetSortSequence(islocal)
7881"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
7882
7883  let ykeep= @@
7884  let svpos= winsaveview()
7885"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7886  call inputsave()
7887  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
7888  call inputrestore()
7889
7890  " refresh the listing
7891  let g:netrw_sort_sequence= newsortseq
7892  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7893"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7894  NetrwKeepj call winrestview(svpos)
7895  let @@= ykeep
7896
7897"  call Dret("NetSortSequence")
7898endfun
7899
7900" ---------------------------------------------------------------------
7901" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
7902"   User access provided by the <mF> mapping. (see :help netrw-mF)
7903"   Used by many MarkFile functions.
7904fun! s:NetrwUnmarkList(curbufnr,curdir)
7905"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
7906
7907  "  remove all files in local marked-file list from global list
7908  if exists("s:netrwmarkfilelist")
7909   for mfile in s:netrwmarkfilelist_{a:curbufnr}
7910    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
7911    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
7912    call remove(s:netrwmarkfilelist,idx)            " remove from global list
7913   endfor
7914   if s:netrwmarkfilelist == []
7915    unlet s:netrwmarkfilelist
7916   endif
7917
7918   " getting rid of the local marked-file lists is easy
7919   unlet s:netrwmarkfilelist_{a:curbufnr}
7920  endif
7921  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
7922   unlet s:netrwmarkfilemtch_{a:curbufnr}
7923  endif
7924  2match none
7925"  call Dret("s:NetrwUnmarkList")
7926endfun
7927
7928" ---------------------------------------------------------------------
7929" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
7930fun! s:NetrwUnmarkAll()
7931"  call Dfunc("s:NetrwUnmarkAll()")
7932  if exists("s:netrwmarkfilelist")
7933   unlet s:netrwmarkfilelist
7934  endif
7935  sil call s:NetrwUnmarkAll2()
7936  2match none
7937"  call Dret("s:NetrwUnmarkAll")
7938endfun
7939
7940" ---------------------------------------------------------------------
7941" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
7942fun! s:NetrwUnmarkAll2()
7943"  call Dfunc("s:NetrwUnmarkAll2()")
7944  redir => netrwmarkfilelist_let
7945  let
7946  redir END
7947  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
7948  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
7949  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
7950  for flist in netrwmarkfilelist_list
7951   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
7952   unlet s:netrwmarkfilelist_{curbufnr}
7953   unlet s:netrwmarkfilemtch_{curbufnr}
7954  endfor
7955"  call Dret("s:NetrwUnmarkAll2")
7956endfun
7957
7958" ---------------------------------------------------------------------
7959" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
7960"
7961" Marked files are in two types of lists:
7962"    s:netrwmarkfilelist    -- holds complete paths to all marked files
7963"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
7964"
7965" Marked files suitable for use with 2match are in:
7966"    s:netrwmarkfilemtch_#   -- used with 2match to display marked files
7967fun! s:NetrwUnMarkFile(islocal)
7968"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
7969  let svpos    = winsaveview()
7970"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7971  let curbufnr = bufnr("%")
7972
7973  " unmark marked file list
7974  " (although I expect s:NetrwUpload() to do it, I'm just making sure)
7975  if exists("s:netrwmarkfilelist")
7976"   "   call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
7977   unlet s:netrwmarkfilelist
7978  endif
7979
7980  let ibuf= 1
7981  while ibuf < bufnr("$")
7982   if exists("s:netrwmarkfilelist_".ibuf)
7983    unlet s:netrwmarkfilelist_{ibuf}
7984    unlet s:netrwmarkfilemtch_{ibuf}
7985   endif
7986   let ibuf = ibuf + 1
7987  endwhile
7988  2match none
7989
7990"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
7991"call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7992call winrestview(svpos)
7993"  call Dret("s:NetrwUnMarkFile")
7994endfun
7995
7996" ---------------------------------------------------------------------
7997" s:NetrwMenu: generates the menu for gvim and netrw {{{2
7998fun! s:NetrwMenu(domenu)
7999
8000  if !exists("g:NetrwMenuPriority")
8001   let g:NetrwMenuPriority= 80
8002  endif
8003
8004  if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8005"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
8006
8007   if !exists("s:netrw_menu_enabled") && a:domenu
8008"    call Decho("initialize menu",'~'.expand("<slnum>"))
8009    let s:netrw_menu_enabled= 1
8010    exe 'sil! menu '.g:NetrwMenuPriority.'.1      '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
8011    exe 'sil! menu '.g:NetrwMenuPriority.'.5      '.g:NetrwTopLvlMenu.'-Sep1-	:'
8012    exe 'sil! menu '.g:NetrwMenuPriority.'.6      '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
8013    exe 'sil! menu '.g:NetrwMenuPriority.'.7      '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
8014    if g:netrw_dirhistmax > 0
8015     exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
8016     exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
8017     exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
8018     exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
8019    else
8020     exe 'sil! menu '.g:NetrwMenuPriority.'.8     '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History	:echo "(disabled)"'."\<cr>"
8021    endif
8022    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1    '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o	o'
8023    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2    '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v	v'
8024    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3    '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t	t'
8025    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4    '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p	p'
8026    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
8027    exe 'sil! menu '.g:NetrwMenuPriority.'.9.6    '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
8028    exe 'sil! menu '.g:NetrwMenuPriority.'.9.7    '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
8029    exe 'sil! menu '.g:NetrwMenuPriority.'.9.8    '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
8030    exe 'sil! menu '.g:NetrwMenuPriority.'.9.9    '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
8031    exe 'sil! menu '.g:NetrwMenuPriority.'.10     '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
8032    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
8033    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
8034    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
8035    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
8036    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
8037    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t	t'
8038    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5   '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
8039    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1   '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
8040    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
8041    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2   '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
8042    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
8043    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
8044    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
8045    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4   '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
8046    exe 'sil! menu '.g:NetrwMenuPriority.'.13     '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
8047    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
8048    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2   '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
8049    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3   '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
8050    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4   '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
8051    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5   '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
8052    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6   '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
8053    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7   '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
8054    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8   '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
8055    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9   '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
8056    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10  '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
8057    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11  '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
8058    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12  '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
8059    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13  '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
8060    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14  '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
8061    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15  '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
8062    exe 'sil! menu '.g:NetrwMenuPriority.'.15     '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
8063    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i	:let w:netrw_liststyle=0<cr><c-L>'
8064    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i	:let w:netrw_liststyle=1<cr><c-L>'
8065    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i	:let w:netrw_liststyle=2<cr><c-L>'
8066    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i	:let w:netrw_liststyle=3<cr><c-L>'
8067    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>'
8068    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>'
8069    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>'
8070    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3   '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
8071    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>'
8072    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>'
8073    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>'
8074    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>'
8075    exe 'sil! menu '.g:NetrwMenuPriority.'.17     '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
8076    exe 'sil! menu '.g:NetrwMenuPriority.'.18     '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
8077    let s:netrw_menucnt= 28
8078    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
8079    call s:NetrwTgtMenu()      " let bookmarks and history be easy targets
8080
8081   elseif !a:domenu
8082    let s:netrwcnt = 0
8083    let curwin     = winnr()
8084    windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8085    exe curwin."wincmd w"
8086
8087    if s:netrwcnt <= 1
8088"     call Decho("clear menus",'~'.expand("<slnum>"))
8089     exe 'sil! unmenu '.g:NetrwTopLvlMenu
8090"     call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8091     sil! unlet s:netrw_menu_enabled
8092    endif
8093   endif
8094"   call Dret("NetrwMenu")
8095   return
8096  endif
8097
8098endfun
8099
8100" ---------------------------------------------------------------------
8101" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8102"                Used by the O maps (as <SID>NetrwObtain())
8103fun! s:NetrwObtain(islocal)
8104"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8105
8106  let ykeep= @@
8107  if exists("s:netrwmarkfilelist_{bufnr('%')}")
8108   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8109   call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8110   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
8111  else
8112   call netrw#Obtain(a:islocal,expand("<cWORD>"))
8113  endif
8114  let @@= ykeep
8115
8116"  call Dret("NetrwObtain")
8117endfun
8118
8119" ---------------------------------------------------------------------
8120" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
8121"   If there's only one window, then the window will first be split.
8122"   Returns:
8123"     choice = 0 : didn't have to choose
8124"     choice = 1 : saved modified file in window first
8125"     choice = 2 : didn't save modified file, opened window
8126"     choice = 3 : cancel open
8127fun! s:NetrwPrevWinOpen(islocal)
8128"  call Dfunc("s:NetrwPrevWinOpen(islocal=".a:islocal.")")
8129
8130  let ykeep= @@
8131  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8132  let curdir = b:netrw_curdir
8133
8134  " get last window number and the word currently under the cursor
8135  let origwin   = winnr()
8136  let lastwinnr = winnr("$")
8137  let curword   = s:NetrwGetWord()
8138  let choice    = 0
8139  let s:treedir = s:NetrwTreeDir(a:islocal)
8140  let curdir    = s:treedir
8141"  call Decho("winnr($)#".lastwinnr." curword<".curword.">",'~'.expand("<slnum>"))
8142
8143  let didsplit = 0
8144  if lastwinnr == 1
8145   " if only one window, open a new one first
8146"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")",'~'.expand("<slnum>"))
8147   if g:netrw_preview
8148    " vertically split preview window
8149    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8150"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s",'~'.expand("<slnum>"))
8151    exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8152   else
8153    " horizontally split preview window
8154    let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8155"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8156    exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8157   endif
8158   let didsplit = 1
8159"   call Decho("did split",'~'.expand("<slnum>"))
8160
8161  else
8162   NetrwKeepj call s:SaveBufVars()
8163   let eikeep= &ei
8164   setl ei=all
8165   wincmd p
8166"   call Decho("wincmd p  (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
8167
8168   " prevwinnr: the window number of the "prev" window
8169   " prevbufnr: the buffer number of the buffer in the "prev" window
8170   " bnrcnt   : the qty of windows open on the "prev" buffer
8171   let prevwinnr   = winnr()
8172   let prevbufnr   = bufnr("%")
8173   let prevbufname = bufname("%")
8174   let prevmod     = &mod
8175   let bnrcnt      = 0
8176   NetrwKeepj call s:RestoreBufVars()
8177"   call Decho("after wincmd p: win#".winnr()." win($)#".winnr("$")." origwin#".origwin." &mod=".&mod." bufname(%)<".bufname("%")."> prevbufnr=".prevbufnr,'~'.expand("<slnum>"))
8178
8179   " if the previous window's buffer has been changed (ie. its modified flag is set),
8180   " and it doesn't appear in any other extant window, then ask the
8181   " user if s/he wants to abandon modifications therein.
8182   if prevmod
8183"    call Decho("detected that prev window's buffer has been modified: prevbufnr=".prevbufnr." winnr()#".winnr(),'~'.expand("<slnum>"))
8184    windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8185"    call Decho("prevbufnr=".prevbufnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr()=".winnr()." prevwinnr#".prevwinnr,'~'.expand("<slnum>"))
8186    exe prevwinnr."wincmd w"
8187
8188    if bnrcnt == 1 && &hidden == 0
8189     " only one copy of the modified buffer in a window, and
8190     " hidden not set, so overwriting will lose the modified file.  Ask first...
8191     let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8192"     call Decho("(NetrwPrevWinOpen) prevbufname<".prevbufname."> choice=".choice." current-winnr#".winnr(),'~'.expand("<slnum>"))
8193     let &ei= eikeep
8194
8195     if choice == 1
8196      " Yes -- write file & then browse
8197      let v:errmsg= ""
8198      sil w
8199      if v:errmsg != ""
8200       call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8201       exe origwin."wincmd w"
8202       let &ei = eikeep
8203       let @@  = ykeep
8204"       call Dret("s:NetrwPrevWinOpen ".choice." : unable to write <".prevbufname.">")
8205       return choice
8206      endif
8207
8208     elseif choice == 2
8209      " No -- don't worry about changed file, just browse anyway
8210"      call Decho("don't worry about chgd file, just browse anyway (winnr($)#".winnr("$").")",'~'.expand("<slnum>"))
8211      echomsg "**note** changes to ".prevbufname." abandoned"
8212
8213     else
8214      " Cancel -- don't do this
8215"      call Decho("cancel, don't browse, switch to win#".origwin,'~'.expand("<slnum>"))
8216      exe origwin."wincmd w"
8217      let &ei= eikeep
8218      let @@ = ykeep
8219"      call Dret("s:NetrwPrevWinOpen ".choice." : cancelled")
8220      return choice
8221     endif
8222    endif
8223   endif
8224   let &ei= eikeep
8225  endif
8226
8227  " restore b:netrw_curdir (window split/enew may have lost it)
8228  let b:netrw_curdir= curdir
8229  if a:islocal < 2
8230   if a:islocal
8231    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
8232   else
8233    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
8234   endif
8235  endif
8236  let @@= ykeep
8237"  call Dret("s:NetrwPrevWinOpen ".choice)
8238  return choice
8239endfun
8240
8241" ---------------------------------------------------------------------
8242" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8243"                Always assumed to be local -> remote
8244"                call s:NetrwUpload(filename, target)
8245"                call s:NetrwUpload(filename, target, fromdirectory)
8246fun! s:NetrwUpload(fname,tgt,...)
8247"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
8248
8249  if a:tgt =~ '^\a\{3,}://'
8250   let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
8251  else
8252   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
8253  endif
8254"  call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
8255
8256  if a:0 > 0
8257   let fromdir= a:1
8258  else
8259   let fromdir= getcwd()
8260  endif
8261"  call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
8262
8263  if type(a:fname) == 1
8264   " handle uploading a single file using NetWrite
8265"   call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8266   1split
8267"   call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8268   exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8269"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8270   if a:tgt =~ '/$'
8271    let wfname= substitute(a:fname,'^.*/','','')
8272"    call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8273    exe "w! ".fnameescape(a:tgt.wfname)
8274   else
8275"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8276    exe "w ".fnameescape(a:tgt)
8277"    call Decho("done writing local->remote",'~'.expand("<slnum>"))
8278   endif
8279   q!
8280
8281  elseif type(a:fname) == 3
8282   " handle uploading a list of files via scp
8283"   call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8284   let curdir= getcwd()
8285   if a:tgt =~ '^scp:'
8286    call s:NetrwLcd(fromdir)
8287    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8288    let args    = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8289    if exists("g:netrw_port") && g:netrw_port != ""
8290     let useport= " ".g:netrw_scpport." ".g:netrw_port
8291    else
8292     let useport= ""
8293    endif
8294    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8295    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8296    call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8297    call s:NetrwLcd(curdir)
8298
8299   elseif a:tgt =~ '^ftp:'
8300    call s:NetrwMethod(a:tgt)
8301
8302    if b:netrw_method == 2
8303     " handle uploading a list of files via ftp+.netrc
8304     let netrw_fname = b:netrw_fname
8305     sil NetrwKeepj new
8306"     call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8307
8308     NetrwKeepj put =g:netrw_ftpmode
8309"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8310
8311     if exists("g:netrw_ftpextracmd")
8312      NetrwKeepj put =g:netrw_ftpextracmd
8313"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8314     endif
8315
8316     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8317"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8318
8319     if tgtdir == ""
8320      let tgtdir= '/'
8321     endif
8322     NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8323"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8324
8325     for fname in a:fname
8326      NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8327"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8328     endfor
8329
8330     if exists("g:netrw_port") && g:netrw_port != ""
8331      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8332     else
8333"      call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8334      call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8335     endif
8336     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8337     sil NetrwKeepj g/Local directory now/d
8338     call histdel("/",-1)
8339     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8340      call netrw#ErrorMsg(s:ERROR,getline(1),14)
8341     else
8342      bw!|q
8343     endif
8344
8345    elseif b:netrw_method == 3
8346     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8347     let netrw_fname= b:netrw_fname
8348     NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8349     let tmpbufnr= bufnr("%")
8350     setl ff=unix
8351
8352     if exists("g:netrw_port") && g:netrw_port != ""
8353      NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8354"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8355     else
8356      NetrwKeepj put ='open '.g:netrw_machine
8357"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8358     endif
8359
8360     if exists("g:netrw_uid") && g:netrw_uid != ""
8361      if exists("g:netrw_ftp") && g:netrw_ftp == 1
8362       NetrwKeepj put =g:netrw_uid
8363"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8364       if exists("s:netrw_passwd")
8365        NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8366       endif
8367"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8368      elseif exists("s:netrw_passwd")
8369       NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8370"       call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8371      endif
8372     endif
8373
8374     NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8375"     call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8376
8377     if exists("b:netrw_fname") && b:netrw_fname != ""
8378      NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8379"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8380     endif
8381
8382     if exists("g:netrw_ftpextracmd")
8383      NetrwKeepj put =g:netrw_ftpextracmd
8384"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8385     endif
8386
8387     for fname in a:fname
8388      NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8389"      call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8390     endfor
8391
8392     " perform ftp:
8393     " -i       : turns off interactive prompting from ftp
8394     " -n  unix : DON'T use <.netrc>, even though it exists
8395     " -n  win32: quit being obnoxious about password
8396     NetrwKeepj norm! 1Gdd
8397     call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8398     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8399     sil NetrwKeepj g/Local directory now/d
8400     call histdel("/",-1)
8401     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8402      let debugkeep= &debug
8403      setl debug=msg
8404      call netrw#ErrorMsg(s:ERROR,getline(1),15)
8405      let &debug = debugkeep
8406      let mod    = 1
8407     else
8408      bw!|q
8409     endif
8410    elseif !exists("b:netrw_method") || b:netrw_method < 0
8411"     call Dfunc("netrw#NetrwUpload : unsupported method")
8412     return
8413    endif
8414   else
8415    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
8416   endif
8417  endif
8418
8419"  call Dret("s:NetrwUpload")
8420endfun
8421
8422" ---------------------------------------------------------------------
8423" s:NetrwPreview: {{{2
8424fun! s:NetrwPreview(path) range
8425"  call Dfunc("NetrwPreview(path<".a:path.">)")
8426  let ykeep= @@
8427  NetrwKeepj call s:NetrwOptionSave("s:")
8428  NetrwKeepj call s:NetrwSafeOptions()
8429  if has("quickfix")
8430   if !isdirectory(s:NetrwFile(a:path))
8431    if g:netrw_preview && !g:netrw_alto
8432     let pvhkeep = &pvh
8433     let winsz   = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8434     let &pvh    = winwidth(0) - winsz
8435    endif
8436    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8437    if exists("pvhkeep")
8438     let &pvh= pvhkeep
8439    endif
8440   elseif !exists("g:netrw_quiet")
8441    NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
8442   endif
8443  elseif !exists("g:netrw_quiet")
8444   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
8445  endif
8446  NetrwKeepj call s:NetrwOptionRestore("s:")
8447  let @@= ykeep
8448"  call Dret("NetrwPreview")
8449endfun
8450
8451" ---------------------------------------------------------------------
8452" s:NetrwRefresh: {{{2
8453fun! s:NetrwRefresh(islocal,dirname)
8454"  call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction)
8455  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
8456  setl ma noro
8457"  call Decho("setl ma noro",'~'.expand("<slnum>"))
8458"  call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8459  let ykeep      = @@
8460
8461  " save the cursor position before refresh.
8462  let screenposn = winsaveview()
8463"  call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8464
8465"  call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8466"  call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
8467  sil! NetrwKeepj %d _
8468  if a:islocal
8469   NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
8470  else
8471   NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
8472  endif
8473
8474  " restore position
8475"  call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
8476  NetrwKeepj call winrestview(screenposn)
8477
8478  " restore file marks
8479  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8480"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8481   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8482  else
8483"   call Decho("2match none  (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8484   2match none
8485  endif
8486
8487"  restore
8488  let @@= ykeep
8489"  call Dret("s:NetrwRefresh")
8490endfun
8491
8492" ---------------------------------------------------------------------
8493" s:NetrwRefreshDir: refreshes a directory by name {{{2
8494"                    Called by NetrwMarkFileCopy()
8495"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
8496fun! s:NetrwRefreshDir(islocal,dirname)
8497"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) g:netrw_fastbrowse=".g:netrw_fastbrowse)
8498  if g:netrw_fastbrowse == 0
8499   " slowest mode (keep buffers refreshed, local or remote)
8500"   call Decho("slowest mode: keep buffers refreshed, local or remote",'~'.expand("<slnum>"))
8501   let tgtwin= bufwinnr(a:dirname)
8502"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin,'~'.expand("<slnum>"))
8503
8504   if tgtwin > 0
8505    " tgtwin is being displayed, so refresh it
8506    let curwin= winnr()
8507"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")",'~'.expand("<slnum>"))
8508    exe tgtwin."wincmd w"
8509    NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8510    exe curwin."wincmd w"
8511
8512   elseif bufnr(a:dirname) > 0
8513    let bn= bufnr(a:dirname)
8514"    call Decho("bd bufnr(".a:dirname.")=".bn,'~'.expand("<slnum>"))
8515    exe "sil keepj bd ".bn
8516   endif
8517
8518  elseif g:netrw_fastbrowse <= 1
8519"   call Decho("medium-speed mode: refresh local buffers only",'~'.expand("<slnum>"))
8520   NetrwKeepj call s:LocalBrowseRefresh()
8521  endif
8522"  call Dret("s:NetrwRefreshDir")
8523endfun
8524
8525" ---------------------------------------------------------------------
8526" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8527" window number to do its editing in.
8528" Supports   [count]C  where the count, if present, is used to specify
8529" a window to use for editing via the <cr> mapping.
8530fun! s:NetrwSetChgwin(...)
8531"  call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
8532  if a:0 > 0
8533"   call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8534   if a:1 == ""    " :NetrwC win#
8535    let g:netrw_chgwin= winnr()
8536   else              " :NetrwC
8537    let g:netrw_chgwin= a:1
8538   endif
8539  elseif v:count > 0 " [count]C
8540   let g:netrw_chgwin= v:count
8541  else               " C
8542   let g:netrw_chgwin= winnr()
8543  endif
8544  echo "editing window now set to window#".g:netrw_chgwin
8545"  call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
8546endfun
8547
8548" ---------------------------------------------------------------------
8549" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8550"          What this function does is to compute a priority for the patterns
8551"          in the g:netrw_sort_sequence.  It applies a substitute to any
8552"          "files" that satisfy each pattern, putting the priority / in
8553"          front.  An "*" pattern handles the default priority.
8554fun! s:NetrwSetSort()
8555"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
8556  let ykeep= @@
8557  if w:netrw_liststyle == s:LONGLIST
8558   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
8559  else
8560   let seqlist  = g:netrw_sort_sequence
8561  endif
8562  " sanity check -- insure that * appears somewhere
8563  if seqlist == ""
8564   let seqlist= '*'
8565  elseif seqlist !~ '\*'
8566   let seqlist= seqlist.',*'
8567  endif
8568  let priority = 1
8569  while seqlist != ""
8570   if seqlist =~ ','
8571    let seq     = substitute(seqlist,',.*$','','e')
8572    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
8573   else
8574    let seq     = seqlist
8575    let seqlist = ""
8576   endif
8577   if priority < 10
8578    let spriority= "00".priority.g:netrw_sepchr
8579   elseif priority < 100
8580    let spriority= "0".priority.g:netrw_sepchr
8581   else
8582    let spriority= priority.g:netrw_sepchr
8583   endif
8584"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
8585
8586   " sanity check
8587   if w:netrw_bannercnt > line("$")
8588    " apparently no files were left after a Hiding pattern was used
8589"    call Dret("SetSort : no files left after hiding")
8590    return
8591   endif
8592   if seq == '*'
8593    let starpriority= spriority
8594   else
8595    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
8596    call histdel("/",-1)
8597    " sometimes multiple sorting patterns will match the same file or directory.
8598    " The following substitute is intended to remove the excess matches.
8599    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
8600    NetrwKeepj call histdel("/",-1)
8601   endif
8602   let priority = priority + 1
8603  endwhile
8604  if exists("starpriority")
8605   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
8606   NetrwKeepj call histdel("/",-1)
8607  endif
8608
8609  " Following line associated with priority -- items that satisfy a priority
8610  " pattern get prefixed by ###/ which permits easy sorting by priority.
8611  " Sometimes files can satisfy multiple priority patterns -- only the latest
8612  " priority pattern needs to be retained.  So, at this point, these excess
8613  " priority prefixes need to be removed, but not directories that happen to
8614  " be just digits themselves.
8615  exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
8616  NetrwKeepj call histdel("/",-1)
8617  let @@= ykeep
8618
8619"  call Dret("SetSort")
8620endfun
8621
8622" ---------------------------------------------------------------------
8623" s:NetrwSetTgt: sets the target to the specified choice index {{{2
8624"    Implements [count]Tb  (bookhist<b>)
8625"               [count]Th  (bookhist<h>)
8626"               See :help netrw-qb for how to make the choice.
8627fun! s:NetrwSetTgt(islocal,bookhist,choice)
8628"  call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
8629
8630  if     a:bookhist == 'b'
8631   " supports choosing a bookmark as a target using a qb-generated list
8632   let choice= a:choice - 1
8633   if exists("g:netrw_bookmarklist[".choice."]")
8634    call netrw#MakeTgt(g:netrw_bookmarklist[choice])
8635   else
8636    echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
8637   endif
8638
8639  elseif a:bookhist == 'h'
8640   " supports choosing a history stack entry as a target using a qb-generated list
8641   let choice= (a:choice % g:netrw_dirhistmax) + 1
8642   if exists("g:netrw_dirhist_".choice)
8643    let histentry = g:netrw_dirhist_{choice}
8644    call netrw#MakeTgt(histentry)
8645   else
8646    echomsg "Sorry, history#".a:choice." not available!"
8647   endif
8648  endif
8649
8650  " refresh the display
8651  if !exists("b:netrw_curdir")
8652   let b:netrw_curdir= getcwd()
8653  endif
8654  call s:NetrwRefresh(a:islocal,b:netrw_curdir)
8655
8656"  call Dret("s:NetrwSetTgt")
8657endfun
8658
8659" =====================================================================
8660" s:NetrwSortStyle: change sorting style (name - time - size) and refresh display {{{2
8661fun! s:NetrwSortStyle(islocal)
8662"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
8663  NetrwKeepj call s:NetrwSaveWordPosn()
8664  let svpos= winsaveview()
8665"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8666
8667  let g:netrw_sort_by= (g:netrw_sort_by =~# '^n')? 'time' : (g:netrw_sort_by =~# '^t')? 'size' : (g:netrw_sort_by =~# '^siz')? 'exten' : 'name'
8668  NetrwKeepj norm! 0
8669  NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
8670"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
8671  NetrwKeepj call winrestview(svpos)
8672
8673"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
8674endfun
8675
8676" ---------------------------------------------------------------------
8677" s:NetrwSplit: mode {{{2
8678"           =0 : net   and o
8679"           =1 : net   and t
8680"           =2 : net   and v
8681"           =3 : local and o
8682"           =4 : local and t
8683"           =5 : local and v
8684fun! s:NetrwSplit(mode)
8685"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
8686
8687  let ykeep= @@
8688  call s:SaveWinVars()
8689
8690  if a:mode == 0
8691   " remote and o
8692   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8693   if winsz == 0|let winsz= ""|endif
8694"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8695   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8696   let s:didsplit= 1
8697   NetrwKeepj call s:RestoreWinVars()
8698   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
8699   unlet s:didsplit
8700
8701  elseif a:mode == 1
8702   " remote and t
8703   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
8704"   call Decho("tabnew",'~'.expand("<slnum>"))
8705   tabnew
8706   let s:didsplit= 1
8707   NetrwKeepj call s:RestoreWinVars()
8708   NetrwKeepj call s:NetrwBrowse(0,newdir)
8709   unlet s:didsplit
8710
8711  elseif a:mode == 2
8712   " remote and v
8713   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8714   if winsz == 0|let winsz= ""|endif
8715"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
8716   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8717   let s:didsplit= 1
8718   NetrwKeepj call s:RestoreWinVars()
8719   NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
8720   unlet s:didsplit
8721
8722  elseif a:mode == 3
8723   " local and o
8724   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8725   if winsz == 0|let winsz= ""|endif
8726"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s",'~'.expand("<slnum>"))
8727   exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8728   let s:didsplit= 1
8729   NetrwKeepj call s:RestoreWinVars()
8730   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8731   unlet s:didsplit
8732
8733  elseif a:mode == 4
8734   " local and t
8735   let cursorword  = s:NetrwGetWord()
8736   let eikeep      = &ei
8737   let netrw_winnr = winnr()
8738   let netrw_line  = line(".")
8739   let netrw_col   = virtcol(".")
8740   NetrwKeepj norm! H0
8741   let netrw_hline = line(".")
8742   setl ei=all
8743   exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8744   exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8745   let &ei          = eikeep
8746   let netrw_curdir = s:NetrwTreeDir(0)
8747"   call Decho("tabnew",'~'.expand("<slnum>"))
8748   tabnew
8749   let b:netrw_curdir = netrw_curdir
8750   let s:didsplit     = 1
8751   NetrwKeepj call s:RestoreWinVars()
8752   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
8753   if &ft == "netrw"
8754    setl ei=all
8755    exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8756    exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8757    let &ei= eikeep
8758   endif
8759   unlet s:didsplit
8760
8761  elseif a:mode == 5
8762   " local and v
8763   let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8764   if winsz == 0|let winsz= ""|endif
8765"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v",'~'.expand("<slnum>"))
8766   exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8767   let s:didsplit= 1
8768   NetrwKeepj call s:RestoreWinVars()
8769   NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
8770   unlet s:didsplit
8771
8772  else
8773   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
8774  endif
8775
8776  let @@= ykeep
8777"  call Dret("s:NetrwSplit")
8778endfun
8779
8780" ---------------------------------------------------------------------
8781" s:NetrwTgtMenu: {{{2
8782fun! s:NetrwTgtMenu()
8783  if !exists("s:netrw_menucnt")
8784   return
8785  endif
8786"  call Dfunc("s:NetrwTgtMenu()")
8787
8788  " the following test assures that gvim is running, has menus available, and has menus enabled.
8789  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
8790   if exists("g:NetrwTopLvlMenu")
8791"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
8792    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
8793   endif
8794   if !exists("s:netrw_initbookhist")
8795    call s:NetrwBookHistRead()
8796   endif
8797
8798   " try to cull duplicate entries
8799   let tgtdict={}
8800
8801   " target bookmarked places
8802   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
8803"    call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
8804    let cnt= 1
8805    for bmd in g:netrw_bookmarklist
8806     if has_key(tgtdict,bmd)
8807      let cnt= cnt + 1
8808      continue
8809     endif
8810     let tgtdict[bmd]= cnt
8811     let ebmd= escape(bmd,g:netrw_menu_escape)
8812     " show bookmarks for goto menu
8813"     call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
8814     exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd."	:call netrw#MakeTgt('".bmd."')\<cr>"
8815     let cnt= cnt + 1
8816    endfor
8817   endif
8818
8819   " target directory browsing history
8820   if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
8821"    call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
8822    let histcnt = 1
8823    while histcnt <= g:netrw_dirhistmax
8824     let priority = g:netrw_dirhist_cnt + histcnt
8825     if exists("g:netrw_dirhist_{histcnt}")
8826      let histentry  = g:netrw_dirhist_{histcnt}
8827      if has_key(tgtdict,histentry)
8828       let histcnt = histcnt + 1
8829       continue
8830      endif
8831      let tgtdict[histentry] = histcnt
8832      let ehistentry         = escape(histentry,g:netrw_menu_escape)
8833"      call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
8834      exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry."	:call netrw#MakeTgt('".histentry."')\<cr>"
8835     endif
8836     let histcnt = histcnt + 1
8837    endwhile
8838   endif
8839  endif
8840"  call Dret("s:NetrwTgtMenu")
8841endfun
8842
8843" ---------------------------------------------------------------------
8844" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
8845" (full path directory with trailing slash returned)
8846fun! s:NetrwTreeDir(islocal)
8847"  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)
8848"  call Decho("g:netrw_keepdir  =".(exists("g:netrw_keepdir")?   g:netrw_keepdir   : 'n/a'),'~'.expand("<slnum>"))
8849"  call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
8850"  call Decho("w:netrw_treetop  =".(exists("w:netrw_treetop")?   w:netrw_treetop   : 'n/a'),'~'.expand("<slnum>"))
8851
8852  if exists("s:treedir")
8853   " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
8854   let treedir= s:treedir
8855   unlet s:treedir
8856"   call Dret("s:NetrwTreeDir ".treedir)
8857   return treedir
8858  endif
8859
8860  if !exists("b:netrw_curdir") || b:netrw_curdir == ""
8861   let b:netrw_curdir= getcwd()
8862  endif
8863  let treedir = b:netrw_curdir
8864"  call Decho("set initial treedir<".treedir.">",'~'.expand("<slnum>"))
8865
8866  let s:treecurpos= winsaveview()
8867"  call Decho("saving posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
8868
8869  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8870"   call Decho("w:netrw_liststyle is TREELIST:",'~'.expand("<slnum>"))
8871"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
8872
8873   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
8874   let curline= substitute(getline('.'),"\t -->.*$",'','')
8875   if curline =~ '/$'
8876"    call Decho("extract tree subdirectory from current line",'~'.expand("<slnum>"))
8877    let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
8878"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8879   elseif curline =~ '@$'
8880"    call Decho("handle symbolic link from current line",'~'.expand("<slnum>"))
8881    let treedir= resolve(substitute(substitute(getline('.'),'@.*$','','e'),'^|*\s*','','e'))
8882"    call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8883   else
8884"    call Decho("do not extract tree subdirectory from current line and set treedir to empty",'~'.expand("<slnum>"))
8885    let treedir= ""
8886   endif
8887
8888   " detect user attempting to close treeroot
8889"   call Decho("check if user is attempting to close treeroot",'~'.expand("<slnum>"))
8890"   call Decho(".win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
8891"   call Decho(".getline(".line(".").")<".getline('.').'> '.((getline('.') =~# '^'.s:treedepthstring)? '=~#' : '!~').' ^'.s:treedepthstring,'~'.expand("<slnum>"))
8892   if curline !~ '^'.s:treedepthstring && getline('.') != '..'
8893"    call Decho(".user may have attempted to close treeroot",'~'.expand("<slnum>"))
8894    " now force a refresh
8895"    call Decho(".force refresh: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
8896    sil! NetrwKeepj %d _
8897"    call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
8898    return b:netrw_curdir
8899"   else " Decho
8900"    call Decho(".user not attempting to close treeroot",'~'.expand("<slnum>"))
8901   endif
8902
8903"   call Decho("islocal=".a:islocal." curline<".curline.">",'~'.expand("<slnum>"))
8904   let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
8905"   call Decho("potentialdir<".potentialdir."> isdir=".isdirectory(potentialdir),'~'.expand("<slnum>"))
8906
8907   " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
8908"   if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
8909"    let newdir          = w:netrw_treetop.'/'.potentialdir
8910" "   call Decho("apply NetrwTreePath to newdir<".newdir.">",'~'.expand("<slnum>"))
8911"    let treedir         = s:NetrwTreePath(newdir)
8912"    let w:netrw_treetop = newdir
8913" "   call Decho("newdir <".newdir.">",'~'.expand("<slnum>"))
8914"   else
8915"    call Decho("apply NetrwTreePath to treetop<".w:netrw_treetop.">",'~'.expand("<slnum>"))
8916    let treedir = s:NetrwTreePath(w:netrw_treetop)
8917"   endif
8918  endif
8919
8920  " sanity maintenance: keep those //s away...
8921  let treedir= substitute(treedir,'//$','/','')
8922"  call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
8923
8924"  call Dret("s:NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".(exists("s:treecurpos")? string(s:treecurpos) : 'n/a').">")
8925  return treedir
8926endfun
8927
8928" ---------------------------------------------------------------------
8929" s:NetrwTreeDisplay: recursive tree display {{{2
8930fun! s:NetrwTreeDisplay(dir,depth)
8931"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
8932
8933  " insure that there are no folds
8934  setl nofen
8935
8936  " install ../ and shortdir
8937  if a:depth == ""
8938   call setline(line("$")+1,'../')
8939"   call Decho("setline#".line("$")." ../ (depth is zero)",'~'.expand("<slnum>"))
8940  endif
8941  if a:dir =~ '^\a\{3,}://'
8942   if a:dir == w:netrw_treetop
8943    let shortdir= a:dir
8944   else
8945    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
8946   endif
8947   call setline(line("$")+1,a:depth.shortdir)
8948  else
8949   let shortdir= substitute(a:dir,'^.*/','','e')
8950   call setline(line("$")+1,a:depth.shortdir.'/')
8951  endif
8952"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">",'~'.expand("<slnum>"))
8953
8954  " append a / to dir if its missing one
8955  let dir= a:dir
8956
8957  " display subtrees (if any)
8958  let depth= s:treedepthstring.a:depth
8959"  call Decho("display subtrees with depth<".depth."> and current leaves",'~'.expand("<slnum>"))
8960
8961"  call Decho("for every entry in w:netrw_treedict[".dir."]=".string(w:netrw_treedict[dir]),'~'.expand("<slnum>"))
8962  for entry in w:netrw_treedict[dir]
8963   if dir =~ '/$'
8964    let direntry= substitute(dir.entry,'[@/]$','','e')
8965   else
8966    let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
8967   endif
8968"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
8969   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
8970"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
8971    NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
8972   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
8973"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
8974    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
8975   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
8976"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
8977    NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
8978   else
8979"    call Decho("<".entry."> is not a key in treedict (no subtree)",'~'.expand("<slnum>"))
8980    sil! NetrwKeepj call setline(line("$")+1,depth.entry)
8981   endif
8982  endfor
8983
8984"  call Dret("NetrwTreeDisplay")
8985endfun
8986
8987" ---------------------------------------------------------------------
8988" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
8989fun! s:NetrwRefreshTreeDict(dir)
8990"  call Dfunc("s:NetrwRefreshTreeDict(dir<".a:dir.">)")
8991  for entry in w:netrw_treedict[a:dir]
8992   let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
8993"   call Decho("a:dir<".a:dir."> entry<".entry."> direntry<".direntry.">",'~'.expand("<slnum>"))
8994
8995   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
8996"    call Decho("<".direntry."> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
8997    NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
8998    let liststar                   = s:NetrwGlob(direntry,'*',1)
8999    let listdotstar                = s:NetrwGlob(direntry,'.*',1)
9000    let w:netrw_treedict[direntry] = liststar + listdotstar
9001"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9002
9003   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
9004"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9005    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9006    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9007    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9008    let w:netrw_treedict[direntry]= liststar + listdotstar
9009"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9010
9011   elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
9012"    call Decho("<".direntry."/> is a key in treedict - display subtree for it",'~'.expand("<slnum>"))
9013    NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
9014    let liststar   = s:NetrwGlob(direntry.'/','*',1)
9015    let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
9016"    call Decho("updating w:netrw_treedict[".direntry.']='.string(w:netrw_treedict[direntry]),'~'.expand("<slnum>"))
9017
9018   else
9019"    call Decho('not updating w:netrw_treedict['.direntry.'] with entry<'.entry.'> (no subtree)',,'~'.expand("<slnum>"))
9020   endif
9021  endfor
9022"  call Dret("s:NetrwRefreshTreeDict")
9023endfun
9024
9025" ---------------------------------------------------------------------
9026" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
9027"                     Called by s:PerformListing()
9028fun! s:NetrwTreeListing(dirname)
9029  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
9030"   call Dfunc("NetrwTreeListing() bufname<".expand("%").">")
9031"   call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
9032"   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>"))
9033"   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>"))
9034
9035   " update the treetop
9036"   call Decho("update the treetop",'~'.expand("<slnum>"))
9037   if !exists("w:netrw_treetop")
9038    let w:netrw_treetop= a:dirname
9039"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>"))
9040   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
9041    let w:netrw_treetop= a:dirname
9042"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
9043   endif
9044
9045   if !exists("w:netrw_treedict")
9046    " insure that we have a treedict, albeit empty
9047"    call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
9048    let w:netrw_treedict= {}
9049   endif
9050
9051   " update the dictionary for the current directory
9052"   call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>"))
9053"   call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9054   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
9055   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
9056"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
9057   exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9058
9059   " if past banner, record word
9060   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
9061    let fname= expand("<cword>")
9062   else
9063    let fname= ""
9064   endif
9065"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
9066"   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>"))
9067
9068   " display from treetop on down
9069   NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
9070"   call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
9071
9072   " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
9073   while getline(1) =~ '^\s*$' && byte2line(1) > 0
9074"    call Decho("deleting blank line",'~'.expand("<slnum>"))
9075    1d
9076   endwhile
9077
9078   exe "setl ".g:netrw_bufsettings
9079
9080"   call Dret("NetrwTreeListing : bufname<".expand("%").">")
9081   return
9082  endif
9083endfun
9084
9085" ---------------------------------------------------------------------
9086" s:NetrwTreePath: returns path to current file in tree listing {{{2
9087"                  Normally, treetop is w:netrw_treetop, but a
9088"                  user of the function ( netrw#SetTreetop() )
9089"                  wipes that out prior to calling this function
9090fun! s:NetrwTreePath(treetop)
9091"  call Dfunc("s:NetrwTreePath() line#".line(".")."<".getline(".").">")
9092  let svpos = winsaveview()
9093"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9094  let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
9095"  call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
9096  let depth = substitute(depth,'^'.s:treedepthstring,'','')
9097"  call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
9098  let curline= getline('.')
9099"  call Decho("curline<".curline.'>','~'.expand("<slnum>"))
9100  if curline =~ '/$'
9101"   call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9102   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9103"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9104  elseif curline =~ '@\s\+-->'
9105"   call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9106   let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9107   let treedir= substitute(treedir,'@\s\+-->.*$','','e')
9108"   call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
9109  else
9110"   call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9111   let treedir= ""
9112  endif
9113  " construct treedir by searching backwards at correct depth
9114"  call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9115"  call Decho("initial      treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
9116  while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
9117   let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9118   let treedir= dirname.treedir
9119   let depth  = substitute(depth,'^'.s:treedepthstring,'','')
9120"   call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
9121  endwhile
9122  if a:treetop =~ '/$'
9123   let treedir= a:treetop.treedir
9124  else
9125   let treedir= a:treetop.'/'.treedir
9126  endif
9127  let treedir= substitute(treedir,'//$','/','')
9128"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
9129  call winrestview(svpos)
9130"  call Dret("s:NetrwTreePath <".treedir.">")
9131  return treedir
9132endfun
9133
9134" ---------------------------------------------------------------------
9135" s:NetrwWideListing: {{{2
9136fun! s:NetrwWideListing()
9137
9138  if w:netrw_liststyle == s:WIDELIST
9139"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9140   " look for longest filename (cpf=characters per filename)
9141   " cpf: characters per filename
9142   " fpl: filenames per line
9143   " fpc: filenames per column
9144   setl ma noro
9145"   call Decho("setl ma noro",'~'.expand("<slnum>"))
9146   let b:netrw_cpf= 0
9147   if line("$") >= w:netrw_bannercnt
9148    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
9149    NetrwKeepj call histdel("/",-1)
9150   else
9151"    call Dret("NetrwWideListing")
9152    return
9153   endif
9154   let b:netrw_cpf= b:netrw_cpf + 2
9155"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
9156
9157   " determine qty files per line (fpl)
9158   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9159   if w:netrw_fpl <= 0
9160    let w:netrw_fpl= 1
9161   endif
9162"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
9163
9164   " make wide display
9165   "   fpc: files per column of wide listing
9166   exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9167   NetrwKeepj call histdel("/",-1)
9168   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9169   let newcolstart = w:netrw_bannercnt + fpc
9170   let newcolend   = newcolstart + fpc - 1
9171"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9172   if has("clipboard")
9173    sil! let keepregstar = @*
9174    sil! let keepregplus = @+
9175   endif
9176   while line("$") >= newcolstart
9177    if newcolend > line("$") | let newcolend= line("$") | endif
9178    let newcolqty= newcolend - newcolstart
9179    exe newcolstart
9180    if newcolqty == 0
9181     exe "sil! NetrwKeepj norm! 0\<c-v>$hx".w:netrw_bannercnt."G$p"
9182    else
9183     exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$hx'.w:netrw_bannercnt.'G$p'
9184    endif
9185    exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
9186    exe 'sil! NetrwKeepj '.w:netrw_bannercnt
9187   endwhile
9188   if has("clipboard")
9189    sil! let @*= keepregstar
9190    sil! let @+= keepregplus
9191   endif
9192   exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9193   NetrwKeepj call histdel("/",-1)
9194   exe 'nno <buffer> <silent> w	:call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9195   exe 'nno <buffer> <silent> b	:call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9196"   call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9197   exe "setl ".g:netrw_bufsettings
9198"   call Decho("(NetrwWideListing) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9199"   call Dret("NetrwWideListing")
9200   return
9201  else
9202   if hasmapto("w","n")
9203    sil! nunmap <buffer> w
9204   endif
9205   if hasmapto("b","n")
9206    sil! nunmap <buffer> b
9207   endif
9208  endif
9209
9210endfun
9211
9212" ---------------------------------------------------------------------
9213" s:PerformListing: {{{2
9214fun! s:PerformListing(islocal)
9215"  call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9216"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9217"  call Decho("settings: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (enter)",'~'.expand("<slnum>"))
9218
9219  " set up syntax highlighting {{{3
9220"  call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
9221  sil! setl ft=netrw
9222
9223  NetrwKeepj call s:NetrwSafeOptions()
9224  setl noro ma
9225"  call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
9226
9227"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
9228"   call Decho("(netrw) Processing your browsing request...",'~'.expand("<slnum>"))
9229"  endif								" Decho
9230
9231"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
9232  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
9233   " force a refresh for tree listings
9234"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9235   sil! NetrwKeepj %d _
9236  endif
9237
9238  " save current directory on directory history list
9239  NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
9240
9241  " Set up the banner {{{3
9242  if g:netrw_banner
9243"   call Decho("--set up banner",'~'.expand("<slnum>"))
9244   NetrwKeepj call setline(1,'" ============================================================================')
9245   if exists("g:netrw_pchk")
9246    " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9247    " failure detections.
9248    NetrwKeepj call setline(2,'" Netrw Directory Listing')
9249   else
9250    NetrwKeepj call setline(2,'" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')')
9251   endif
9252   if exists("g:netrw_pchk")
9253    let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9254   else
9255    let curdir= b:netrw_curdir
9256   endif
9257   if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9258    NetrwKeepj call setline(3,'"   '.substitute(curdir,'/','\\','g'))
9259   else
9260    NetrwKeepj call setline(3,'"   '.curdir)
9261   endif
9262   let w:netrw_bannercnt= 3
9263   NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
9264  else
9265"   call Decho("--no banner",'~'.expand("<slnum>"))
9266   NetrwKeepj 1
9267   let w:netrw_bannercnt= 1
9268  endif
9269"  call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9270"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9271
9272  let sortby= g:netrw_sort_by
9273  if g:netrw_sort_direction =~# "^r"
9274   let sortby= sortby." reversed"
9275  endif
9276
9277  " Sorted by... {{{3
9278  if g:netrw_banner
9279"   call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9280   if g:netrw_sort_by =~# "^n"
9281"   call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9282    " sorted by name
9283    NetrwKeepj put ='\"   Sorted by      '.sortby
9284    NetrwKeepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
9285    let w:netrw_bannercnt= w:netrw_bannercnt + 2
9286   else
9287"   call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9288    " sorted by size or date
9289    NetrwKeepj put ='\"   Sorted by '.sortby
9290    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9291   endif
9292   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9293"  else " Decho
9294"   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>"))
9295  endif
9296
9297  " show copy/move target, if any
9298  if g:netrw_banner
9299   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9300"    call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9301    NetrwKeepj put =''
9302    if s:netrwmftgt_islocal
9303     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9304    else
9305     sil! NetrwKeepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9306    endif
9307    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9308   else
9309"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
9310   endif
9311   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9312  endif
9313
9314  " Hiding...  -or-  Showing... {{{3
9315  if g:netrw_banner
9316"   call Decho("--handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9317   if g:netrw_list_hide != "" && g:netrw_hide
9318    if g:netrw_hide == 1
9319     NetrwKeepj put ='\"   Hiding:        '.g:netrw_list_hide
9320    else
9321     NetrwKeepj put ='\"   Showing:       '.g:netrw_list_hide
9322    endif
9323    let w:netrw_bannercnt= w:netrw_bannercnt + 1
9324   endif
9325   exe "NetrwKeepj ".w:netrw_bannercnt
9326
9327"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9328   let quickhelp   = g:netrw_quickhelp%len(s:QuickHelp)
9329"   call Decho("quickhelp   =".quickhelp,'~'.expand("<slnum>"))
9330   NetrwKeepj put ='\"   Quick Help: <F1>:help  '.s:QuickHelp[quickhelp]
9331"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9332   NetrwKeepj put ='\" =============================================================================='
9333   let w:netrw_bannercnt= w:netrw_bannercnt + 2
9334"  else " Decho
9335"   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>"))
9336  endif
9337
9338  " bannercnt should index the line just after the banner
9339  if g:netrw_banner
9340   let w:netrw_bannercnt= w:netrw_bannercnt + 1
9341   exe "sil! NetrwKeepj ".w:netrw_bannercnt
9342"   call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9343"  else " Decho
9344"   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>"))
9345  endif
9346
9347  " get list of files
9348"  call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
9349  if a:islocal
9350   NetrwKeepj call s:LocalListing()
9351  else " remote
9352   NetrwKeepj let badresult= s:NetrwRemoteListing()
9353   if badresult
9354"    call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9355"    call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9356    return
9357   endif
9358  endif
9359
9360  " manipulate the directory listing (hide, sort) {{{3
9361  if !exists("w:netrw_bannercnt")
9362   let w:netrw_bannercnt= 0
9363  endif
9364"  call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9365"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9366"  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>"))
9367
9368  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9369"   call Decho("manipulate directory listing (hide)",'~'.expand("<slnum>"))
9370"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9371   if g:netrw_hide && g:netrw_list_hide != ""
9372    NetrwKeepj call s:NetrwListHide()
9373   endif
9374   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9375"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9376
9377    if g:netrw_sort_by =~# "^n"
9378     " sort by name
9379     NetrwKeepj call s:NetrwSetSort()
9380
9381     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9382"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9383      if g:netrw_sort_direction =~# 'n'
9384       " normal direction sorting
9385       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9386      else
9387       " reverse direction sorting
9388       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9389      endif
9390     endif
9391     " remove priority pattern prefix
9392"     call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9393     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9394     NetrwKeepj call histdel("/",-1)
9395
9396    elseif g:netrw_sort_by =~# "^ext"
9397     " sort by extension
9398     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9399     NetrwKeepj call histdel("/",-1)
9400     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9401     NetrwKeepj call histdel("/",-1)
9402     exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9403     NetrwKeepj call histdel("/",-1)
9404     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9405"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9406      if g:netrw_sort_direction =~# 'n'
9407       " normal direction sorting
9408       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9409      else
9410       " reverse direction sorting
9411       exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9412      endif
9413     endif
9414     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9415     NetrwKeepj call histdel("/",-1)
9416
9417    elseif a:islocal
9418     if !g:netrw_banner || w:netrw_bannercnt < line("$")
9419"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9420      if g:netrw_sort_direction =~# 'n'
9421"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9422       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9423      else
9424"       call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9425       exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9426      endif
9427     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9428     NetrwKeepj call histdel("/",-1)
9429     endif
9430    endif
9431
9432   elseif g:netrw_sort_direction =~# 'r'
9433"    call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9434    if !g:netrw_banner || w:netrw_bannercnt < line('$')
9435     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9436     call histdel("/",-1)
9437    endif
9438   endif
9439  endif
9440"  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>"))
9441
9442  " convert to wide/tree listing {{{3
9443"  call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9444"  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>"))
9445  NetrwKeepj call s:NetrwWideListing()
9446"  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>"))
9447  NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
9448"  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>"))
9449
9450  " resolve symbolic links if local and (thin or tree)
9451  if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
9452"   call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9453   g/@$/call s:ShowLink()
9454  endif
9455
9456  if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
9457   " place cursor on the top-left corner of the file listing
9458"   call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9459   exe 'sil! '.w:netrw_bannercnt
9460   sil! NetrwKeepj norm! 0
9461"   call Decho("  tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9462  else
9463"   call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9464"   call Decho("  w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9465"   call Decho("  line($)=".line("$"),'~'.expand("<slnum>"))
9466"   call Decho("  g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
9467  endif
9468
9469  " record previous current directory
9470  let w:netrw_prvdir= b:netrw_curdir
9471"  call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
9472
9473  " save certain window-oriented variables into buffer-oriented variables {{{3
9474"  call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9475"  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>"))
9476  NetrwKeepj call s:SetBufWinVars()
9477"  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>"))
9478  NetrwKeepj call s:NetrwOptionRestore("w:")
9479"  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>"))
9480
9481  " set display to netrw display settings
9482"  call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
9483  exe "setl ".g:netrw_bufsettings
9484"  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>"))
9485  if g:netrw_liststyle == s:LONGLIST
9486"   call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9487   exe "setl ts=".(g:netrw_maxfilenamelen+1)
9488  endif
9489
9490  if exists("s:treecurpos")
9491"   call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
9492"   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>"))
9493"   call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9494   NetrwKeepj call winrestview(s:treecurpos)
9495   unlet s:treecurpos
9496  endif
9497
9498"  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>"))
9499"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9500"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
9501endfun
9502
9503" ---------------------------------------------------------------------
9504" s:SetupNetrwStatusLine: {{{2
9505fun! s:SetupNetrwStatusLine(statline)
9506"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
9507
9508  if !exists("s:netrw_setup_statline")
9509   let s:netrw_setup_statline= 1
9510"   call Decho("do first-time status line setup",'~'.expand("<slnum>"))
9511
9512   if !exists("s:netrw_users_stl")
9513    let s:netrw_users_stl= &stl
9514   endif
9515   if !exists("s:netrw_users_ls")
9516    let s:netrw_users_ls= &laststatus
9517   endif
9518
9519   " set up User9 highlighting as needed
9520   let keepa= @a
9521   redir @a
9522   try
9523    hi User9
9524   catch /^Vim\%((\a\{3,})\)\=:E411/
9525    if &bg == "dark"
9526     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
9527    else
9528     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
9529    endif
9530   endtry
9531   redir END
9532   let @a= keepa
9533  endif
9534
9535  " set up status line (may use User9 highlighting)
9536  " insure that windows have a statusline
9537  " make sure statusline is displayed
9538  let &stl=a:statline
9539  setl laststatus=2
9540"  call Decho("stl=".&stl,'~'.expand("<slnum>"))
9541  redraw
9542
9543"  call Dret("SetupNetrwStatusLine : stl=".&stl)
9544endfun
9545
9546" ---------------------------------------------------------------------
9547"  Remote Directory Browsing Support:    {{{1
9548" ===========================================
9549
9550" ---------------------------------------------------------------------
9551" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
9552"  This function assumes that a long listing will be received.  Size, time,
9553"  and reverse sorts will be requested of the server but not otherwise
9554"  enforced here.
9555fun! s:NetrwRemoteFtpCmd(path,listcmd)
9556"  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 : "???")))
9557"  call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9558  " sanity check: {{{3
9559  if !exists("w:netrw_method")
9560   if exists("b:netrw_method")
9561    let w:netrw_method= b:netrw_method
9562   else
9563    call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
9564"    call Dret("NetrwRemoteFtpCmd")
9565    return
9566   endif
9567  endif
9568
9569  " WinXX ftp uses unix style input, so set ff to unix	" {{{3
9570  let ffkeep= &ff
9571  setl ma ff=unix noro
9572"  call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
9573
9574  " clear off any older non-banner lines	" {{{3
9575  " note that w:netrw_bannercnt indexes the line after the banner
9576"  call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _  (clear off old non-banner lines)",'~'.expand("<slnum>"))
9577  exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
9578
9579  ".........................................
9580  if w:netrw_method == 2 || w:netrw_method == 5	" {{{3
9581   " ftp + <.netrc>:  Method #2
9582   if a:path != ""
9583    NetrwKeepj put ='cd \"'.a:path.'\"'
9584   endif
9585   if exists("g:netrw_ftpextracmd")
9586    NetrwKeepj put =g:netrw_ftpextracmd
9587"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9588   endif
9589   NetrwKeepj call setline(line("$")+1,a:listcmd)
9590"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9591   if exists("g:netrw_port") && g:netrw_port != ""
9592"    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>"))
9593    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)
9594   else
9595"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
9596    exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
9597   endif
9598
9599  ".........................................
9600  elseif w:netrw_method == 3	" {{{3
9601   " ftp + machine,id,passwd,filename:  Method #3
9602    setl ff=unix
9603    if exists("g:netrw_port") && g:netrw_port != ""
9604     NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
9605    else
9606     NetrwKeepj put ='open '.g:netrw_machine
9607    endif
9608
9609    " handle userid and password
9610    let host= substitute(g:netrw_machine,'\..*$','','')
9611"    call Decho("host<".host.">",'~'.expand("<slnum>"))
9612    if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
9613     call NetUserPass("ftp:".host)
9614    endif
9615    if exists("g:netrw_uid") && g:netrw_uid != ""
9616     if exists("g:netrw_ftp") && g:netrw_ftp == 1
9617      NetrwKeepj put =g:netrw_uid
9618      if exists("s:netrw_passwd") && s:netrw_passwd != ""
9619       NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
9620      endif
9621     elseif exists("s:netrw_passwd")
9622      NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
9623     endif
9624    endif
9625
9626   if a:path != ""
9627    NetrwKeepj put ='cd \"'.a:path.'\"'
9628   endif
9629   if exists("g:netrw_ftpextracmd")
9630    NetrwKeepj put =g:netrw_ftpextracmd
9631"    call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9632   endif
9633   NetrwKeepj call setline(line("$")+1,a:listcmd)
9634
9635   " perform ftp:
9636   " -i       : turns off interactive prompting from ftp
9637   " -n  unix : DON'T use <.netrc>, even though it exists
9638   " -n  win32: quit being obnoxious about password
9639   if exists("w:netrw_bannercnt")
9640"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9641    call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
9642"   else " Decho
9643"    call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
9644"    g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
9645   endif
9646
9647  ".........................................
9648  elseif w:netrw_method == 9	" {{{3
9649   " sftp username@machine: Method #9
9650   " s:netrw_sftp_cmd
9651   setl ff=unix
9652
9653   " restore settings
9654   let &ff= ffkeep
9655"   call Dret("NetrwRemoteFtpCmd")
9656   return
9657
9658  ".........................................
9659  else	" {{{3
9660   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
9661  endif
9662
9663  " cleanup for Windows " {{{3
9664  if has("win32") || has("win95") || has("win64") || has("win16")
9665   sil! NetrwKeepj %s/\r$//e
9666   NetrwKeepj call histdel("/",-1)
9667  endif
9668  if a:listcmd == "dir"
9669   " infer directory/link based on the file permission string
9670   sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
9671   sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
9672   NetrwKeepj call histdel("/",-1)
9673   NetrwKeepj call histdel("/",-1)
9674   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9675    exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
9676    NetrwKeepj call histdel("/",-1)
9677   endif
9678  endif
9679
9680  " ftp's listing doesn't seem to include ./ or ../ " {{{3
9681  if !search('^\.\/$\|\s\.\/$','wn')
9682   exe 'NetrwKeepj '.w:netrw_bannercnt
9683   NetrwKeepj put ='./'
9684  endif
9685  if !search('^\.\.\/$\|\s\.\.\/$','wn')
9686   exe 'NetrwKeepj '.w:netrw_bannercnt
9687   NetrwKeepj put ='../'
9688  endif
9689
9690  " restore settings " {{{3
9691  let &ff= ffkeep
9692"  call Dret("NetrwRemoteFtpCmd")
9693endfun
9694
9695" ---------------------------------------------------------------------
9696" s:NetrwRemoteListing: {{{2
9697fun! s:NetrwRemoteListing()
9698"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
9699
9700  if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
9701   let w:netrw_bannercnt= s:bannercnt
9702  endif
9703  if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
9704   let w:netrw_bannercnt= s:bannercnt
9705  endif
9706
9707  call s:RemotePathAnalysis(b:netrw_curdir)
9708
9709  " sanity check:
9710  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
9711"   call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
9712   if !executable("ftp")
9713"    call Decho("ftp is not executable",'~'.expand("<slnum>"))
9714    if !exists("g:netrw_quiet")
9715     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
9716    endif
9717    call s:NetrwOptionRestore("w:")
9718"    call Dret("s:NetrwRemoteListing -1")
9719    return -1
9720   endif
9721
9722  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
9723"   call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
9724   if !exists("g:netrw_quiet")
9725    if g:netrw_list_cmd == ""
9726     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)
9727    else
9728     NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
9729    endif
9730   endif
9731
9732   NetrwKeepj call s:NetrwOptionRestore("w:")
9733"   call Dret("s:NetrwRemoteListing -1")
9734   return -1
9735  endif  " (remote handling sanity check)
9736"  call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
9737
9738  if exists("b:netrw_method")
9739"   call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
9740   let w:netrw_method= b:netrw_method
9741  endif
9742
9743  if s:method == "ftp"
9744   " use ftp to get remote file listing {{{3
9745"   call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
9746   let s:method  = "ftp"
9747   let listcmd = g:netrw_ftp_list_cmd
9748   if g:netrw_sort_by =~# '^t'
9749    let listcmd= g:netrw_ftp_timelist_cmd
9750   elseif g:netrw_sort_by =~# '^s'
9751    let listcmd= g:netrw_ftp_sizelist_cmd
9752   endif
9753"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
9754   call s:NetrwRemoteFtpCmd(s:path,listcmd)
9755"   exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
9756
9757   " report on missing file or directory messages
9758   if search('[Nn]o such file or directory\|Failed to change directory')
9759    let mesg= getline(".")
9760    if exists("w:netrw_bannercnt")
9761     setl ma
9762     exe w:netrw_bannercnt.",$d _"
9763     setl noma
9764    endif
9765    NetrwKeepj call s:NetrwOptionRestore("w:")
9766    call netrw#ErrorMsg(s:WARNING,mesg,96)
9767"    call Dret("s:NetrwRemoteListing : -1")
9768    return -1
9769   endif
9770
9771   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9772    " shorten the listing
9773"    call Decho("generate short listing",'~'.expand("<slnum>"))
9774    exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
9775
9776    " cleanup
9777    if g:netrw_ftp_browse_reject != ""
9778     exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
9779     NetrwKeepj call histdel("/",-1)
9780    endif
9781    sil! NetrwKeepj %s/\r$//e
9782    NetrwKeepj call histdel("/",-1)
9783
9784    " if there's no ../ listed, then put ../ in
9785    let line1= line(".")
9786    exe "sil! NetrwKeepj ".w:netrw_bannercnt
9787    let line2= search('\.\.\/\%(\s\|$\)','cnW')
9788"    call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2."  w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9789    if line2 == 0
9790"     call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
9791     sil! NetrwKeepj put='../'
9792    endif
9793    exe "sil! NetrwKeepj ".line1
9794    sil! NetrwKeepj norm! 0
9795
9796"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
9797    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9798"     call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
9799     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
9800     NetrwKeepj call histdel("/",-1)
9801    else " normal ftp cleanup
9802"     call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
9803     exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
9804     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
9805     exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
9806     NetrwKeepj call histdel("/",-1)
9807     NetrwKeepj call histdel("/",-1)
9808     NetrwKeepj call histdel("/",-1)
9809    endif
9810   endif
9811
9812   else
9813   " use ssh to get remote file listing {{{3
9814"   call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
9815   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
9816"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
9817   if g:netrw_scp_cmd =~ '^pscp'
9818"    call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
9819    exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
9820    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
9821    sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
9822    sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
9823    sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
9824    NetrwKeepj call histdel("/",-1)
9825    NetrwKeepj call histdel("/",-1)
9826    NetrwKeepj call histdel("/",-1)
9827    if g:netrw_liststyle != s:LONGLIST
9828     sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
9829     NetrwKeepj call histdel("/",-1)
9830    endif
9831   else
9832    if s:path == ""
9833"     call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
9834     exe "NetrwKeepj keepalt r! ".listcmd
9835    else
9836"     call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
9837     exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
9838"     call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
9839    endif
9840   endif
9841
9842   " cleanup
9843   if g:netrw_ssh_browse_reject != ""
9844"    call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
9845    exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
9846    NetrwKeepj call histdel("/",-1)
9847   endif
9848  endif
9849
9850  if w:netrw_liststyle == s:LONGLIST
9851   " do a long listing; these substitutions need to be done prior to sorting {{{3
9852"   call Decho("fix long listing:",'~'.expand("<slnum>"))
9853
9854   if s:method == "ftp"
9855    " cleanup
9856    exe "sil! NetrwKeepj ".w:netrw_bannercnt
9857    while getline('.') =~# g:netrw_ftp_browse_reject
9858     sil! NetrwKeepj d
9859    endwhile
9860    " if there's no ../ listed, then put ../ in
9861    let line1= line(".")
9862    sil! NetrwKeepj 1
9863    sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
9864    let line2= line(".")
9865    if line2 == 0
9866     if b:netrw_curdir != '/'
9867      exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
9868     endif
9869    endif
9870    exe "sil! NetrwKeepj ".line1
9871    sil! NetrwKeepj norm! 0
9872   endif
9873
9874   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9875"    call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
9876    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/'
9877   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
9878"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9879    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
9880    exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
9881    exe 'sil NetrwKeepj '.w:netrw_bannercnt
9882    NetrwKeepj call histdel("/",-1)
9883    NetrwKeepj call histdel("/",-1)
9884    NetrwKeepj call histdel("/",-1)
9885   endif
9886  endif
9887
9888"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
9889"   exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
9890"  endif " Decho
9891
9892"  call Dret("s:NetrwRemoteListing 0")
9893  return 0
9894endfun
9895
9896" ---------------------------------------------------------------------
9897" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
9898fun! s:NetrwRemoteRm(usrhost,path) range
9899"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
9900"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
9901  let svpos= winsaveview()
9902"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9903
9904  let all= 0
9905  if exists("s:netrwmarkfilelist_{bufnr('%')}")
9906   " remove all marked files
9907"   call Decho("remove all marked files with bufnr#".bufnr("%"),'~'.expand("<slnum>"))
9908   for fname in s:netrwmarkfilelist_{bufnr("%")}
9909    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
9910    if ok =~# 'q\%[uit]'
9911     break
9912    elseif ok =~# 'a\%[ll]'
9913     let all= 1
9914    endif
9915   endfor
9916   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
9917
9918  else
9919   " remove files specified by range
9920"   call Decho("remove files specified by range",'~'.expand("<slnum>"))
9921
9922   " preparation for removing multiple files/directories
9923   let keepsol = &l:sol
9924   setl nosol
9925   let ctr    = a:firstline
9926
9927   " remove multiple files and directories
9928   while ctr <= a:lastline
9929    exe "NetrwKeepj ".ctr
9930    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
9931    if ok =~# 'q\%[uit]'
9932     break
9933    elseif ok =~# 'a\%[ll]'
9934     let all= 1
9935    endif
9936    let ctr= ctr + 1
9937   endwhile
9938   let &l:sol = keepsol
9939  endif
9940
9941  " refresh the (remote) directory listing
9942"  call Decho("refresh remote directory listing",'~'.expand("<slnum>"))
9943  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
9944"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
9945  NetrwKeepj call winrestview(svpos)
9946
9947"  call Dret("s:NetrwRemoteRm")
9948endfun
9949
9950" ---------------------------------------------------------------------
9951" s:NetrwRemoteRmFile: {{{2
9952fun! s:NetrwRemoteRmFile(path,rmfile,all)
9953"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
9954
9955  let all= a:all
9956  let ok = ""
9957
9958  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
9959   " attempt to remove file
9960"    call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
9961   if !all
9962    echohl Statement
9963"    call Decho("case all=0:",'~'.expand("<slnum>"))
9964    call inputsave()
9965    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
9966    call inputrestore()
9967    echohl NONE
9968    if ok == ""
9969     let ok="no"
9970    endif
9971    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
9972    if ok =~# 'a\%[ll]'
9973     let all= 1
9974    endif
9975   endif
9976
9977   if all || ok =~# 'y\%[es]' || ok == ""
9978"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
9979    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9980"     call Decho("case ftp:",'~'.expand("<slnum>"))
9981     let path= a:path
9982     if path =~ '^\a\{3,}://'
9983      let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
9984     endif
9985     sil! NetrwKeepj .,$d _
9986     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
9987    else
9988"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
9989     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
9990"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
9991     if !exists("b:netrw_curdir")
9992      NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
9993      let ok="q"
9994     else
9995      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
9996"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
9997"      call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
9998"      call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
9999      if remotedir != ""
10000       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
10001      else
10002       let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
10003      endif
10004"      call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
10005      let ret= system(netrw_rm_cmd)
10006      if v:shell_error != 0
10007       if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
10008        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)
10009       else
10010        call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10011       endif
10012      elseif ret != 0
10013       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
10014      endif
10015"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10016     endif
10017    endif
10018   elseif ok =~# 'q\%[uit]'
10019"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10020   endif
10021
10022  else
10023   " attempt to remove directory
10024"    call Decho("attempt to remove directory",'~'.expand("<slnum>"))
10025   if !all
10026    call inputsave()
10027    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10028    call inputrestore()
10029    if ok == ""
10030     let ok="no"
10031    endif
10032    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10033    if ok =~# 'a\%[ll]'
10034     let all= 1
10035    endif
10036   endif
10037
10038   if all || ok =~# 'y\%[es]' || ok == ""
10039    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10040     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
10041    else
10042     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
10043     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
10044"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
10045     let ret= system(netrw_rmdir_cmd)
10046"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10047
10048     if v:shell_error != 0
10049"      call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
10050      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
10051"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
10052      let ret= system(netrw_rmf_cmd)
10053"      call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
10054
10055      if v:shell_error != 0 && !exists("g:netrw_quiet")
10056      	NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
10057      endif
10058     endif
10059    endif
10060
10061   elseif ok =~# 'q\%[uit]'
10062"    call Decho("ok==".ok,'~'.expand("<slnum>"))
10063   endif
10064  endif
10065
10066"  call Dret("s:NetrwRemoteRmFile ".ok)
10067  return ok
10068endfun
10069
10070" ---------------------------------------------------------------------
10071" s:NetrwRemoteRename: rename a remote file or directory {{{2
10072fun! s:NetrwRemoteRename(usrhost,path) range
10073"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
10074
10075  " preparation for removing multiple files/directories
10076  let svpos      = winsaveview()
10077"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10078  let ctr        = a:firstline
10079  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10080
10081  " rename files given by the markfilelist
10082  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10083   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10084"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10085    if exists("subfrom")
10086     let newname= substitute(oldname,subfrom,subto,'')
10087"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10088    else
10089     call inputsave()
10090     let newname= input("Moving ".oldname." to : ",oldname)
10091     call inputrestore()
10092     if newname =~ '^s/'
10093      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10094      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10095      let newname = substitute(oldname,subfrom,subto,'')
10096"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10097     endif
10098    endif
10099
10100    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10101     NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10102    else
10103     let oldname= s:ShellEscape(a:path.oldname)
10104     let newname= s:ShellEscape(a:path.newname)
10105"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10106     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10107    endif
10108
10109   endfor
10110   call s:NetrwUnMarkFile(1)
10111
10112  else
10113
10114  " attempt to rename files/directories
10115   let keepsol= &l:sol
10116   setl nosol
10117   while ctr <= a:lastline
10118    exe "NetrwKeepj ".ctr
10119
10120    let oldname= s:NetrwGetWord()
10121"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10122
10123    call inputsave()
10124    let newname= input("Moving ".oldname." to : ",oldname)
10125    call inputrestore()
10126
10127    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10128     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10129    else
10130     let oldname= s:ShellEscape(a:path.oldname)
10131     let newname= s:ShellEscape(a:path.newname)
10132"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")",'~'.expand("<slnum>"))
10133     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10134    endif
10135
10136    let ctr= ctr + 1
10137   endwhile
10138   let &l:sol= keepsol
10139  endif
10140
10141  " refresh the directory
10142  NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
10143"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10144  NetrwKeepj call winrestview(svpos)
10145
10146"  call Dret("NetrwRemoteRename")
10147endfun
10148
10149" ---------------------------------------------------------------------
10150"  Local Directory Browsing Support:    {{{1
10151" ==========================================
10152
10153" ---------------------------------------------------------------------
10154" netrw#FileUrlRead: handles reading file://* files {{{2
10155"   Should accept:   file://localhost/etc/fstab
10156"                    file:///etc/fstab
10157"                    file:///c:/WINDOWS/clock.avi
10158"                    file:///c|/WINDOWS/clock.avi
10159"                    file://localhost/c:/WINDOWS/clock.avi
10160"                    file://localhost/c|/WINDOWS/clock.avi
10161"                    file://c:/foo.txt
10162"                    file:///c:/foo.txt
10163" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
10164fun! netrw#FileUrlRead(fname)
10165"  call Dfunc("netrw#FileUrlRead(fname<".a:fname.">)")
10166  let fname = a:fname
10167  if fname =~ '^file://localhost/'
10168"   call Decho('converting file://localhost/   -to-  file:///','~'.expand("<slnum>"))
10169   let fname= substitute(fname,'^file://localhost/','file:///','')
10170"   call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10171  endif
10172  if (has("win32") || has("win95") || has("win64") || has("win16"))
10173   if fname  =~ '^file:///\=\a[|:]/'
10174"    call Decho('converting file:///\a|/   -to-  file://\a:/','~'.expand("<slnum>"))
10175    let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10176"    call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10177   endif
10178  endif
10179  let fname2396 = netrw#RFC2396(fname)
10180  let fname2396e= fnameescape(fname2396)
10181  let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
10182  if (has("win32") || has("win95") || has("win64") || has("win16"))
10183"   call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10184   if plainfname =~ '^/\+\a:'
10185"    call Decho('removing leading "/"s','~'.expand("<slnum>"))
10186    let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10187   endif
10188  endif
10189"  call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10190"  call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
10191  exe "sil doau BufReadPre ".fname2396e
10192  exe 'NetrwKeepj r '.plainfname
10193  exe 'sil! bdelete '.plainfname
10194  exe 'keepalt file! '.plainfname
10195  NetrwKeepj 1d
10196"  call Decho("setl nomod",'~'.expand("<slnum>"))
10197  setl nomod
10198"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10199"  call Dret("netrw#FileUrlRead")
10200  exe "sil doau BufReadPost ".fname2396e
10201endfun
10202
10203" ---------------------------------------------------------------------
10204" netrw#LocalBrowseCheck: {{{2
10205fun! netrw#LocalBrowseCheck(dirname)
10206  " This function is called by netrwPlugin.vim's s:LocalBrowse(), s:NetrwRexplore(), and by <cr> when atop listed file/directory
10207  " unfortunate interaction -- split window debugging can't be
10208  " used here, must use D-echoRemOn or D-echoTabOn -- the BufEnter
10209  " event triggers another call to LocalBrowseCheck() when attempts
10210  " to write to the DBG buffer are made.
10211  " The &ft == "netrw" test was installed because the BufEnter event
10212  " would hit when re-entering netrw windows, creating unexpected
10213  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
10214"  call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">")
10215"  call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>"))
10216"  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>"))
10217"  call Dredir("ls!","ls!")
10218"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10219"  call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
10220
10221  let ykeep= @@
10222  if isdirectory(s:NetrwFile(a:dirname))
10223"   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>"))
10224
10225   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10226"    call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10227"    call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10228    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10229
10230   elseif &ft == "netrw" && line("$") == 1
10231"    call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10232    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10233
10234   elseif exists("s:treeforceredraw")
10235"    call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10236    unlet s:treeforceredraw
10237    sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10238   endif
10239"   call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10240"   call Dret("netrw#LocalBrowseCheck")
10241   return
10242  endif
10243
10244  " following code wipes out currently unused netrw buffers
10245  "       IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10246  "   AND IF the listing style is not a tree listing
10247  if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
10248"   call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10249   let ibuf    = 1
10250   let buflast = bufnr("$")
10251   while ibuf <= buflast
10252    if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10253     exe "sil! keepj keepalt ".ibuf."bw!"
10254    endif
10255    let ibuf= ibuf + 1
10256   endwhile
10257  endif
10258  let @@= ykeep
10259"  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>"))
10260"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10261  " not a directory, ignore it
10262"  call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
10263endfun
10264
10265" ---------------------------------------------------------------------
10266" s:LocalBrowseRefresh: this function is called after a user has {{{2
10267" performed any shell command.  The idea is to cause all local-browsing
10268" buffers to be refreshed after a user has executed some shell command,
10269" on the chance that s/he removed/created a file/directory with it.
10270fun! s:LocalBrowseRefresh()
10271"  call Dfunc("s:LocalBrowseRefresh() tabpagenr($)=".tabpagenr("$"))
10272"  call Decho("s:netrw_browselist =".(exists("s:netrw_browselist")?  string(s:netrw_browselist)  : '<n/a>'),'~'.expand("<slnum>"))
10273"  call Decho("w:netrw_bannercnt  =".(exists("w:netrw_bannercnt")?   string(w:netrw_bannercnt)   : '<n/a>'),'~'.expand("<slnum>"))
10274
10275  " determine which buffers currently reside in a tab
10276  if !exists("s:netrw_browselist")
10277"   call Dret("s:LocalBrowseRefresh : browselist is empty")
10278   return
10279  endif
10280  if !exists("w:netrw_bannercnt")
10281"   call Dret("s:LocalBrowseRefresh : don't refresh when focus not on netrw window")
10282   return
10283  endif
10284  if exists("s:netrw_events") && s:netrw_events == 1
10285   " s:LocalFastBrowser gets called (indirectly) from a
10286   let s:netrw_events= 2
10287"   call Dret("s:LocalBrowseRefresh : avoid initial double refresh")
10288   return
10289  endif
10290  let itab       = 1
10291  let buftablist = []
10292  let ykeep      = @@
10293  while itab <= tabpagenr("$")
10294   let buftablist = buftablist + tabpagebuflist()
10295   let itab       = itab + 1
10296   tabn
10297  endwhile
10298"  call Decho("buftablist".string(buftablist),'~'.expand("<slnum>"))
10299"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">",'~'.expand("<slnum>"))
10300  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10301  "   | refresh any netrw window
10302  "   | wipe out any non-displaying netrw buffer
10303  let curwin = winnr()
10304  let ibl    = 0
10305  for ibuf in s:netrw_browselist
10306"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf),'~'.expand("<slnum>"))
10307   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10308    " wipe out any non-displaying netrw buffer
10309"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">",'~'.expand("<slnum>"))
10310    exe "sil! keepj bd ".fnameescape(ibuf)
10311    call remove(s:netrw_browselist,ibl)
10312"    call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10313    continue
10314   elseif index(tabpagebuflist(),ibuf) != -1
10315    " refresh any netrw buffer
10316"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf),'~'.expand("<slnum>"))
10317    exe bufwinnr(ibuf)."wincmd w"
10318    if getline(".") =~# 'Quick Help'
10319     " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10320     " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10321     let g:netrw_quickhelp= g:netrw_quickhelp - 1
10322    endif
10323"    call Decho("#3: quickhelp=".g:netrw_quickhelp,'~'.expand("<slnum>"))
10324    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10325     NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10326    endif
10327    NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10328   endif
10329   let ibl= ibl + 1
10330"   call Decho("bottom of s:netrw_browselist for loop: ibl=".ibl,'~'.expand("<slnum>"))
10331  endfor
10332"  call Decho("restore window: exe ".curwin."wincmd w",'~'.expand("<slnum>"))
10333  exe curwin."wincmd w"
10334  let @@= ykeep
10335
10336"  call Dret("s:LocalBrowseRefresh")
10337endfun
10338
10339" ---------------------------------------------------------------------
10340" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10341"
10342"     g:netrw_    Directory Is
10343"     fastbrowse  Local  Remote
10344"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
10345"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
10346"  fast   2         H      H
10347"
10348"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10349"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
10350"                       (re-using a buffer may not be as accurate)
10351"
10352"  s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds whena med or fast browsing
10353"                   =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10354"                       BufEnter may be first event, then a FocusGained event.  Ignore the first FocusGained event.
10355"                       If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10356"                   =2: autocmds installed (doesn't ignore any FocusGained events)
10357fun! s:LocalFastBrowser()
10358"  call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
10359"  call Decho("s:netrw_events        ".(exists("s:netrw_events")? "exists"    : 'n/a'),'~'.expand("<slnum>"))
10360"  call Decho("autocmd: ShellCmdPost ".(exists("#ShellCmdPost")?  "installed" : "not installed"),'~'.expand("<slnum>"))
10361"  call Decho("autocmd: FocusGained  ".(exists("#FocusGained")?   "installed" : "not installed"),'~'.expand("<slnum>"))
10362
10363  " initialize browselist, a list of buffer numbers that the local browser has used
10364  if !exists("s:netrw_browselist")
10365"   call Decho("initialize s:netrw_browselist",'~'.expand("<slnum>"))
10366   let s:netrw_browselist= []
10367  endif
10368
10369  " append current buffer to fastbrowse list
10370  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
10371"   call Decho("appendng current buffer to browselist",'~'.expand("<slnum>"))
10372   call add(s:netrw_browselist,bufnr("%"))
10373"   call Decho("browselist=".string(s:netrw_browselist),'~'.expand("<slnum>"))
10374  endif
10375
10376  " enable autocmd events to handle refreshing/removing local browser buffers
10377  "    If local browse buffer is currently showing: refresh it
10378  "    If local browse buffer is currently hidden : wipe it
10379  "    g:netrw_fastbrowse=0 : slow   speed, never re-use directory listing
10380  "                      =1 : medium speed, re-use directory listing for remote only
10381  "                      =2 : fast   speed, always re-use directory listing when possible
10382  if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
10383   let s:netrw_events= 1
10384   augroup AuNetrwEvent
10385    au!
10386    if (has("win32") || has("win95") || has("win64") || has("win16"))
10387"     call Decho("installing autocmd: ShellCmdPost",'~'.expand("<slnum>"))
10388     au ShellCmdPost			*	call s:LocalBrowseRefresh()
10389    else
10390"     call Decho("installing autocmds: ShellCmdPost FocusGained",'~'.expand("<slnum>"))
10391     au ShellCmdPost,FocusGained	*	call s:LocalBrowseRefresh()
10392    endif
10393   augroup END
10394
10395  " user must have changed fastbrowse to its fast setting, so remove
10396  " the associated autocmd events
10397  elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
10398"   call Decho("remove AuNetrwEvent autcmd group",'~'.expand("<slnum>"))
10399   unlet s:netrw_events
10400   augroup AuNetrwEvent
10401    au!
10402   augroup END
10403   augroup! AuNetrwEvent
10404  endif
10405
10406"  call Dret("LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
10407endfun
10408
10409" ---------------------------------------------------------------------
10410"  s:LocalListing: does the job of "ls" for local directories {{{2
10411fun! s:LocalListing()
10412"  call Dfunc("s:LocalListing()")
10413"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10414"  call Decho("modified=".&modified." modifiable=".&modifiable." readonly=".&readonly,'~'.expand("<slnum>"))
10415"  call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10416
10417"  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
10418"  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
10419"  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>"))
10420
10421  " get the list of files contained in the current directory
10422  let dirname    = b:netrw_curdir
10423  let dirnamelen = strlen(b:netrw_curdir)
10424  let filelist   = s:NetrwGlob(dirname,"*",0)
10425  let filelist   = filelist + s:NetrwGlob(dirname,".*",0)
10426"  call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10427
10428  if g:netrw_cygwin == 0 && (has("win32") || has("win95") || has("win64") || has("win16"))
10429"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10430  elseif index(filelist,'..') == -1 && b:netrw_curdir !~ '/'
10431    " include ../ in the glob() entry if its missing
10432"   call Decho("forcibly including on \"..\"",'~'.expand("<slnum>"))
10433   let filelist= filelist+[s:ComposePath(b:netrw_curdir,"../")]
10434"   call Decho("filelist=".string(filelist),'~'.expand("<slnum>"))
10435  endif
10436
10437"  call Decho("before while: dirname   <".dirname.">",'~'.expand("<slnum>"))
10438"  call Decho("before while: dirnamelen<".dirnamelen.">",'~'.expand("<slnum>"))
10439"  call Decho("before while: filelist  =".string(filelist),'~'.expand("<slnum>"))
10440
10441  if get(g:, 'netrw_dynamic_maxfilenamelen', 0)
10442   let filelistcopy           = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10443   let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
10444"   call Decho("dynamic_maxfilenamelen: filenames             =".string(filelistcopy),'~'.expand("<slnum>"))
10445"   call Decho("dynamic_maxfilenamelen: g:netrw_maxfilenamelen=".g:netrw_maxfilenamelen,'~'.expand("<slnum>"))
10446  endif
10447"  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>"))
10448
10449  for filename in filelist
10450"   call Decho(" ",'~'.expand("<slnum>"))
10451"   call Decho("for filename in filelist: filename<".filename.">",'~'.expand("<slnum>"))
10452
10453   if getftype(filename) == "link"
10454    " indicate a symbolic link
10455"    call Decho("indicate <".filename."> is a symbolic link with trailing @",'~'.expand("<slnum>"))
10456    let pfile= filename."@"
10457
10458   elseif getftype(filename) == "socket"
10459    " indicate a socket
10460"    call Decho("indicate <".filename."> is a socket with trailing =",'~'.expand("<slnum>"))
10461    let pfile= filename."="
10462
10463   elseif getftype(filename) == "fifo"
10464    " indicate a fifo
10465"    call Decho("indicate <".filename."> is a fifo with trailing |",'~'.expand("<slnum>"))
10466    let pfile= filename."|"
10467
10468   elseif isdirectory(s:NetrwFile(filename))
10469    " indicate a directory
10470"    call Decho("indicate <".filename."> is a directory with trailing /",'~'.expand("<slnum>"))
10471    let pfile= filename."/"
10472
10473   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10474    if (has("win32") || has("win95") || has("win64") || has("win16"))
10475     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10476      " indicate an executable
10477"      call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10478      let pfile= filename."*"
10479     else
10480      " normal file
10481      let pfile= filename
10482     endif
10483    elseif executable(filename)
10484     " indicate an executable
10485"     call Decho("indicate <".filename."> is executable with trailing *",'~'.expand("<slnum>"))
10486     let pfile= filename."*"
10487    else
10488     " normal file
10489     let pfile= filename
10490    endif
10491
10492   else
10493    " normal file
10494    let pfile= filename
10495   endif
10496"   call Decho("pfile<".pfile."> (after *@/ appending)",'~'.expand("<slnum>"))
10497
10498   if pfile =~ '//$'
10499    let pfile= substitute(pfile,'//$','/','e')
10500"    call Decho("change // to /: pfile<".pfile.">",'~'.expand("<slnum>"))
10501   endif
10502   let pfile= strpart(pfile,dirnamelen)
10503   let pfile= substitute(pfile,'^[/\\]','','e')
10504"   call Decho("filename<".filename.">",'~'.expand("<slnum>"))
10505"   call Decho("pfile   <".pfile.">",'~'.expand("<slnum>"))
10506
10507   if w:netrw_liststyle == s:LONGLIST
10508    let sz   = getfsize(filename)
10509    if g:netrw_sizestyle =~# "[hH]"
10510     let sz= s:NetrwHumanReadable(sz)
10511    endif
10512    let fsz  = strpart("               ",1,15-strlen(sz)).sz
10513    let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
10514"    call Decho("longlist support: sz=".sz." fsz=".fsz,'~'.expand("<slnum>"))
10515   endif
10516
10517   if     g:netrw_sort_by =~# "^t"
10518    " sort by time (handles time up to 1 quintillion seconds, US)
10519"    call Decho("getftime(".filename.")=".getftime(filename),'~'.expand("<slnum>"))
10520    let t  = getftime(filename)
10521    let ft = strpart("000000000000000000",1,18-strlen(t)).t
10522"    call Decho("exe NetrwKeepj put ='".ft.'/'.filename."'",'~'.expand("<slnum>"))
10523    let ftpfile= ft.'/'.pfile
10524    sil! NetrwKeepj put=ftpfile
10525
10526   elseif g:netrw_sort_by =~ "^s"
10527    " sort by size (handles file sizes up to 1 quintillion bytes, US)
10528"    call Decho("getfsize(".filename.")=".getfsize(filename),'~'.expand("<slnum>"))
10529    let sz   = getfsize(filename)
10530    if g:netrw_sizestyle =~# "[hH]"
10531     let sz= s:NetrwHumanReadable(sz)
10532    endif
10533    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
10534"    call Decho("exe NetrwKeepj put ='".fsz.'/'.filename."'",'~'.expand("<slnum>"))
10535    let fszpfile= fsz.'/'.pfile
10536    sil! NetrwKeepj put =fszpfile
10537
10538   else
10539    " sort by name
10540"    call Decho("exe NetrwKeepj put ='".pfile."'",'~'.expand("<slnum>"))
10541    sil! NetrwKeepj put=pfile
10542   endif
10543  endfor
10544
10545  " cleanup any windows mess at end-of-line
10546  sil! NetrwKeepj g/^$/d
10547  sil! NetrwKeepj %s/\r$//e
10548  call histdel("/",-1)
10549"  call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
10550  exe "setl ts=".(g:netrw_maxfilenamelen+1)
10551
10552"  call Dret("s:LocalListing")
10553endfun
10554
10555" ---------------------------------------------------------------------
10556" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
10557fun! s:NetrwLocalExecute(cmd)
10558"  call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
10559  let ykeep= @@
10560  " sanity check
10561  if !executable(a:cmd)
10562   call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
10563   let @@= ykeep
10564"   call Dret("s:NetrwLocalExecute")
10565   return
10566  endif
10567
10568  let optargs= input(":!".a:cmd,"","file")
10569"  call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
10570  let result= system(a:cmd.optargs)
10571"  call Decho("result,'~'.expand("<slnum>"))
10572
10573  " strip any ansi escape sequences off
10574  let result = substitute(result,"\e\\[[0-9;]*m","","g")
10575
10576  " show user the result(s)
10577  echomsg result
10578  let @@= ykeep
10579
10580"  call Dret("s:NetrwLocalExecute")
10581endfun
10582
10583" ---------------------------------------------------------------------
10584" s:NetrwLocalRename: rename a local file or directory {{{2
10585fun! s:NetrwLocalRename(path) range
10586"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
10587
10588  " preparation for removing multiple files/directories
10589  let ykeep    = @@
10590  let ctr      = a:firstline
10591  let svpos    = winsaveview()
10592"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10593
10594  " rename files given by the markfilelist
10595  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10596   for oldname in s:netrwmarkfilelist_{bufnr("%")}
10597"    call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10598    if exists("subfrom")
10599     let newname= substitute(oldname,subfrom,subto,'')
10600"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10601    else
10602     call inputsave()
10603     let newname= input("Moving ".oldname." to : ",oldname,"file")
10604     call inputrestore()
10605     if newname =~ ''
10606      " two ctrl-x's : ignore all of string preceding the ctrl-x's
10607      let newname = substitute(newname,'^.*','','')
10608     elseif newname =~ ''
10609      " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
10610      let newname = substitute(newname,'[^/]*','','')
10611     endif
10612     if newname =~ '^s/'
10613      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10614      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10615"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">",'~'.expand("<slnum>"))
10616      let newname = substitute(oldname,subfrom,subto,'')
10617     endif
10618    endif
10619    call rename(oldname,newname)
10620   endfor
10621   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
10622
10623  else
10624
10625   " attempt to rename files/directories
10626   while ctr <= a:lastline
10627    exe "NetrwKeepj ".ctr
10628
10629    " sanity checks
10630    if line(".") < w:netrw_bannercnt
10631     let ctr= ctr + 1
10632     continue
10633    endif
10634    let curword= s:NetrwGetWord()
10635    if curword == "./" || curword == "../"
10636     let ctr= ctr + 1
10637     continue
10638    endif
10639
10640    NetrwKeepj norm! 0
10641    let oldname= s:ComposePath(a:path,curword)
10642"   call Decho("oldname<".oldname.">",'~'.expand("<slnum>"))
10643
10644    call inputsave()
10645    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
10646    call inputrestore()
10647
10648    call rename(oldname,newname)
10649"   call Decho("renaming <".oldname."> to <".newname.">",'~'.expand("<slnum>"))
10650
10651    let ctr= ctr + 1
10652   endwhile
10653  endif
10654
10655  " refresh the directory
10656"  call Decho("refresh the directory listing",'~'.expand("<slnum>"))
10657  NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10658"  call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10659  NetrwKeepj call winrestview(svpos)
10660  let @@= ykeep
10661
10662"  call Dret("NetrwLocalRename")
10663endfun
10664
10665" ---------------------------------------------------------------------
10666" s:NetrwLocalRm: {{{2
10667fun! s:NetrwLocalRm(path) range
10668"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
10669"  call Decho("firstline=".a:firstline." lastline=".a:lastline,'~'.expand("<slnum>"))
10670
10671  " preparation for removing multiple files/directories
10672  let ykeep = @@
10673  let ret   = 0
10674  let all   = 0
10675  let svpos = winsaveview()
10676"  call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10677
10678  if exists("s:netrwmarkfilelist_{bufnr('%')}")
10679   " remove all marked files
10680"   call Decho("remove all marked files",'~'.expand("<slnum>"))
10681   for fname in s:netrwmarkfilelist_{bufnr("%")}
10682    let ok= s:NetrwLocalRmFile(a:path,fname,all)
10683    if ok =~# 'q\%[uit]' || ok == "no"
10684     break
10685    elseif ok =~# 'a\%[ll]'
10686     let all= 1
10687    endif
10688   endfor
10689   call s:NetrwUnMarkFile(1)
10690
10691  else
10692  " remove (multiple) files and directories
10693"   call Decho("remove files in range [".a:firstline.",".a:lastline."]",'~'.expand("<slnum>"))
10694
10695   let keepsol= &l:sol
10696   setl nosol
10697   let ctr = a:firstline
10698   while ctr <= a:lastline
10699    exe "NetrwKeepj ".ctr
10700
10701    " sanity checks
10702    if line(".") < w:netrw_bannercnt
10703     let ctr= ctr + 1
10704     continue
10705    endif
10706    let curword= s:NetrwGetWord()
10707    if curword == "./" || curword == "../"
10708     let ctr= ctr + 1
10709     continue
10710    endif
10711    let ok= s:NetrwLocalRmFile(a:path,curword,all)
10712    if ok =~# 'q\%[uit]' || ok == "no"
10713     break
10714    elseif ok =~# 'a\%[ll]'
10715     let all= 1
10716    endif
10717    let ctr= ctr + 1
10718   endwhile
10719   let &l:sol= keepsol
10720  endif
10721
10722  " refresh the directory
10723"  call Decho("bufname<".bufname("%").">",'~'.expand("<slnum>"))
10724  if bufname("%") != "NetrwMessage"
10725   NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
10726"   call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
10727   NetrwKeepj call winrestview(svpos)
10728  endif
10729  let @@= ykeep
10730
10731"  call Dret("s:NetrwLocalRm")
10732endfun
10733
10734" ---------------------------------------------------------------------
10735" s:NetrwLocalRmFile: remove file fname given the path {{{2
10736"                     Give confirmation prompt unless all==1
10737fun! s:NetrwLocalRmFile(path,fname,all)
10738"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
10739
10740  let all= a:all
10741  let ok = ""
10742  NetrwKeepj norm! 0
10743  let rmfile= s:NetrwFile(s:ComposePath(a:path,a:fname))
10744"  call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
10745
10746  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
10747   " attempt to remove file
10748"   call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
10749   if !all
10750    echohl Statement
10751    call inputsave()
10752    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10753    call inputrestore()
10754    echohl NONE
10755    if ok == ""
10756     let ok="no"
10757    endif
10758"    call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
10759    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10760"    call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
10761    if ok =~# 'a\%[ll]'
10762     let all= 1
10763    endif
10764   endif
10765
10766   if all || ok =~# 'y\%[es]' || ok == ""
10767    let ret= s:NetrwDelete(rmfile)
10768"    call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
10769   endif
10770
10771  else
10772   " attempt to remove directory
10773   if !all
10774    echohl Statement
10775    call inputsave()
10776    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10777    call inputrestore()
10778    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10779    if ok == ""
10780     let ok="no"
10781    endif
10782    if ok =~# 'a\%[ll]'
10783     let all= 1
10784    endif
10785   endif
10786   let rmfile= substitute(rmfile,'[\/]$','','e')
10787
10788   if all || ok =~# 'y\%[es]' || ok == ""
10789    if v:version < 704 || !has("patch1109")
10790" "    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_localrmdir.') '.s:ShellEscape(rmfile).')','~'.expand("<slnum>"))
10791     call system(netrw#WinPath(g:netrw_localrmdir).' '.s:ShellEscape(rmfile))
10792" "    call Decho("v:shell_error=".v:shell_error,'~'.expand("<slnum>"))
10793
10794     if v:shell_error != 0
10795" "     call Decho("2nd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
10796      let errcode= s:NetrwDelete(rmfile)
10797" "     call Decho("errcode=".errcode,'~'.expand("<slnum>"))
10798
10799      if errcode != 0
10800       if has("unix")
10801" "       call Decho("3rd attempt to remove directory<".rmfile.">",'~'.expand("<slnum>"))
10802	call system("rm ".s:ShellEscape(rmfile))
10803	if v:shell_error != 0 && !exists("g:netrw_quiet")
10804	 call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
10805	 let ok="no"
10806	endif
10807       elseif !exists("g:netrw_quiet")
10808	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
10809	let ok="no"
10810       endif
10811      endif
10812     endif
10813    else
10814     if delete(rmfile,"d")
10815      call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
10816     endif
10817    endif
10818   endif
10819  endif
10820
10821"  call Dret("s:NetrwLocalRmFile ".ok)
10822  return ok
10823endfun
10824
10825" ---------------------------------------------------------------------
10826" Support Functions: {{{1
10827
10828" ---------------------------------------------------------------------
10829" s:WinNames: COMBAK {{{2
10830fun! s:WinNames(id)
10831  let curwin= winnr()
10832  1wincmd w
10833"  call Decho("--- Windows By Name --- #".a:id)
10834"  windo call Decho("win#".winnr()."<".expand("%").">")
10835"  call Decho("--- --- --- --- --- ---")
10836  exe curwin."wincmd w"
10837endfun
10838
10839" ---------------------------------------------------------------------
10840" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
10841"   0: marked file list of current buffer
10842"   1: marked file target
10843fun! netrw#Access(ilist)
10844  if     a:ilist == 0
10845   if exists("s:netrwmarkfilelist_".bufnr('%'))
10846    return s:netrwmarkfilelist_{bufnr('%')}
10847   else
10848    return "no-list-buf#".bufnr('%')
10849   endif
10850  elseif a:ilist == 1
10851   return s:netrwmftgt
10852endfun
10853
10854" ---------------------------------------------------------------------
10855" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
10856fun! netrw#Call(funcname,...)
10857"  call Dfunc("netrw#Call(funcname<".a:funcname.">,".string(a:000).")")
10858  if a:0 > 0
10859   exe "call s:".a:funcname."(".string(a:000).")"
10860  else
10861   exe "call s:".a:funcname."()"
10862  endif
10863"  call Dret("netrw#Call")
10864endfun
10865
10866" ---------------------------------------------------------------------
10867" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
10868"               I expect this function to be used in
10869"                 :PChkAssert netrw#Expose("netrwmarkfilelist")
10870"               for example.
10871fun! netrw#Expose(varname)
10872"   call Dfunc("netrw#Expose(varname<".a:varname.">)")
10873  if exists("s:".a:varname)
10874   exe "let retval= s:".a:varname
10875   if exists("g:netrw_pchk")
10876    if type(retval) == 3
10877     let retval = copy(retval)
10878     let i      = 0
10879     while i < len(retval)
10880      let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
10881      let i        = i + 1
10882     endwhile
10883    endif
10884"     call Dret("netrw#Expose ".string(retval))
10885    return string(retval)
10886   endif
10887  else
10888   let retval= "n/a"
10889  endif
10890
10891"  call Dret("netrw#Expose ".string(retval))
10892  return retval
10893endfun
10894
10895" ---------------------------------------------------------------------
10896" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
10897fun! netrw#Modify(varname,newvalue)
10898"  call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
10899  exe "let s:".a:varname."= ".string(a:newvalue)
10900"  call Dret("netrw#Modify")
10901endfun
10902
10903" ---------------------------------------------------------------------
10904"  netrw#RFC2396: converts %xx into characters {{{2
10905fun! netrw#RFC2396(fname)
10906"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
10907  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
10908"  call Dret("netrw#RFC2396 ".fname)
10909  return fname
10910endfun
10911
10912" ---------------------------------------------------------------------
10913" netrw#UserMaps: supports user-specified maps {{{2
10914"                 see :help function()
10915"
10916"                 g:Netrw_UserMaps is a List with members such as:
10917"                       [[keymap sequence, function reference],...]
10918"
10919"                 The referenced function may return a string,
10920"                 	refresh : refresh the display
10921"                 	-other- : this string will be executed
10922"                 or it may return a List of strings.
10923"
10924"                 Each keymap-sequence will be set up with a nnoremap
10925"                 to invoke netrw#UserMaps(islocal).
10926"                 Related functions:
10927"                   netrw#Expose(varname)          -- see s:varname variables
10928"                   netrw#Modify(varname,newvalue) -- modify value of s:varname variable
10929"                   netrw#Call(funcname,...)       -- call internal netrw function with optional arguments
10930fun! netrw#UserMaps(islocal)
10931"  call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
10932"  call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
10933
10934   " set up usermaplist
10935   if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
10936"    call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
10937    for umap in g:Netrw_UserMaps
10938"     call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
10939"     call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
10940     " if umap[0] is a string and umap[1] is a string holding a function name
10941     if type(umap[0]) == 1 && type(umap[1]) == 1
10942"      call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
10943      exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
10944      else
10945       call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
10946     endif
10947    endfor
10948   endif
10949"  call Dret("netrw#UserMaps")
10950endfun
10951
10952" ---------------------------------------------------------------------
10953" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
10954fun! netrw#WinPath(path)
10955"  call Dfunc("netrw#WinPath(path<".a:path.">)")
10956  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
10957   " remove cygdrive prefix, if present
10958   let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
10959   " remove trailing slash (Win95)
10960   let path = substitute(path, '\(\\\|/\)$', '', 'g')
10961   " remove escaped spaces
10962   let path = substitute(path, '\ ', ' ', 'g')
10963   " convert slashes to backslashes
10964   let path = substitute(path, '/', '\', 'g')
10965  else
10966   let path= a:path
10967  endif
10968"  call Dret("netrw#WinPath <".path.">")
10969  return path
10970endfun
10971
10972" ---------------------------------------------------------------------
10973"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
10974fun! s:ComposePath(base,subdir)
10975"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
10976
10977  if has("amiga")
10978"   call Decho("amiga",'~'.expand("<slnum>"))
10979   let ec = a:base[s:Strlen(a:base)-1]
10980   if ec != '/' && ec != ':'
10981    let ret = a:base."/" . a:subdir
10982   else
10983    let ret = a:base.a:subdir
10984   endif
10985
10986  elseif a:subdir =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
10987"   call Decho("windows",'~'.expand("<slnum>"))
10988   let ret= a:subdir
10989
10990  elseif a:base =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
10991"   call Decho("windows",'~'.expand("<slnum>"))
10992   if a:base =~ '[/\\]$'
10993    let ret= a:base.a:subdir
10994   else
10995    let ret= a:base.'/'.a:subdir
10996   endif
10997
10998  elseif a:base =~ '^\a\{3,}://'
10999"   call Decho("remote linux/macos",'~'.expand("<slnum>"))
11000   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
11001   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
11002   if a:subdir == '../'
11003    if curpath =~ '[^/]/[^/]\+/$'
11004     let curpath= substitute(curpath,'[^/]\+/$','','')
11005    else
11006     let curpath=""
11007    endif
11008    let ret= urlbase.curpath
11009   else
11010    let ret= urlbase.curpath.a:subdir
11011   endif
11012"   call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
11013"   call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
11014"   call Decho("ret<".ret.">",'~'.expand("<slnum>"))
11015
11016  else
11017"   call Decho("local linux/macos",'~'.expand("<slnum>"))
11018   let ret = substitute(a:base."/".a:subdir,"//","/","g")
11019   if a:base =~ '^//'
11020    " keeping initial '//' for the benefit of network share listing support
11021    let ret= '/'.ret
11022   endif
11023   let ret= simplify(ret)
11024  endif
11025
11026"  call Dret("s:ComposePath ".ret)
11027  return ret
11028endfun
11029
11030" ---------------------------------------------------------------------
11031" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
11032"   Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
11033fun! s:DeleteBookmark(fname)
11034"  call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
11035  call s:MergeBookmarks()
11036
11037  if exists("g:netrw_bookmarklist")
11038   let indx= index(g:netrw_bookmarklist,a:fname)
11039   if indx == -1
11040    let indx= 0
11041    while indx < len(g:netrw_bookmarklist)
11042     if g:netrw_bookmarklist[indx] =~ a:fname
11043      call remove(g:netrw_bookmarklist,indx)
11044      let indx= indx - 1
11045     endif
11046     let indx= indx + 1
11047    endwhile
11048   else
11049    " remove exact match
11050    call remove(g:netrw_bookmarklist,indx)
11051   endif
11052  endif
11053
11054"  call Dret("s:DeleteBookmark")
11055endfun
11056
11057" ---------------------------------------------------------------------
11058" s:FileReadable: o/s independent filereadable {{{2
11059fun! s:FileReadable(fname)
11060"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
11061
11062  if g:netrw_cygwin
11063   let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
11064  else
11065   let ret= filereadable(s:NetrwFile(a:fname))
11066  endif
11067
11068"  call Dret("s:FileReadable ".ret)
11069  return ret
11070endfun
11071
11072" ---------------------------------------------------------------------
11073"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
11074"                 Places correct suffix on end of temporary filename,
11075"                 using the suffix provided with fname
11076fun! s:GetTempfile(fname)
11077"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
11078
11079  if !exists("b:netrw_tmpfile")
11080   " get a brand new temporary filename
11081   let tmpfile= tempname()
11082"   call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
11083
11084   let tmpfile= substitute(tmpfile,'\','/','ge')
11085"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
11086
11087   " sanity check -- does the temporary file's directory exist?
11088   if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
11089"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11090    NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
11091"    call Dret("s:GetTempfile getcwd<".getcwd().">")
11092    return ""
11093   endif
11094
11095   " let netrw#NetSource() know about the tmpfile
11096   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
11097"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
11098
11099   " o/s dependencies
11100   if g:netrw_cygwin != 0
11101    let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
11102   elseif has("win32") || has("win95") || has("win64") || has("win16")
11103    if !exists("+shellslash") || !&ssl
11104     let tmpfile = substitute(tmpfile,'/','\','g')
11105    endif
11106   else
11107    let tmpfile = tmpfile
11108   endif
11109   let b:netrw_tmpfile= tmpfile
11110"   call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
11111  else
11112   " re-use temporary filename
11113   let tmpfile= b:netrw_tmpfile
11114"   call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
11115  endif
11116
11117  " use fname's suffix for the temporary file
11118  if a:fname != ""
11119   if a:fname =~ '\.[^./]\+$'
11120"    call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11121    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11122     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11123    elseif a:fname =~ '.txz$'
11124     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11125    else
11126     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11127    endif
11128"    call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11129    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11130"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11131    let tmpfile .= suffix
11132"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11133    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
11134   endif
11135  endif
11136
11137"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11138"  call Dret("s:GetTempfile <".tmpfile.">")
11139  return tmpfile
11140endfun
11141
11142" ---------------------------------------------------------------------
11143" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
11144"               a correct command for use with a system() call
11145fun! s:MakeSshCmd(sshcmd)
11146"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
11147  if s:user == ""
11148   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
11149  else
11150   let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
11151  endif
11152  if exists("g:netrw_port") && g:netrw_port != ""
11153   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
11154  elseif exists("s:port") && s:port != ""
11155   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
11156  else
11157   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
11158  endif
11159"  call Dret("s:MakeSshCmd <".sshcmd.">")
11160  return sshcmd
11161endfun
11162
11163" ---------------------------------------------------------------------
11164" s:MakeBookmark: enters a bookmark into Netrw's bookmark system   {{{2
11165fun! s:MakeBookmark(fname)
11166"  call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
11167
11168  if !exists("g:netrw_bookmarklist")
11169   let g:netrw_bookmarklist= []
11170  endif
11171
11172  if index(g:netrw_bookmarklist,a:fname) == -1
11173   " curdir not currently in g:netrw_bookmarklist, so include it
11174   if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11175    call add(g:netrw_bookmarklist,a:fname.'/')
11176   elseif a:fname !~ '/'
11177    call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11178   else
11179    call add(g:netrw_bookmarklist,a:fname)
11180   endif
11181   call sort(g:netrw_bookmarklist)
11182  endif
11183
11184"  call Dret("s:MakeBookmark")
11185endfun
11186
11187" ---------------------------------------------------------------------
11188" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11189fun! s:MergeBookmarks()
11190"  call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
11191  " get bookmarks from .netrwbook file
11192  let savefile= s:NetrwHome()."/.netrwbook"
11193  if filereadable(s:NetrwFile(savefile))
11194"   call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11195   NetrwKeepj call s:NetrwBookHistSave()
11196"   call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11197   NetrwKeepj call delete(savefile)
11198  endif
11199"  call Dret("s:MergeBookmarks")
11200endfun
11201
11202" ---------------------------------------------------------------------
11203" s:NetrwBMShow: {{{2
11204fun! s:NetrwBMShow()
11205"  call Dfunc("s:NetrwBMShow()")
11206  redir => bmshowraw
11207   menu
11208  redir END
11209  let bmshowlist = split(bmshowraw,'\n')
11210  if bmshowlist != []
11211   let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"')
11212   if bmshowfuncs != []
11213    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11214    if bmshowfunc =~# '^call.*BMShow()'
11215     exe "sil! NetrwKeepj ".bmshowfunc
11216    endif
11217   endif
11218  endif
11219"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
11220endfun
11221
11222" ---------------------------------------------------------------------
11223" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
11224fun! s:NetrwCursor()
11225  if !exists("w:netrw_liststyle")
11226   let w:netrw_liststyle= g:netrw_liststyle
11227  endif
11228"  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)
11229
11230  if &ft != "netrw"
11231   " if the current window isn't a netrw directory listing window, then use user cursorline/column
11232   " settings.  Affects when netrw is used to read/write a file using scp/ftp/etc.
11233"   call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
11234   let &l:cursorline   = s:netrw_usercul
11235   let &l:cursorcolumn = s:netrw_usercuc
11236
11237  elseif g:netrw_cursor == 4
11238   " all styles: cursorline, cursorcolumn
11239"   call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
11240   setl cursorline
11241   setl cursorcolumn
11242
11243  elseif g:netrw_cursor == 3
11244   " thin-long-tree: cursorline, user's cursorcolumn
11245   " wide          : cursorline, cursorcolumn
11246   if w:netrw_liststyle == s:WIDELIST
11247"    call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11248    setl cursorline
11249    setl cursorcolumn
11250   else
11251"    call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11252    setl cursorline
11253    let &l:cursorcolumn   = s:netrw_usercuc
11254   endif
11255
11256  elseif g:netrw_cursor == 2
11257   " thin-long-tree: cursorline, user's cursorcolumn
11258   " wide          : cursorline, user's cursorcolumn
11259"   call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11260   let &l:cursorcolumn = s:netrw_usercuc
11261   setl cursorline
11262
11263  elseif g:netrw_cursor == 1
11264   " thin-long-tree: user's cursorline, user's cursorcolumn
11265   " wide          : cursorline,        user's cursorcolumn
11266   let &l:cursorcolumn = s:netrw_usercuc
11267   if w:netrw_liststyle == s:WIDELIST
11268"    call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11269    setl cursorline
11270   else
11271"    call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11272    let &l:cursorline   = s:netrw_usercul
11273   endif
11274
11275  else
11276   " all styles: user's cursorline, user's cursorcolumn
11277"   call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11278   let &l:cursorline   = s:netrw_usercul
11279   let &l:cursorcolumn = s:netrw_usercuc
11280  endif
11281
11282"  call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
11283endfun
11284
11285" ---------------------------------------------------------------------
11286" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11287fun! s:RestoreCursorline()
11288"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
11289  if exists("s:netrw_usercul")
11290   let &l:cursorline   = s:netrw_usercul
11291  endif
11292  if exists("s:netrw_usercuc")
11293   let &l:cursorcolumn = s:netrw_usercuc
11294  endif
11295"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
11296endfun
11297
11298" ---------------------------------------------------------------------
11299" s:NetrwDelete: Deletes a file. {{{2
11300"           Uses Steve Hall's idea to insure that Windows paths stay
11301"           acceptable.  No effect on Unix paths.
11302"  Examples of use:  let result= s:NetrwDelete(path)
11303fun! s:NetrwDelete(path)
11304"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
11305
11306  let path = netrw#WinPath(a:path)
11307  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
11308   if exists("+shellslash")
11309    let sskeep= &shellslash
11310    setl noshellslash
11311    let result      = delete(path)
11312    let &shellslash = sskeep
11313   else
11314"    call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11315    let result= delete(path)
11316   endif
11317  else
11318"   call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11319   let result= delete(path)
11320  endif
11321  if result < 0
11322   NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
11323  endif
11324
11325"  call Dret("s:NetrwDelete ".result)
11326  return result
11327endfun
11328
11329" ---------------------------------------------------------------------
11330" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
11331fun! s:NetrwEnew(...)
11332"  call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$"))
11333"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
11334
11335  " grab a function-local-variable copy of buffer variables
11336"  call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
11337  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
11338  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
11339  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
11340  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
11341  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11342  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
11343  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
11344  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
11345  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11346  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11347  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
11348  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
11349  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
11350  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
11351  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
11352  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
11353
11354  NetrwKeepj call s:NetrwOptionRestore("w:")
11355"  call Decho("generate a buffer with NetrwKeepj keepalt enew!",'~'.expand("<slnum>"))
11356  " when tree listing uses file TreeListing... a new buffer is made.
11357  " Want the old buffer to be unlisted.
11358  " COMBAK: this causes a problem, see P43
11359"  setl nobl
11360  let netrw_keepdiff= &l:diff
11361  noswapfile NetrwKeepj keepalt enew!
11362  let &l:diff= netrw_keepdiff
11363"  call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
11364  NetrwKeepj call s:NetrwOptionSave("w:")
11365
11366  " copy function-local-variables to buffer variable equivalents
11367"  call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
11368  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
11369  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
11370  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
11371  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
11372  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
11373  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
11374  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
11375  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
11376  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11377  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11378  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
11379  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
11380  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
11381  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
11382  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
11383  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
11384
11385  if a:0 > 0
11386   let b:netrw_curdir= a:1
11387   if b:netrw_curdir =~ '/$'
11388    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11389     setl nobl
11390     file NetrwTreeListing
11391     setl nobl bt=nowrite bh=hide
11392     nno <silent> <buffer> [	:sil call <SID>TreeListMove('[')<cr>
11393     nno <silent> <buffer> ]	:sil call <SID>TreeListMove(']')<cr>
11394    else
11395     exe "sil! keepalt file ".fnameescape(b:netrw_curdir)
11396    endif
11397   endif
11398  endif
11399
11400"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
11401endfun
11402
11403" ---------------------------------------------------------------------
11404" s:NetrwExe: executes a string using "!" {{{2
11405fun! s:NetrwExe(cmd)
11406"  call Dfunc("s:NetrwExe(a:cmd)")
11407  if has("win32") && &shell !~? 'cmd' && !g:netrw_cygwin
11408    let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
11409    set shell& shellcmdflag& shellxquote& shellxescape&
11410    set shellquote& shellpipe& shellredir& shellslash&
11411    exe a:cmd
11412    let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
11413  else
11414   exe a:cmd
11415  endif
11416"  call Dret("s:NetrwExe")
11417endfun
11418
11419" ---------------------------------------------------------------------
11420" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
11421fun! s:NetrwInsureWinVars()
11422  if !exists("w:netrw_liststyle")
11423"   call Dfunc("s:NetrwInsureWinVars() win#".winnr())
11424   let curbuf = bufnr("%")
11425   let curwin = winnr()
11426   let iwin   = 1
11427   while iwin <= winnr("$")
11428    exe iwin."wincmd w"
11429    if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
11430     " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
11431     let winvars= w:
11432     break
11433    endif
11434    let iwin= iwin + 1
11435   endwhile
11436   exe "keepalt ".curwin."wincmd w"
11437   if exists("winvars")
11438"    call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
11439    for k in keys(winvars)
11440     let w:{k}= winvars[k]
11441    endfor
11442   endif
11443"   call Dret("s:NetrwInsureWinVars win#".winnr())
11444  endif
11445endfun
11446
11447" ---------------------------------------------------------------------
11448" s:NetrwLcd: handles changing the (local) directory {{{2
11449fun! s:NetrwLcd(newdir)
11450"  call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
11451
11452  try
11453   exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
11454  catch /^Vim\%((\a\+)\)\=:E344/
11455     " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
11456     " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
11457     " 'root' (ie. '\').  The share name may start with either backslashes ('\\Foo') or
11458     " forward slashes ('//Foo'), depending on whether backslashes have been converted to
11459     " forward slashes by earlier code; so check for both.
11460     if (has("win32") || has("win95") || has("win64") || has("win16")) && !g:netrw_cygwin
11461       if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
11462         let dirname = '\'
11463	 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
11464       endif
11465     endif
11466  catch /^Vim\%((\a\+)\)\=:E472/
11467   call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
11468   if exists("w:netrw_prvdir")
11469    let a:newdir= w:netrw_prvdir
11470   else
11471    call s:NetrwOptionRestore("w:")
11472"    call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
11473    exe "setl ".g:netrw_bufsettings
11474"    call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11475    let a:newdir= dirname
11476"    call Dret("s:NetrwBrowse : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
11477    return
11478   endif
11479  endtry
11480
11481"  call Dret("s:NetrwLcd")
11482endfun
11483
11484" ------------------------------------------------------------------------
11485" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
11486" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
11487fun! s:NetrwSaveWordPosn()
11488"  call Dfunc("NetrwSaveWordPosn()")
11489  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
11490"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
11491endfun
11492
11493" ---------------------------------------------------------------------
11494" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
11495"                       1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
11496fun! s:NetrwHumanReadable(sz)
11497"  call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
11498
11499  if g:netrw_sizestyle == 'h'
11500   if a:sz >= 1000000000
11501    let sz = printf("%.1f",a:sz/1000000000.0)."g"
11502   elseif a:sz >= 10000000
11503    let sz = printf("%d",a:sz/1000000)."m"
11504   elseif a:sz >= 1000000
11505    let sz = printf("%.1f",a:sz/1000000.0)."m"
11506   elseif a:sz >= 10000
11507    let sz = printf("%d",a:sz/1000)."k"
11508   elseif a:sz >= 1000
11509    let sz = printf("%.1f",a:sz/1000.0)."k"
11510   else
11511    let sz= a:sz
11512   endif
11513
11514  elseif g:netrw_sizestyle == 'H'
11515   if a:sz >= 1073741824
11516    let sz = printf("%.1f",a:sz/1073741824.0)."G"
11517   elseif a:sz >= 10485760
11518    let sz = printf("%d",a:sz/1048576)."M"
11519   elseif a:sz >= 1048576
11520    let sz = printf("%.1f",a:sz/1048576.0)."M"
11521   elseif a:sz >= 10240
11522    let sz = printf("%d",a:sz/1024)."K"
11523   elseif a:sz >= 1024
11524    let sz = printf("%.1f",a:sz/1024.0)."K"
11525   else
11526    let sz= a:sz
11527   endif
11528
11529  else
11530   let sz= a:sz
11531  endif
11532
11533"  call Dret("s:NetrwHumanReadable ".sz)
11534  return sz
11535endfun
11536
11537" ---------------------------------------------------------------------
11538" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
11539"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
11540fun! s:NetrwRestoreWordPosn()
11541"  call Dfunc("NetrwRestoreWordPosn()")
11542  sil! call search(s:netrw_saveword,'w')
11543"  call Dret("NetrwRestoreWordPosn")
11544endfun
11545
11546" ---------------------------------------------------------------------
11547" s:RestoreBufVars: {{{2
11548fun! s:RestoreBufVars()
11549"  call Dfunc("s:RestoreBufVars()")
11550
11551  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
11552  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
11553  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
11554  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
11555  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
11556  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
11557
11558"  call Dret("s:RestoreBufVars")
11559endfun
11560
11561" ---------------------------------------------------------------------
11562" s:RemotePathAnalysis: {{{2
11563fun! s:RemotePathAnalysis(dirname)
11564"  call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
11565
11566  "                method   ://    user  @      machine      :port            /path
11567  let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
11568  let s:method  = substitute(a:dirname,dirpat,'\1','')
11569  let s:user    = substitute(a:dirname,dirpat,'\3','')
11570  let s:machine = substitute(a:dirname,dirpat,'\4','')
11571  let s:port    = substitute(a:dirname,dirpat,'\5','')
11572  let s:path    = substitute(a:dirname,dirpat,'\6','')
11573  let s:fname   = substitute(s:path,'^.*/\ze.','','')
11574  if s:machine =~ '@'
11575   let dirpat    = '^\(.*\)@\(.\{-}\)$'
11576   let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')
11577   let s:machine = substitute(s:machine,dirpat,'\2','')
11578  endif
11579
11580"  call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
11581"  call Decho("set up s:user   <".s:user   .">",'~'.expand("<slnum>"))
11582"  call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
11583"  call Decho("set up s:port   <".s:port.">",'~'.expand("<slnum>"))
11584"  call Decho("set up s:path   <".s:path   .">",'~'.expand("<slnum>"))
11585"  call Decho("set up s:fname  <".s:fname  .">",'~'.expand("<slnum>"))
11586
11587"  call Dret("s:RemotePathAnalysis")
11588endfun
11589
11590" ---------------------------------------------------------------------
11591" s:RemoteSystem: runs a command on a remote host using ssh {{{2
11592"                 Returns status
11593" Runs system() on
11594"    [cd REMOTEDIRPATH;] a:cmd
11595" Note that it doesn't do s:ShellEscape(a:cmd)!
11596fun! s:RemoteSystem(cmd)
11597"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
11598  if !executable(g:netrw_ssh_cmd)
11599   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
11600  elseif !exists("b:netrw_curdir")
11601   NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
11602  else
11603   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
11604   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
11605   if remotedir != ""
11606    let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
11607   else
11608    let cmd= cmd.' '
11609   endif
11610   let cmd= cmd.a:cmd
11611"   call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
11612   let ret= system(cmd)
11613  endif
11614"  call Dret("s:RemoteSystem ".ret)
11615  return ret
11616endfun
11617
11618" ---------------------------------------------------------------------
11619" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
11620fun! s:RestoreWinVars()
11621"  call Dfunc("s:RestoreWinVars()")
11622  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
11623  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
11624  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
11625  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
11626  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
11627  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
11628  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
11629  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
11630  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
11631  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
11632  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
11633  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
11634  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
11635  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
11636  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
11637  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
11638  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
11639  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
11640"  call Dret("s:RestoreWinVars")
11641endfun
11642
11643" ---------------------------------------------------------------------
11644" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
11645"
11646"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
11647"             is true) and a command, :Rexplore, which call this function.
11648"
11649"             s:netrw_nbcd is set up by s:NetrwBrowseChgDir()
11650"
11651"             s:rexposn_BUFNR used to save/restore cursor position
11652fun! s:NetrwRexplore(islocal,dirname)
11653  if exists("s:netrwdrag")
11654   return
11655  endif
11656"  call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
11657"  call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
11658"  call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
11659
11660  if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
11661   " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
11662"   call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
11663   exe "NetrwKeepj e ".w:netrw_rexfile
11664   unlet w:netrw_rexfile
11665"   call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%").">  (ft=".&ft.")")
11666   return
11667"  else " Decho
11668"   call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
11669"   call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
11670  endif
11671
11672  " ---------------------------
11673  " :Rex issued while in a file
11674  " ---------------------------
11675
11676  " record current file so :Rex can return to it from netrw
11677  let w:netrw_rexfile= expand("%")
11678"  call Decho("set w:netrw_rexfile<".w:netrw_rexfile.">  (win#".winnr().")",'~'.expand("<slnum>"))
11679
11680  if !exists("w:netrw_rexlocal")
11681"   call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
11682   return
11683  endif
11684"  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>"))
11685  if w:netrw_rexlocal
11686   NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
11687  else
11688   NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
11689  endif
11690  if exists("s:initbeval")
11691   setl beval
11692  endif
11693  if exists("s:rexposn_".bufnr("%"))
11694"   call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
11695   " restore position in directory listing
11696"   call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
11697   NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
11698   if exists("s:rexposn_".bufnr('%'))
11699    unlet s:rexposn_{bufnr('%')}
11700   endif
11701  else
11702"   call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
11703  endif
11704
11705  if exists("s:explore_match")
11706   exe "2match netrwMarkFile /".s:explore_match."/"
11707  endif
11708
11709"  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>"))
11710"  call Dret("s:NetrwRexplore : ft=".&ft)
11711endfun
11712
11713" ---------------------------------------------------------------------
11714" s:SaveBufVars: save selected b: variables to s: variables {{{2
11715"                use s:RestoreBufVars() to restore b: variables from s: variables
11716fun! s:SaveBufVars()
11717"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
11718
11719  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
11720  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
11721  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
11722  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
11723  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
11724  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
11725
11726"  call Dret("s:SaveBufVars")
11727endfun
11728
11729" ---------------------------------------------------------------------
11730" s:SavePosn: saves position associated with current buffer into a dictionary {{{2
11731fun! s:SavePosn(posndict)
11732"  call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
11733
11734  let a:posndict[bufnr("%")]= winsaveview()
11735"  call Decho("saving posn: posndict[".bufnr("%")."]=".string(winsaveview()),'~'.expand("<slnum>"))
11736
11737"  call Dret("s:SavePosn posndict")
11738  return a:posndict
11739endfun
11740
11741" ---------------------------------------------------------------------
11742" s:RestorePosn: restores position associated with current buffer using dictionary {{{2
11743fun! s:RestorePosn(posndict)
11744"  call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
11745  if has_key(a:posndict,bufnr("%"))
11746   call winrestview(a:posndict[bufnr("%")])
11747"   call Decho("restoring posn: posndict[".bufnr("%")."]=".string(a:posndict[bufnr("%")]),'~'.expand("<slnum>"))
11748  endif
11749"  call Dret("s:RestorePosn")
11750endfun
11751
11752" ---------------------------------------------------------------------
11753" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
11754fun! s:SaveWinVars()
11755"  call Dfunc("s:SaveWinVars() win#".winnr())
11756  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
11757  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
11758  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
11759  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
11760  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
11761  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
11762  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
11763  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
11764  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
11765  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
11766  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
11767  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
11768  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
11769  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
11770  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
11771  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
11772  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
11773  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
11774"  call Dret("s:SaveWinVars")
11775endfun
11776
11777" ---------------------------------------------------------------------
11778" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
11779"   To allow separate windows to have their own activities, such as
11780"   Explore **/pattern, several variables have been made window-oriented.
11781"   However, when the user splits a browser window (ex: ctrl-w s), these
11782"   variables are not inherited by the new window.  SetBufWinVars() and
11783"   UseBufWinVars() get around that.
11784fun! s:SetBufWinVars()
11785"  call Dfunc("s:SetBufWinVars() win#".winnr())
11786  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
11787  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
11788  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
11789  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
11790  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
11791  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
11792  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
11793  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
11794  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
11795  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
11796"  call Dret("s:SetBufWinVars")
11797endfun
11798
11799" ---------------------------------------------------------------------
11800" s:SetRexDir: set directory for :Rexplore {{{2
11801fun! s:SetRexDir(islocal,dirname)
11802"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
11803  let w:netrw_rexdir         = a:dirname
11804  let w:netrw_rexlocal       = a:islocal
11805  let s:rexposn_{bufnr("%")} = winsaveview()
11806"  call Decho("setting w:netrw_rexdir  =".w:netrw_rexdir,'~'.expand("<slnum>"))
11807"  call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>"))
11808"  call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
11809"  call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>"))
11810"  call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
11811endfun
11812
11813" ---------------------------------------------------------------------
11814" s:ShowLink: used to modify thin and tree listings to show links {{{2
11815fun! s:ShowLink()
11816" "  call Dfunc("s:ShowLink()")
11817" "  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">",'~'.expand("<slnum>"))
11818" "  call Decho(printf("line#%4d: %s",line("."),getline(".")),'~'.expand("<slnum>"))
11819  if exists("b:netrw_curdir")
11820   norm! $?\a
11821   let fname   = b:netrw_curdir.'/'.s:NetrwGetWord()
11822   let resname = resolve(fname)
11823" "   call Decho("fname         <".fname.">",'~'.expand("<slnum>"))
11824" "   call Decho("resname       <".resname.">",'~'.expand("<slnum>"))
11825" "   call Decho("b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
11826   if resname =~ '^\M'.b:netrw_curdir.'/'
11827    let dirlen  = strlen(b:netrw_curdir)
11828    let resname = strpart(resname,dirlen+1)
11829" "    call Decho("resname<".resname.">  (b:netrw_curdir elided)",'~'.expand("<slnum>"))
11830   endif
11831   let modline = getline(".")."\t --> ".resname
11832" "   call Decho("fname  <".fname.">",'~'.expand("<slnum>"))
11833" "   call Decho("modline<".modline.">",'~'.expand("<slnum>"))
11834   setl noro ma
11835   call setline(".",modline)
11836   setl ro noma nomod
11837  endif
11838" "  call Dret("s:ShowLink".((exists("fname")? ' : '.fname : 'n/a')))
11839endfun
11840
11841" ---------------------------------------------------------------------
11842" s:ShowStyle: {{{2
11843fun! s:ShowStyle()
11844  if !exists("w:netrw_liststyle")
11845   let liststyle= g:netrw_liststyle
11846  else
11847   let liststyle= w:netrw_liststyle
11848  endif
11849  if     liststyle == s:THINLIST
11850   return s:THINLIST.":thin"
11851  elseif liststyle == s:LONGLIST
11852   return s:LONGLIST.":long"
11853  elseif liststyle == s:WIDELIST
11854   return s:WIDELIST.":wide"
11855  elseif liststyle == s:TREELIST
11856   return s:TREELIST.":tree"
11857  else
11858   return 'n/a'
11859  endif
11860endfun
11861
11862" ---------------------------------------------------------------------
11863" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
11864"           Solution from Nicolai Weibull, vim docs (:help strlen()),
11865"           Tony Mechelynck, and my own invention.
11866fun! s:Strlen(x)
11867"  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
11868
11869  if v:version >= 703 && exists("*strdisplaywidth")
11870   let ret= strdisplaywidth(a:x)
11871
11872  elseif type(g:Align_xstrlen) == 1
11873   " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
11874   exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
11875
11876  elseif g:Align_xstrlen == 1
11877   " number of codepoints (Latin a + combining circumflex is two codepoints)
11878   " (comment from TM, solution from NW)
11879   let ret= strlen(substitute(a:x,'.','c','g'))
11880
11881  elseif g:Align_xstrlen == 2
11882   " number of spacing codepoints (Latin a + combining circumflex is one spacing
11883   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
11884   " (comment from TM, solution from TM)
11885   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
11886
11887  elseif g:Align_xstrlen == 3
11888   " virtual length (counting, for instance, tabs as anything between 1 and
11889   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
11890   " preceded by lam, one otherwise, etc.)
11891   " (comment from TM, solution from me)
11892   let modkeep= &l:mod
11893   exe "norm! o\<esc>"
11894   call setline(line("."),a:x)
11895   let ret= virtcol("$") - 1
11896   d
11897   NetrwKeepj norm! k
11898   let &l:mod= modkeep
11899
11900  else
11901   " at least give a decent default
11902    let ret= strlen(a:x)
11903  endif
11904"  "" call Dret("s:Strlen ".ret)
11905  return ret
11906endfun
11907
11908" ---------------------------------------------------------------------
11909" s:ShellEscape: shellescape(), or special windows handling {{{2
11910fun! s:ShellEscape(s, ...)
11911  if (has('win32') || has('win64')) && $SHELL == '' && &shellslash
11912    return printf('"%s"', substitute(a:s, '"', '""', 'g'))
11913  endif
11914  let f = a:0 > 0 ? a:1 : 0
11915  return shellescape(a:s, f)
11916endfun
11917
11918" ---------------------------------------------------------------------
11919" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
11920fun! s:TreeListMove(dir)
11921"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
11922  let curline      = getline('.')
11923  let prvline      = (line(".") > 1)?         getline(line(".")-1) : ''
11924  let nxtline      = (line(".") < line("$"))? getline(line(".")+1) : ''
11925  let curindent    = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
11926  let indentm1     = substitute(curindent,'^'.s:treedepthstring,'','')
11927  let treedepthchr = substitute(s:treedepthstring,' ','','g')
11928  let stopline     = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
11929"  call Decho("prvline  <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
11930"  call Decho("curline  <".curline."> #".line(".")    , '~'.expand("<slnum>"))
11931"  call Decho("nxtline  <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
11932"  call Decho("curindent<".curindent.">"              , '~'.expand("<slnum>"))
11933"  call Decho("indentm1 <".indentm1.">"               , '~'.expand("<slnum>"))
11934  "  COMBAK : need to handle when on a directory
11935  "  COMBAK : need to handle ]] and ][.  In general, needs work!!!
11936  if curline !~ '/$'
11937   if     a:dir == '[[' && prvline != ''
11938    NetrwKeepj norm! 0
11939    let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
11940"    call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
11941   elseif a:dir == '[]' && nxtline != ''
11942    NetrwKeepj norm! 0
11943"    call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>"))
11944    let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
11945    if nl != 0
11946     NetrwKeepj norm! k
11947    else
11948     NetrwKeepj norm! G
11949    endif
11950"    call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
11951   endif
11952  endif
11953
11954"  call Dret("s:TreeListMove")
11955endfun
11956
11957" ---------------------------------------------------------------------
11958" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
11959"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
11960"                      can't be called except via emenu.  But due to locale, that menu line may not be called
11961"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
11962fun! s:UpdateBuffersMenu()
11963"  call Dfunc("s:UpdateBuffersMenu()")
11964  if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
11965   try
11966    sil emenu Buffers.Refresh\ menu
11967   catch /^Vim\%((\a\+)\)\=:E/
11968    let v:errmsg= ""
11969    sil NetrwKeepj call s:NetrwBMShow()
11970   endtry
11971  endif
11972"  call Dret("s:UpdateBuffersMenu")
11973endfun
11974
11975" ---------------------------------------------------------------------
11976" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
11977"              Matching function to s:SetBufWinVars()
11978fun! s:UseBufWinVars()
11979"  call Dfunc("s:UseBufWinVars()")
11980  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
11981  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
11982  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
11983  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
11984  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
11985  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
11986  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11987  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
11988  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
11989  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
11990"  call Dret("s:UseBufWinVars")
11991endfun
11992
11993" ---------------------------------------------------------------------
11994" s:UserMaps: supports user-defined UserMaps {{{2
11995"               * calls a user-supplied funcref(islocal,curdir)
11996"               * interprets result
11997"             See netrw#UserMaps()
11998fun! s:UserMaps(islocal,funcname)
11999"  call Dfunc("s:UserMaps(islocal=".a:islocal.",funcname<".a:funcname.">)")
12000
12001  if !exists("b:netrw_curdir")
12002   let b:netrw_curdir= getcwd()
12003  endif
12004  let Funcref = function(a:funcname)
12005  let result  = Funcref(a:islocal)
12006
12007  if     type(result) == 1
12008   " if result from user's funcref is a string...
12009"   call Decho("result string from user funcref<".result.">",'~'.expand("<slnum>"))
12010   if result == "refresh"
12011"    call Decho("refreshing display",'~'.expand("<slnum>"))
12012    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12013   elseif result != ""
12014"    call Decho("executing result<".result.">",'~'.expand("<slnum>"))
12015    exe result
12016   endif
12017
12018  elseif type(result) == 3
12019   " if result from user's funcref is a List...
12020"   call Decho("result List from user funcref<".string(result).">",'~'.expand("<slnum>"))
12021   for action in result
12022    if action == "refresh"
12023"     call Decho("refreshing display",'~'.expand("<slnum>"))
12024     call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
12025    elseif action != ""
12026"     call Decho("executing action<".action.">",'~'.expand("<slnum>"))
12027     exe action
12028    endif
12029   endfor
12030  endif
12031
12032"  call Dret("s:UserMaps")
12033endfun
12034
12035" ---------------------------------------------------------------------
12036" Settings Restoration: {{{1
12037let &cpo= s:keepcpo
12038unlet s:keepcpo
12039
12040" ------------------------------------------------------------------------
12041" Modelines: {{{1
12042" vim:ts=8 fdm=marker
12043