1" netrw.vim: Handles file transfer and remote directory listing across
2"            AUTOLOAD SECTION
3" Date:		Jul 27, 2010
4" Version:	140
5" Maintainer:	Charles E Campbell, Jr <NdrOchip@ScampbellPfamily.AbizM-NOSPAM>
6" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
7" Copyright:    Copyright (C) 1999-2010 Charles E. Campbell, Jr. {{{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
25let g:loaded_netrw = "v140"
26if v:version < 702
27 echohl WarningMsg
28 echo "***warning*** this version of netrw needs vim 7.2"
29 echohl Normal
30 finish
31endif
32if !exists("s:NOTE")
33 let s:NOTE    = 0
34 let s:WARNING = 1
35 let s:ERROR   = 2
36endif
37
38" sanity checks
39if v:version < 700
40 call netrw#ErrorMsg(s:WARNING,"you need vim version 7.0 or later for version ".g:loaded_netrw." of netrw",1)
41 finish
42endif
43
44let s:keepcpo= &cpo
45setlocal cpo&vim
46"DechoTabOn
47"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw)
48
49" ======================
50"  Netrw Variables: {{{1
51" ======================
52
53" ---------------------------------------------------------------------
54" NetrwInit: initializes variables if they haven't been defined {{{2
55"            Loosely,  varname = value.
56fun s:NetrwInit(varname,value)
57  if !exists(a:varname)
58   if type(a:value) == 0
59    exe "let ".a:varname."=".a:value
60   elseif type(a:value) == 1
61    exe "let ".a:varname."="."'".a:value."'"
62   else
63    exe "let ".a:varname."=".a:value
64   endif
65  endif
66endfun
67
68" ---------------------------------------------------------------------
69"  Netrw Constants: {{{2
70call s:NetrwInit("g:netrw_dirhist_cnt",0)
71if !exists("s:LONGLIST")
72 call s:NetrwInit("s:THINLIST",0)
73 call s:NetrwInit("s:LONGLIST",1)
74 call s:NetrwInit("s:WIDELIST",2)
75 call s:NetrwInit("s:TREELIST",3)
76 call s:NetrwInit("s:MAXLIST" ,4)
77endif
78
79" ---------------------------------------------------------------------
80" Default values for netrw's global protocol variables {{{2
81if !exists("g:netrw_dav_cmd")
82 if executable("cadaver")
83  let g:netrw_dav_cmd	= "cadaver"
84 elseif executable("curl")
85  let g:netrw_dav_cmd	= "curl"
86 else
87  let g:netrw_dav_cmd   = ""
88 endif
89endif
90if !exists("g:netrw_fetch_cmd")
91 if executable("fetch")
92  let g:netrw_fetch_cmd	= "fetch -o"
93 else
94  let g:netrw_fetch_cmd	= ""
95 endif
96endif
97if !exists("g:netrw_ftp_cmd")
98  let g:netrw_ftp_cmd	= "ftp"
99endif
100if !exists("g:netrw_http_cmd")
101 if executable("elinks")
102  let g:netrw_http_cmd = "elinks"
103  call s:NetrwInit("g:netrw_http_xcmd","-source >")
104 elseif executable("links")
105  let g:netrw_http_cmd = "links"
106  call s:NetrwInit("g:netrw_http_xcmd","-source >")
107 elseif executable("curl")
108  let g:netrw_http_cmd	= "curl"
109  call s:NetrwInit("g:netrw_http_xcmd","-o")
110 elseif executable("wget")
111  let g:netrw_http_cmd	= "wget"
112  call s:NetrwInit("g:netrw_http_xcmd","-q -O")
113 elseif executable("fetch")
114  let g:netrw_http_cmd	= "fetch"
115  call s:NetrwInit("g:netrw_http_xcmd","-o")
116 else
117  let g:netrw_http_cmd	= ""
118 endif
119endif
120call s:NetrwInit("g:netrw_rcp_cmd"  , "rcp")
121call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
122call s:NetrwInit("g:netrw_scp_cmd"  , "scp -q")
123call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
124call s:NetrwInit("g:netrw_ssh_cmd"  , "ssh")
125
126if (has("win32") || has("win95") || has("win64") || has("win16"))
127  \ && exists("g:netrw_use_nt_rcp")
128  \ && g:netrw_use_nt_rcp
129  \ && executable( $SystemRoot .'/system32/rcp.exe')
130 let s:netrw_has_nt_rcp = 1
131 let s:netrw_rcpmode    = '-b'
132else
133 let s:netrw_has_nt_rcp = 0
134 let s:netrw_rcpmode    = ''
135endif
136
137" ---------------------------------------------------------------------
138" Default values for netrw's global variables {{{2
139" Cygwin Detection ------- {{{3
140if !exists("g:netrw_cygwin")
141 if has("win32") || has("win95") || has("win64") || has("win16")
142  if &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
143   let g:netrw_cygwin= 1
144  else
145   let g:netrw_cygwin= 0
146  endif
147 else
148  let g:netrw_cygwin= 0
149 endif
150endif
151" Default values - a-c ---------- {{{3
152call s:NetrwInit("g:netrw_alto"        , &sb)
153call s:NetrwInit("g:netrw_altv"        , &spr)
154call s:NetrwInit("g:netrw_banner"      , 1)
155call s:NetrwInit("g:netrw_browse_split", 0)
156call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro")
157call s:NetrwInit("g:netrw_chgwin"      , -1)
158call s:NetrwInit("g:netrw_compress"    , "gzip")
159call s:NetrwInit("g:netrw_ctags"       , "ctags")
160if !exists("g:netrw_cursorline")
161 let g:netrw_cursorline= 1
162 let s:netrw_usercul   = &cursorline
163 let s:netrw_usercuc   = &cursorcolumn
164endif
165" Default values - d-g ---------- {{{3
166call s:NetrwInit("g:netrw_dirhist_cnt"      , 0)
167call s:NetrwInit("g:netrw_decompress"       , '{ ".gz" : "gunzip", ".bz2" : "bunzip2", ".zip" : "unzip", ".tar" : "tar -xf", ".xz" : "unxz" }')
168call s:NetrwInit("g:netrw_dirhistmax"       , 10)
169call s:NetrwInit("g:netrw_fastbrowse"       , 1)
170call 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$')
171if !exists("g:netrw_ftp_list_cmd")
172 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
173  let g:netrw_ftp_list_cmd     = "ls -lF"
174  let g:netrw_ftp_timelist_cmd = "ls -tlF"
175  let g:netrw_ftp_sizelist_cmd = "ls -slF"
176 else
177  let g:netrw_ftp_list_cmd     = "dir"
178  let g:netrw_ftp_timelist_cmd = "dir"
179  let g:netrw_ftp_sizelist_cmd = "dir"
180 endif
181endif
182call s:NetrwInit("g:netrw_ftpmode",'binary')
183" Default values - h-lh ---------- {{{3
184call s:NetrwInit("g:netrw_hide",1)
185if !exists("g:netrw_ignorenetrc")
186 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
187  let g:netrw_ignorenetrc= 1
188 else
189  let g:netrw_ignorenetrc= 0
190 endif
191endif
192call s:NetrwInit("g:netrw_keepdir",1)
193if !exists("g:netrw_list_cmd")
194 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
195  " provide a 'pscp' listing command
196  if (has("win32") || has("win95") || has("win64") || has("win16")) && filereadable("c:\\private.ppk")
197   let g:netrw_scp_cmd ="pscp -i C:\\private.ppk"
198  endif
199  let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
200 elseif executable(g:netrw_ssh_cmd)
201  " provide a default listing command
202  let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
203 else
204"  call Decho(g:netrw_ssh_cmd." is not executable")
205  let g:netrw_list_cmd= ""
206 endif
207endif
208call s:NetrwInit("g:netrw_list_hide","")
209" Default values - lh-lz ---------- {{{3
210if !exists("g:netrw_localcopycmd")
211 if has("win32") || has("win95") || has("win64") || has("win16")
212  if g:netrw_cygwin
213   let g:netrw_localcopycmd= "cp"
214  else
215   let g:netrw_localcopycmd= "copy"
216  endif
217 elseif has("unix") || has("macunix")
218  let g:netrw_localcopycmd= "cp"
219 else
220  let g:netrw_localcopycmd= ""
221 endif
222endif
223call s:NetrwInit("g:netrw_local_mkdir","mkdir")
224if !exists("g:netrw_localmovecmd")
225 if has("win32") || has("win95") || has("win64") || has("win16")
226  if g:netrw_cygwin
227   let g:netrw_localmovecmd= "mv"
228  else
229   let g:netrw_localmovecmd= "move"
230  endif
231 elseif has("unix") || has("macunix")
232  let g:netrw_localmovecmd= "mv"
233 else
234  let g:netrw_localmovecmd= ""
235 endif
236endif
237call s:NetrwInit("g:netrw_local_rmdir", "rmdir")
238call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
239" sanity checks
240if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
241 let g:netrw_liststyle= s:THINLIST
242endif
243if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
244 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
245endif
246" Default values - m-r ---------- {{{3
247call s:NetrwInit("g:netrw_markfileesc"   , '*./[\~')
248call s:NetrwInit("g:netrw_maxfilenamelen", 32)
249call s:NetrwInit("g:netrw_menu"          , 1)
250call s:NetrwInit("g:netrw_mkdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
251call s:NetrwInit("g:netrw_mousemaps"     , (exists("&mouse") && &mouse =~ '[anh]'))
252call s:NetrwInit("g:netrw_retmap"        , 0)
253if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
254 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
255elseif has("win32") || has("win95") || has("win64") || has("win16")
256 call s:NetrwInit("g:netrw_chgperm"       , "cacls FILENAME /e /p PERM")
257else
258 call s:NetrwInit("g:netrw_chgperm"       , "chmod PERM FILENAME")
259endif
260call s:NetrwInit("g:netrw_preview"       , 0)
261call s:NetrwInit("g:netrw_scpport"       , "-P")
262call s:NetrwInit("g:netrw_sshport"       , "-p")
263call s:NetrwInit("g:netrw_rename_cmd"    , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
264call s:NetrwInit("g:netrw_rm_cmd"        , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
265call s:NetrwInit("g:netrw_rmdir_cmd"     , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
266call s:NetrwInit("g:netrw_rmf_cmd"       , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f")
267" Default values - s ---------- {{{3
268" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
269call s:NetrwInit("g:netrw_sepchr"        , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
270call s:NetrwInit("s:netrw_silentxfer"    , (exists("g:netrw_silent") && g:netrw_silent != 0)? "silent keepj " : "keepj ")
271call s:NetrwInit("g:netrw_sort_by"       , "name") " alternatives: date                                      , size
272call s:NetrwInit("g:netrw_sort_options"  , "")
273call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse  (z y x ...)
274if !exists("g:netrw_sort_sequence")
275 if has("unix")
276  let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
277 else
278  let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
279 endif
280endif
281call s:NetrwInit("g:netrw_special_syntax"   , 0)
282call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
283call s:NetrwInit("g:netrw_use_noswf"        , 0)
284" Default values - t-w ---------- {{{3
285call s:NetrwInit("g:netrw_timefmt","%c")
286call s:NetrwInit("g:netrw_xstrlen",0)
287call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
288call s:NetrwInit("g:netrw_use_errorwindow",1)
289call s:NetrwInit("g:netrw_win95ftp",1)
290call s:NetrwInit("g:netrw_winsize",25)
291" ---------------------------------------------------------------------
292" Default values for netrw's script variables: {{{2
293call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
294if has("win32") || has("win95") || has("win64") || has("win16")
295 call s:NetrwInit("g:netrw_glob_escape",'[]*?`{$')
296else
297 call s:NetrwInit("g:netrw_glob_escape",'[]*?`{~$\')
298endif
299call s:NetrwInit("g:netrw_menu_escape",'./&? \')
300call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
301call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
302
303" BufEnter event ignored by decho when following variable is true
304"  Has a side effect that doau BufReadPost doesn't work, so
305"  files read by network transfer aren't appropriately highlighted.
306"let g:decho_bufenter = 1	"Decho
307
308" ==============================
309"  Netrw Utility Functions: {{{1
310" ==============================
311
312" ------------------------------------------------------------------------
313" s:NetrwOptionSave: save options and set to "standard" form {{{2
314"  06/08/07 : removed call to NetrwSafeOptions(), either placed
315"             immediately after NetrwOptionSave() calls in NetRead
316"             and NetWrite, or after the s:NetrwEnew() call in
317"             NetrwBrowse.
318"             vt: normally its "w:" or "s:" (a variable type)
319fun! s:NetrwOptionSave(vt)
320"  call Dfunc("s:NetrwOptionSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$"))
321
322"  call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"))
323  if !exists("{a:vt}netrw_optionsave")
324   let {a:vt}netrw_optionsave= 1
325  else
326"   call Dret("s:NetrwOptionSave : options already saved")
327   return
328  endif
329"  call Decho("fo=".&fo.(exists("&acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff)
330
331  " Save current settings and current directory
332  let s:yykeep          = @@
333  if exists("&l:acd")
334   let {a:vt}netrw_acdkeep  = &l:acd
335  endif
336  let {a:vt}netrw_aikeep    = &l:ai
337  let {a:vt}netrw_awkeep    = &l:aw
338  let {a:vt}netrw_bombkeep  = &l:bomb
339  let {a:vt}netrw_cikeep    = &l:ci
340  let {a:vt}netrw_cinkeep   = &l:cin
341  let {a:vt}netrw_cinokeep  = &l:cino
342  let {a:vt}netrw_comkeep   = &l:com
343  let {a:vt}netrw_cpokeep   = &l:cpo
344  let {a:vt}netrw_diffkeep  = &l:diff
345  if g:netrw_keepdir
346   let {a:vt}netrw_dirkeep  = getcwd()
347  endif
348  let {a:vt}netrw_fokeep    = &l:fo           " formatoptions
349  let {a:vt}netrw_gdkeep    = &l:gd           " gdefault
350  let {a:vt}netrw_hidkeep   = &l:hidden
351  let {a:vt}netrw_imkeep    = &l:im
352  let {a:vt}netrw_magickeep = &l:magic
353  let {a:vt}netrw_repkeep   = &l:report
354  let {a:vt}netrw_selkeep   = &l:sel
355  let {a:vt}netrw_spellkeep = &l:spell
356  let {a:vt}netrw_twkeep    = &l:tw           " textwidth
357  let {a:vt}netrw_wigkeep   = &l:wig          " wildignore
358  if has("win32") && !has("win95")
359   let {a:vt}netrw_swfkeep  = &l:swf          " swapfile
360  endif
361  if &go =~ 'a' | silent! let {a:vt}netrw_regstar = @* | endif
362  silent! let {a:vt}netrw_regslash= @/
363
364"  call Dret("s:NetrwOptionSave : win#".winnr()." buf#".bufnr("%"))
365endfun
366
367" ------------------------------------------------------------------------
368" s:NetrwOptionRestore: restore options {{{2
369fun! s:NetrwOptionRestore(vt)
370"  call Dfunc("s:NetrwOptionRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")." winnr($)=".winnr("$"))
371  if !exists("{a:vt}netrw_optionsave")
372"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
373"   call Dret("s:NetrwOptionRestore : ".a:vt."netrw_optionsave doesn't exist")
374   return
375  endif
376  unlet {a:vt}netrw_optionsave
377
378  if exists("&acd")
379   if exists("{a:vt}netrw_acdkeep")
380"    call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd)
381    let curdir = getcwd()
382    let &l:acd = {a:vt}netrw_acdkeep
383    unlet {a:vt}netrw_acdkeep
384    if &l:acd
385"     call Decho("exe keepjumps lcd ".fnameescape(curdir))  " NOTE: was g:netrw_fname_escape for some reason
386     try
387      if !exists("&l:acd") && !&l:acd
388       exe 'keepj lcd '.fnameescape(curdir)
389      endif
390     catch /^Vim\%((\a\+)\)\=:E472/
391      call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".curdir."> (permissions?)",61)
392     endtry
393    endif
394   endif
395  endif
396  if exists("{a:vt}netrw_aikeep")   |let &l:ai     = {a:vt}netrw_aikeep      |unlet {a:vt}netrw_aikeep   |endif
397  if exists("{a:vt}netrw_awkeep")   |let &l:aw     = {a:vt}netrw_awkeep      |unlet {a:vt}netrw_awkeep   |endif
398  if exists("{a:vt}netrw_bombkeep") |let &l:bomb   = {a:vt}netrw_bombkeep    |unlet {a:vt}netrw_bombkeep |endif
399  if exists("{a:vt}netrw_cikeep")   |let &l:ci     = {a:vt}netrw_cikeep      |unlet {a:vt}netrw_cikeep   |endif
400  if exists("{a:vt}netrw_cinkeep")  |let &l:cin    = {a:vt}netrw_cinkeep     |unlet {a:vt}netrw_cinkeep  |endif
401  if exists("{a:vt}netrw_cinokeep") |let &l:cino   = {a:vt}netrw_cinokeep    |unlet {a:vt}netrw_cinokeep |endif
402  if exists("{a:vt}netrw_comkeep")  |let &l:com    = {a:vt}netrw_comkeep     |unlet {a:vt}netrw_comkeep  |endif
403  if exists("{a:vt}netrw_cpokeep")  |let &l:cpo    = {a:vt}netrw_cpokeep     |unlet {a:vt}netrw_cpokeep  |endif
404  if exists("{a:vt}netrw_diffkeep") |let &l:diff   = {a:vt}netrw_diffkeep    |unlet {a:vt}netrw_diffkeep |endif
405  if exists("{a:vt}netrw_dirkeep") && isdirectory({a:vt}netrw_dirkeep) && g:netrw_keepdir
406   let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
407   if exists("{a:vt}netrw_dirkeep")  |exe "keepjumps lcd ".fnameescape(dirkeep)|unlet {a:vt}netrw_dirkeep  |endif
408  endif
409  if exists("{a:vt}netrw_fokeep")   |let &l:fo     = {a:vt}netrw_fokeep      |unlet {a:vt}netrw_fokeep   |endif
410  if exists("{a:vt}netrw_gdkeep")   |let &l:gd     = {a:vt}netrw_gdkeep      |unlet {a:vt}netrw_gdkeep   |endif
411  if exists("{a:vt}netrw_hidkeep")  |let &l:hidden = {a:vt}netrw_hidkeep     |unlet {a:vt}netrw_hidkeep  |endif
412  if exists("{a:vt}netrw_imkeep")   |let &l:im     = {a:vt}netrw_imkeep      |unlet {a:vt}netrw_imkeep   |endif
413  if exists("{a:vt}netrw_magic")    |let &l:magic  = {a:vt}netrw_magic       |unlet {a:vt}netrw_magic    |endif
414  if exists("{a:vt}netrw_repkeep")  |let &l:report = {a:vt}netrw_repkeep     |unlet {a:vt}netrw_repkeep  |endif
415  if exists("{a:vt}netrw_selkeep")  |let &l:sel    = {a:vt}netrw_selkeep     |unlet {a:vt}netrw_selkeep  |endif
416  if exists("{a:vt}netrw_spellkeep")|let &l:spell  = {a:vt}netrw_spellkeep   |unlet {a:vt}netrw_spellkeep|endif
417  if exists("{a:vt}netrw_twkeep")   |let &l:tw     = {a:vt}netrw_twkeep      |unlet {a:vt}netrw_twkeep   |endif
418  if exists("{a:vt}netrw_wigkeep")  |let &l:wig    = {a:vt}netrw_wigkeep     |unlet {a:vt}netrw_wigkeep  |endif
419  if exists("s:yykeep")             |let  @@       = s:yykeep                |unlet s:yykeep             |endif
420  if exists("{a:vt}netrw_swfkeep")
421   if &directory == ""
422    " user hasn't specified a swapfile directory;
423    " netrw will temporarily set the swapfile directory
424    " to the current directory as returned by getcwd().
425    let &l:directory   = getcwd()
426    silent! let &l:swf = {a:vt}netrw_swfkeep
427    setlocal directory=
428    unlet {a:vt}netrw_swfkeep
429   elseif &l:swf != {a:vt}netrw_swfkeep
430    " following line causes a Press ENTER in windows -- can't seem to work around it!!!
431    silent! let &l:swf= {a:vt}netrw_swfkeep
432    unlet {a:vt}netrw_swfkeep
433   endif
434  endif
435  if exists("{a:vt}netrw_regstar") |silent! let @*= {a:vt}netrw_regstar |unlet {a:vt}netrw_regstar |endif
436  if exists("{a:vt}netrw_regslash")|silent! let @/= {a:vt}netrw_regslash|unlet {a:vt}netrw_regslash|endif
437
438"  call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd)
439"  call Decho("fo=".&fo.(exists("&acd")? " acd=".&acd : " acd doesn't exist"))
440"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
441"  call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"))
442"  call Dret("s:NetrwOptionRestore : win#".winnr()." buf#".bufnr("%"))
443endfun
444
445" ---------------------------------------------------------------------
446" s:NetrwSafeOptions: sets options to help netrw do its job {{{2
447fun! s:NetrwSafeOptions()
448"  call Dfunc("s:NetrwSafeOptions() win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
449"  call Decho("win#".winnr()."'s ft=".&ft)
450  setlocal cino=
451  setlocal com=
452  setlocal cpo-=aA
453  if exists("&acd") | setlocal noacd | endif
454  setlocal nocin noai nobomb noci magic nospell nohid wig= noaw noim
455  setlocal fo=nroql2
456  setlocal tw=0
457  setlocal report=10000
458  setlocal isk+=@ isk+=* isk+=/
459  setlocal sel=inclusive
460  if g:netrw_use_noswf && has("win32") && !has("win95")
461   setlocal noswf
462  endif
463  call s:NetrwCursorline()
464
465  " allow the user to override safe options
466"  call Decho("ft<".&ft."> ei=".&ei)
467  if &ft == "netrw"
468"   call Decho("do any netrw FileType autocmds")
469   silent keepalt keepjumps doau FileType netrw
470  endif
471
472"  call Decho("fo=".&fo.(exists("&acd")? " acd=".&acd : " acd doesn't exist"))
473"  call Dret("s:NetrwSafeOptions")
474endfun
475
476" ---------------------------------------------------------------------
477" netrw#NetrwClean: remove netrw {{{2
478" supports :NetrwClean  -- remove netrw from first directory on runtimepath
479"          :NetrwClean! -- remove netrw from all directories on runtimepath
480fun! netrw#NetrwClean(sys)
481"  call Dfunc("netrw#NetrwClean(sys=".a:sys.")")
482
483  if a:sys
484   let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
485  else
486   let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
487  endif
488"  call Decho("choice=".choice)
489  let diddel= 0
490  let diddir= ""
491
492  if choice == 1
493   for dir in split(&rtp,',')
494    if filereadable(dir."/plugin/netrwPlugin.vim")
495"     call Decho("removing netrw-related files from ".dir)
496     if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
497     if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
498     if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
499     if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
500     if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
501     if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
502     let diddir= dir
503     let diddel= diddel + 1
504     if !a:sys|break|endif
505    endif
506   endfor
507  endif
508
509   echohl WarningMsg
510  if diddel == 0
511   echomsg "netrw is either not installed or not removable"
512  elseif diddel == 1
513   echomsg "removed one copy of netrw from <".diddir.">"
514  else
515   echomsg "removed ".diddel." copies of netrw"
516  endif
517   echohl None
518
519"  call Dret("netrw#NetrwClean")
520endfun
521
522" ---------------------------------------------------------------------
523" netrw#Nread: {{{2
524fun! netrw#Nread(mode,fname)
525"  call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
526  call netrw#NetrwSavePosn()
527  call netrw#NetRead(a:mode,a:fname)
528  call netrw#NetrwRestorePosn()
529"  call Dret("netrw#Nread")
530endfun
531
532" ------------------------------------------------------------------------
533"  Netrw Transfer Functions: {{{1
534" ===============================
535
536" ------------------------------------------------------------------------
537" netrw#NetRead: responsible for reading a file over the net {{{2
538"   mode: =0 read remote file and insert before current line
539"         =1 read remote file and insert after current line
540"         =2 replace with remote file
541"         =3 obtain file, but leave in temporary format
542fun! netrw#NetRead(mode,...)
543"  call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw)
544
545  " NetRead: save options {{{3
546  call s:NetrwOptionSave("w:")
547  call s:NetrwSafeOptions()
548  call s:RestoreCursorline()
549
550  " NetRead: interpret mode into a readcmd {{{3
551  if     a:mode == 0 " read remote file before current line
552   let readcmd = "0r"
553  elseif a:mode == 1 " read file after current line
554   let readcmd = "r"
555  elseif a:mode == 2 " replace with remote file
556   let readcmd = "%r"
557  elseif a:mode == 3 " skip read of file (leave as temporary)
558   let readcmd = "t"
559  else
560   exe a:mode
561   let readcmd = "r"
562  endif
563  let ichoice = (a:0 == 0)? 0 : 1
564"  call Decho("readcmd<".readcmd."> ichoice=".ichoice)
565
566  " NetRead: get temporary filename {{{3
567  let tmpfile= s:GetTempfile("")
568  if tmpfile == ""
569"   call Dret("netrw#NetRead : unable to get a tempfile!")
570   return
571  endif
572
573  while ichoice <= a:0
574
575   " attempt to repeat with previous host-file-etc
576   if exists("b:netrw_lastfile") && a:0 == 0
577"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">")
578    let choice = b:netrw_lastfile
579    let ichoice= ichoice + 1
580
581   else
582    exe "let choice= a:" . ichoice
583"    call Decho("no lastfile: choice<" . choice . ">")
584
585    if match(choice,"?") == 0
586     " give help
587     echomsg 'NetRead Usage:'
588     echomsg ':Nread machine:path                         uses rcp'
589     echomsg ':Nread "machine path"                       uses ftp   with <.netrc>'
590     echomsg ':Nread "machine id password path"           uses ftp'
591     echomsg ':Nread dav://machine[:port]/path            uses cadaver'
592     echomsg ':Nread fetch://machine/path                 uses fetch'
593     echomsg ':Nread ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
594     echomsg ':Nread http://[user@]machine/path           uses http  wget'
595     echomsg ':Nread rcp://[user@]machine/path            uses rcp'
596     echomsg ':Nread rsync://machine[:port]/path          uses rsync'
597     echomsg ':Nread scp://[user@]machine[[:#]port]/path  uses scp'
598     echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
599     sleep 4
600     break
601
602    elseif match(choice,'^"') != -1
603     " Reconstruct Choice if choice starts with '"'
604"     call Decho("reconstructing choice")
605     if match(choice,'"$') != -1
606      " case "..."
607      let choice=strpart(choice,1,strlen(choice)-2)
608     else
609       "  case "... ... ..."
610      let choice      = strpart(choice,1,strlen(choice)-1)
611      let wholechoice = ""
612
613      while match(choice,'"$') == -1
614       let wholechoice = wholechoice . " " . choice
615       let ichoice     = ichoice + 1
616       if ichoice > a:0
617       	if !exists("g:netrw_quiet")
618	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
619	endif
620"        call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
621        return
622       endif
623       let choice= a:{ichoice}
624      endwhile
625      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
626     endif
627    endif
628   endif
629
630"   call Decho("choice<" . choice . ">")
631   let ichoice= ichoice + 1
632
633   " NetRead: Determine method of read (ftp, rcp, etc) {{{3
634   call s:NetrwMethod(choice)
635   if !exists("b:netrw_method") || b:netrw_method < 0
636"    call Dfunc("netrw#NetRead : unsupported method")
637    return
638   endif
639   let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
640
641   " Check if NetrwBrowse() should be handling this request
642"   call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">")
643   if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^http://'
644"    call Decho("yes, choice matches '^.*[\/]$'")
645    keepj call s:NetrwBrowse(0,choice)
646"    call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
647    return
648   endif
649
650   " ============
651   " NetRead: Perform Protocol-Based Read {{{3
652   " ===========================
653   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
654    echo "(netrw) Processing your read request..."
655   endif
656
657   ".........................................
658   " NetRead: (rcp)  NetRead Method #1 {{{3
659   if  b:netrw_method == 1 " read with rcp
660"    call Decho("read via rcp (method #1)")
661   " ER: nothing done with g:netrw_uid yet?
662   " ER: on Win2K" rcp machine[.user]:file tmpfile
663   " ER: if machine contains '.' adding .user is required (use $USERNAME)
664   " ER: the tmpfile is full path: rcp sees C:\... as host C
665   if s:netrw_has_nt_rcp == 1
666    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
667     let uid_machine = g:netrw_machine .'.'. g:netrw_uid
668    else
669     " Any way needed it machine contains a '.'
670     let uid_machine = g:netrw_machine .'.'. $USERNAME
671    endif
672   else
673    if exists("g:netrw_uid") &&	( g:netrw_uid != "" )
674     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
675    else
676     let uid_machine = g:netrw_machine
677    endif
678   endif
679"   call Decho("executing: !".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".shellescape(uid_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1))
680   exe s:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".shellescape(uid_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1)
681   let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
682   let b:netrw_lastfile = choice
683
684   ".........................................
685   " NetRead: (ftp + <.netrc>)  NetRead Method #2 {{{3
686   elseif b:netrw_method  == 2		" read with ftp + <.netrc>
687"     call Decho("read via ftp+.netrc (method #2)")
688     let netrw_fname= b:netrw_fname
689     call s:SaveBufVars()|new|call s:RestoreBufVars()
690     let filtbuf= bufnr("%")
691     setlocal ff=unix
692     keepj put =g:netrw_ftpmode
693"     call Decho("filter input: ".getline(line("$")))
694     if exists("g:netrw_ftpextracmd")
695      keepj put =g:netrw_ftpextracmd
696"      call Decho("filter input: ".getline(line("$")))
697     endif
698     call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
699"     call Decho("filter input: ".getline(line("$")))
700     if exists("g:netrw_port") && g:netrw_port != ""
701"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine." ".g:netrw_port,1))
702      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine." ".g:netrw_port,1)
703     else
704"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
705      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
706     endif
707     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
708     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
709      let debugkeep = &debug
710      setlocal debug=msg
711      call netrw#ErrorMsg(s:ERROR,getline(1),4)
712      let &debug    = debugkeep
713     endif
714     call s:SaveBufVars()
715     bd!
716     if bufname("%") == "" && getline("$") == "" && line('$') == 1
717      " needed when one sources a file in a nolbl setting window via ftp
718      q!
719     endif
720     call s:RestoreBufVars()
721     let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
722     let b:netrw_lastfile = choice
723
724   ".........................................
725   " NetRead: (ftp + machine,id,passwd,filename)  NetRead Method #3 {{{3
726   elseif b:netrw_method == 3		" read with ftp + machine, id, passwd, and fname
727    " Construct execution string (four lines) which will be passed through filter
728"    call Decho("read via ftp+mipf (method #3)")
729    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
730    call s:SaveBufVars()|new|call s:RestoreBufVars()
731    let filtbuf= bufnr("%")
732    setlocal ff=unix
733    if exists("g:netrw_port") && g:netrw_port != ""
734     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
735"     call Decho("filter input: ".getline('.'))
736    else
737     keepj put ='open '.g:netrw_machine
738"     call Decho("filter input: ".getline('.'))
739    endif
740
741    if exists("g:netrw_ftp") && g:netrw_ftp == 1
742     keepj put =g:netrw_uid
743"     call Decho("filter input: ".getline('.'))
744     keepj put ='\"'.s:netrw_passwd.'\"'
745"     call Decho("filter input: ".getline('.'))
746    else
747     keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
748"     call Decho("filter input: ".getline('.'))
749    endif
750
751    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
752     keepj put =g:netrw_ftpmode
753"     call Decho("filter input: ".getline('.'))
754    endif
755    if exists("g:netrw_ftpextracmd")
756     put =g:netrw_ftpextracmd
757"     call Decho("filter input: ".getline('.'))
758    endif
759    keepj put ='get \"'.netrw_fname.'\" '.tmpfile
760"    call Decho("filter input: ".getline('.'))
761
762    " perform ftp:
763    " -i       : turns off interactive prompting from ftp
764    " -n  unix : DON'T use <.netrc>, even though it exists
765    " -n  win32: quit being obnoxious about password
766    norm! 1Gdd
767"    call Decho("executing: %!".g:netrw_ftp_cmd." -i -n")
768    exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
769    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
770    if getline(1) !~ "^$"
771"     call Decho("error<".getline(1).">")
772     if !exists("g:netrw_quiet")
773      call netrw#ErrorMsg(s:ERROR,getline(1),5)
774     endif
775    endif
776    call s:SaveBufVars()|bd!|call s:RestoreBufVars()
777    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
778    let b:netrw_lastfile = choice
779
780   ".........................................
781   " NetRead: (scp) NetRead Method #4 {{{3
782   elseif     b:netrw_method  == 4	" read with scp
783"    call Decho("read via scp (method #4)")
784    if exists("g:netrw_port") && g:netrw_port != ""
785     let useport= " ".g:netrw_scpport." ".g:netrw_port
786    else
787     let useport= ""
788    endif
789"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1))
790    exe s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1)
791    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
792    let b:netrw_lastfile = choice
793
794   ".........................................
795   " NetRead: (http) NetRead Method #5 (wget) {{{3
796   elseif     b:netrw_method  == 5
797"    call Decho("read via http (method #5)")
798    if g:netrw_http_cmd == ""
799     if !exists("g:netrw_quiet")
800      call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
801     endif
802"     call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
803     return
804    endif
805
806    if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
807     " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
808"     call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)")
809     if exists("g:netrw_http_xcmd")
810"      call Decho("exe ".s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape("http://".g:netrw_machine.b:netrw_fname,1)." ".g:netrw_http_xcmd." ".shellescape(tmpfile,1))
811      exe s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape("http://".g:netrw_machine.b:netrw_fname,1)." ".g:netrw_http_xcmd." ".shellescape(tmpfile,1)
812     else
813"      call Decho("exe ".s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape(tmpfile,1)." ".shellescape("http://".g:netrw_machine.b:netrw_fname,1))
814      exe s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape(tmpfile,1)." ".shellescape("http://".g:netrw_machine.b:netrw_fname,1)
815     endif
816     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
817
818    else
819     " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
820"     call Decho(("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)")
821     let netrw_html= substitute(b:netrw_fname,"#.*$","","")
822     let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
823"     call Decho("netrw_html<".netrw_html.">")
824"     call Decho("netrw_tag <".netrw_tag.">")
825"     call Decho("exe ".s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape(tmpfile,1)." ".shellescape("http://".g:netrw_machine.netrw_html,1))
826     exe s:netrw_silentxfer."!".g:netrw_http_cmd." ".shellescape(tmpfile,1)." ".shellescape("http://".g:netrw_machine.netrw_html,1)
827     let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
828"     call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/')
829     exe 'norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
830    endif
831    let b:netrw_lastfile = choice
832    setlocal ro
833
834   ".........................................
835   " NetRead: (dav) NetRead Method #6 {{{3
836   elseif     b:netrw_method  == 6
837"    call Decho("read via cadaver (method #6)")
838
839    if !executable(g:netrw_dav_cmd)
840     call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
841"     call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
842     return
843    endif
844    if g:netrw_dav_cmd =~ "curl"
845"     call Decho("exe ".s:netrw_silentxfer."!".g:netrw_dav_cmd." ".shellescape("dav://".g:netrw_machine.b:netrw_fname,1)." ".shellescape(tmpfile,1))
846     exe s:netrw_silentxfer."!".g:netrw_dav_cmd." ".shellescape("dav://".g:netrw_machine.b:netrw_fname,1)." ".shellescape(tmpfile,1)
847    else
848     " Construct execution string (four lines) which will be passed through filter
849     let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
850     new
851     setlocal ff=unix
852     if exists("g:netrw_port") && g:netrw_port != ""
853      keepj put ='open '.g:netrw_machine.' '.g:netrw_port
854     else
855      keepj put ='open '.g:netrw_machine
856     endif
857     keepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
858     keepj put ='get '.netrw_fname.' '.tmpfile
859     keepj put ='quit'
860
861     " perform cadaver operation:
862     keepj norm! 1Gdd
863"    call Decho("executing: %!".g:netrw_dav_cmd)
864     exe s:netrw_silentxfer."%!".g:netrw_dav_cmd
865     bd!
866    endif
867    let result           = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
868    let b:netrw_lastfile = choice
869
870   ".........................................
871   " NetRead: (rsync) NetRead Method #7 {{{3
872   elseif     b:netrw_method  == 7
873"    call Decho("read via rsync (method #7)")
874"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1))
875    exe s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".shellescape(tmpfile,1)
876    let result		 = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
877    let b:netrw_lastfile = choice
878
879   ".........................................
880   " NetRead: (fetch) NetRead Method #8 {{{3
881   "    fetch://[user@]host[:http]/path
882   elseif     b:netrw_method  == 8
883"    call Decho("read via fetch (method #8)")
884    if g:netrw_fetch_cmd == ""
885     if !exists("g:netrw_quiet")
886      call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
887     endif
888"     call Dret("NetRead")
889    endif
890    if exists("g:netrw_option") && g:netrw_option == ":http"
891     let netrw_option= "http"
892    else
893     let netrw_option= "ftp"
894    endif
895"    call Decho("read via fetch for ".netrw_option)
896
897    if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
898"     call Decho("exe ".s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".shellescape(tmpfile,1)." ".shellescape(netrw_option."://".g:netrw_uid.':'.s:netrw_passwd.'@'.g:netrw_machine."/".b:netrw_fname,1))
899     exe s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".shellescape(tmpfile,1)." ".shellescape(netrw_option."://".g:netrw_uid.':'.s:netrw_passwd.'@'.g:netrw_machine."/".b:netrw_fname,1)
900    else
901"     call Decho("exe ".s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".shellescape(tmpfile,1)." ".shellescape(netrw_option."://".g:netrw_machine."/".b:netrw_fname,1))
902     exe s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".shellescape(tmpfile,1)." ".shellescape(netrw_option."://".g:netrw_machine."/".b:netrw_fname,1)
903    endif
904
905    let result		= s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
906    let b:netrw_lastfile = choice
907    setlocal ro
908
909   ".........................................
910   " NetRead: (sftp) NetRead Method #9 {{{3
911   elseif     b:netrw_method  == 9
912"    call Decho("read via sftp (method #9)")
913"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
914    exe s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile
915    let result		= s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
916    let b:netrw_lastfile = choice
917
918   ".........................................
919   " NetRead: Complain {{{3
920   else
921    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
922   endif
923  endwhile
924
925  " NetRead: cleanup {{{3
926  if exists("b:netrw_method")
927"   call Decho("cleanup b:netrw_method and b:netrw_fname")
928   unlet b:netrw_method
929   unlet b:netrw_fname
930  endif
931  if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
932"   call Decho("cleanup by deleting tmpfile<".tmpfile.">")
933   call s:NetrwDelete(tmpfile)
934  endif
935  call s:NetrwOptionRestore("w:")
936
937"  call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
938endfun
939
940" ------------------------------------------------------------------------
941" netrw#NetWrite: responsible for writing a file over the net {{{2
942fun! netrw#NetWrite(...) range
943"  call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
944
945  " NetWrite: option handling {{{3
946  let mod= 0
947  call s:NetrwOptionSave("w:")
948  call s:NetrwSafeOptions()
949
950  " NetWrite: Get Temporary Filename {{{3
951  let tmpfile= s:GetTempfile("")
952  if tmpfile == ""
953"   call Dret("netrw#NetWrite : unable to get a tempfile!")
954   return
955  endif
956
957  if a:0 == 0
958   let ichoice = 0
959  else
960   let ichoice = 1
961  endif
962
963  let curbufname= expand("%")
964"  call Decho("curbufname<".curbufname.">")
965  if &binary
966   " For binary writes, always write entire file.
967   " (line numbers don't really make sense for that).
968   " Also supports the writing of tar and zip files.
969"   call Decho("(write entire file) silent exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile))
970   exe "silent keepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
971  elseif g:netrw_cygwin
972   " write (selected portion of) file to temporary
973   let cygtmpfile= substitute(tmpfile,'/cygdrive/\(.\)','\1:','')
974"   call Decho("(write selected portion) silent exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile))
975   exe "sil keepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
976  else
977   " write (selected portion of) file to temporary
978"   call Decho("(write selected portion) silent exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile))
979   exe "sil keepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
980  endif
981
982  if curbufname == ""
983   " if the file is [No Name], and one attempts to Nwrite it, the buffer takes
984   " on the temporary file's name.  Deletion of the temporary file during
985   " cleanup then causes an error message.
986   0file!
987  endif
988
989  " NetWrite: while choice loop: {{{3
990  while ichoice <= a:0
991
992   " Process arguments: {{{4
993   " attempt to repeat with previous host-file-etc
994   if exists("b:netrw_lastfile") && a:0 == 0
995"    call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">")
996    let choice = b:netrw_lastfile
997    let ichoice= ichoice + 1
998   else
999    exe "let choice= a:" . ichoice
1000
1001    " Reconstruct Choice if choice starts with '"'
1002    if match(choice,"?") == 0
1003     echomsg 'NetWrite Usage:"'
1004     echomsg ':Nwrite machine:path                        uses rcp'
1005     echomsg ':Nwrite "machine path"                      uses ftp with <.netrc>'
1006     echomsg ':Nwrite "machine id password path"          uses ftp'
1007     echomsg ':Nwrite dav://[user@]machine/path           uses cadaver'
1008     echomsg ':Nwrite fetch://[user@]machine/path         uses fetch'
1009     echomsg ':Nwrite ftp://machine[#port]/path           uses ftp  (autodetects <.netrc>)'
1010     echomsg ':Nwrite rcp://machine/path                  uses rcp'
1011     echomsg ':Nwrite rsync://[user@]machine/path         uses rsync'
1012     echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
1013     echomsg ':Nwrite sftp://[user@]machine/path          uses sftp'
1014     sleep 4
1015     break
1016
1017    elseif match(choice,"^\"") != -1
1018     if match(choice,"\"$") != -1
1019       " case "..."
1020      let choice=strpart(choice,1,strlen(choice)-2)
1021     else
1022      "  case "... ... ..."
1023      let choice      = strpart(choice,1,strlen(choice)-1)
1024      let wholechoice = ""
1025
1026      while match(choice,"\"$") == -1
1027       let wholechoice= wholechoice . " " . choice
1028       let ichoice    = ichoice + 1
1029       if choice > a:0
1030       	if !exists("g:netrw_quiet")
1031	 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
1032	endif
1033"        call Dret("netrw#NetWrite")
1034        return
1035       endif
1036       let choice= a:{ichoice}
1037      endwhile
1038      let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
1039     endif
1040    endif
1041   endif
1042   let ichoice= ichoice + 1
1043"   call Decho("choice<" . choice . "> ichoice=".ichoice)
1044
1045   " Determine method of write (ftp, rcp, etc) {{{4
1046   call s:NetrwMethod(choice)
1047   if !exists("b:netrw_method") || b:netrw_method < 0
1048"    call Dfunc("netrw#NetWrite : unsupported method")
1049    return
1050   endif
1051
1052   " =============
1053   " NetWrite: Perform Protocol-Based Write {{{3
1054   " ============================
1055   if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
1056    echo "(netrw) Processing your write request..."
1057"    call Decho("(netrw) Processing your write request...")
1058   endif
1059
1060   ".........................................
1061   " NetWrite: (rcp) NetWrite Method #1 {{{3
1062   if  b:netrw_method == 1
1063"    call Decho("write via rcp (method #1)")
1064    if s:netrw_has_nt_rcp == 1
1065     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
1066      let uid_machine = g:netrw_machine .'.'. g:netrw_uid
1067     else
1068      let uid_machine = g:netrw_machine .'.'. $USERNAME
1069     endif
1070    else
1071     if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
1072      let uid_machine = g:netrw_uid .'@'. g:netrw_machine
1073     else
1074      let uid_machine = g:netrw_machine
1075     endif
1076    endif
1077"    call Decho("executing: !".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".shellescape(tmpfile,1)." ".shellescape(uid_machine.":".b:netrw_fname,1))
1078    exe s:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".shellescape(tmpfile,1)." ".shellescape(uid_machine.":".b:netrw_fname,1)
1079    let b:netrw_lastfile = choice
1080
1081   ".........................................
1082   " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
1083   elseif b:netrw_method == 2
1084"    call Decho("write via ftp+.netrc (method #2)")
1085    let netrw_fname = b:netrw_fname
1086
1087    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
1088    let bhkeep      = &l:bh
1089    let curbuf      = bufnr("%")
1090    setlocal bh=hide
1091    enew
1092
1093"    call Decho("filter input window#".winnr())
1094    setlocal ff=unix
1095    keepj put =g:netrw_ftpmode
1096"    call Decho("filter input: ".getline('$'))
1097    if exists("g:netrw_ftpextracmd")
1098     keepj put =g:netrw_ftpextracmd
1099"     call Decho("filter input: ".getline("$"))
1100    endif
1101    call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
1102"    call Decho("filter input: ".getline("$"))
1103    if exists("g:netrw_port") && g:netrw_port != ""
1104"     call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1))
1105     exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1)
1106    else
1107"     call Decho("filter input window#".winnr())
1108"     call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
1109     exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
1110    endif
1111    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1112    if getline(1) !~ "^$"
1113     if !exists("g:netrw_quiet")
1114      call netrw#ErrorMsg(s:ERROR,getline(1),14)
1115     endif
1116     let mod=1
1117    endif
1118
1119    " remove enew buffer (quietly)
1120    let filtbuf= bufnr("%")
1121    exe curbuf."b!"
1122    let &l:bh            = bhkeep
1123    exe filtbuf."bw!"
1124
1125    let b:netrw_lastfile = choice
1126
1127   ".........................................
1128   " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
1129   elseif b:netrw_method == 3
1130    " Construct execution string (three or more lines) which will be passed through filter
1131"    call Decho("read via ftp+mipf (method #3)")
1132    let netrw_fname = b:netrw_fname
1133    let bhkeep      = &l:bh
1134
1135    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
1136    let curbuf      = bufnr("%")
1137    setlocal bh=hide
1138    enew
1139    setlocal ff=unix
1140
1141    if exists("g:netrw_port") && g:netrw_port != ""
1142     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
1143"     call Decho("filter input: ".getline('.'))
1144    else
1145     keepj put ='open '.g:netrw_machine
1146"     call Decho("filter input: ".getline('.'))
1147    endif
1148    if exists("g:netrw_ftp") && g:netrw_ftp == 1
1149     keepj put =g:netrw_uid
1150"     call Decho("filter input: ".getline('.'))
1151     keepj put ='\"'.s:netrw_passwd.'\"'
1152"     call Decho("filter input: ".getline('.'))
1153    else
1154     keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1155"     call Decho("filter input: ".getline('.'))
1156    endif
1157    keepj put =g:netrw_ftpmode
1158"    call Decho("filter input: ".getline('$'))
1159    if exists("g:netrw_ftpextracmd")
1160     keepj put =g:netrw_ftpextracmd
1161"     call Decho("filter input: ".getline("$"))
1162    endif
1163    keepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
1164"    call Decho("filter input: ".getline('.'))
1165    " save choice/id/password for future use
1166    let b:netrw_lastfile = choice
1167
1168    " perform ftp:
1169    " -i       : turns off interactive prompting from ftp
1170    " -n  unix : DON'T use <.netrc>, even though it exists
1171    " -n  win32: quit being obnoxious about password
1172    keepj norm! 1Gdd
1173"    call Decho("executing: %!".g:netrw_ftp_cmd." -i -n")
1174    exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
1175    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1176    if getline(1) !~ "^$"
1177     if  !exists("g:netrw_quiet")
1178      call netrw#ErrorMsg(s:ERROR,getline(1),15)
1179     endif
1180     let mod=1
1181    endif
1182
1183    " remove enew buffer (quietly)
1184    let filtbuf= bufnr("%")
1185    exe curbuf."b!"
1186    let &l:bh= bhkeep
1187    exe filtbuf."bw!"
1188
1189   ".........................................
1190   " NetWrite: (scp) NetWrite Method #4 {{{3
1191   elseif     b:netrw_method == 4
1192"    call Decho("write via scp (method #4)")
1193    if exists("g:netrw_port") && g:netrw_port != ""
1194     let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
1195    else
1196     let useport= ""
1197    endif
1198"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".shellescape(tmpfile,1)." ".shellescape(g:netrw_machine.":".b:netrw_fname,1))
1199    exe s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".shellescape(tmpfile,1)." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)
1200    let b:netrw_lastfile = choice
1201
1202   ".........................................
1203   " NetWrite: (http) NetWrite Method #5 {{{3
1204   elseif     b:netrw_method == 5
1205"    call Decho("write via http (method #5)")
1206    if !exists("g:netrw_quiet")
1207     call netrw#ErrorMsg(s:ERROR,"currently <netrw.vim> does not support writing using http:",16)
1208    endif
1209
1210   ".........................................
1211   " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
1212   elseif     b:netrw_method == 6
1213"    call Decho("write via cadaver (method #6)")
1214
1215    " Construct execution string (four lines) which will be passed through filter
1216    let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
1217    let bhkeep      = &l:bh
1218
1219    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
1220    let curbuf      = bufnr("%")
1221    setlocal bh=hide
1222    enew
1223
1224    setlocal ff=unix
1225    if exists("g:netrw_port") && g:netrw_port != ""
1226     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
1227    else
1228     keepj put ='open '.g:netrw_machine
1229    endif
1230    if exists("g:netrw_uid") && exists("s:netrw_passwd")
1231     keepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
1232    endif
1233    keepj put ='put '.tmpfile.' '.netrw_fname
1234
1235    " perform cadaver operation:
1236    keepj norm! 1Gdd
1237"    call Decho("executing: %!".g:netrw_dav_cmd)
1238    exe s:netrw_silentxfer."%!".g:netrw_dav_cmd
1239
1240    " remove enew buffer (quietly)
1241    let filtbuf= bufnr("%")
1242    exe curbuf."b!"
1243    let &l:bh            = bhkeep
1244    exe filtbuf."bw!"
1245
1246    let b:netrw_lastfile = choice
1247
1248   ".........................................
1249   " NetWrite: (rsync) NetWrite Method #7 {{{3
1250   elseif     b:netrw_method == 7
1251"    call Decho("write via rsync (method #7)")
1252"    call Decho("executing: !".g:netrw_rsync_cmd." ".shellescape(tmpfile,1)." ".shellescape(g:netrw_machine.":".b:netrw_fname,1))
1253    exe s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".shellescape(tmpfile,1)." ".shellescape(g:netrw_machine.":".b:netrw_fname,1)
1254    let b:netrw_lastfile = choice
1255
1256   ".........................................
1257   " NetWrite: (sftp) NetWrite Method #9 {{{3
1258   elseif     b:netrw_method == 9
1259"    call Decho("read via sftp (method #9)")
1260    let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
1261    if exists("g:netrw_uid") &&  ( g:netrw_uid != "" )
1262     let uid_machine = g:netrw_uid .'@'. g:netrw_machine
1263    else
1264     let uid_machine = g:netrw_machine
1265    endif
1266
1267    " formerly just a "new...bd!", that changed the window sizes when equalalways.  Using enew workaround instead
1268    let bhkeep = &l:bh
1269    let curbuf = bufnr("%")
1270    setlocal bh=hide
1271    enew
1272
1273    setlocal ff=unix
1274    call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
1275"    call Decho("filter input: ".getline('.'))
1276"    call Decho("executing: %!".g:netrw_sftp_cmd.' '.shellescape(uid_machine,1))
1277    exe s:netrw_silentxfer."%!".g:netrw_sftp_cmd.' '.shellescape(uid_machine,1)
1278    let filtbuf= bufnr("%")
1279    exe curbuf."b!"
1280    let &l:bh            = bhkeep
1281    exe filtbuf."bw!"
1282    let b:netrw_lastfile = choice
1283
1284   ".........................................
1285   " NetWrite: Complain {{{3
1286   else
1287    call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
1288   endif
1289  endwhile
1290
1291  " NetWrite: Cleanup: {{{3
1292"  call Decho("cleanup")
1293  if s:FileReadable(tmpfile)
1294"   call Decho("tmpfile<".tmpfile."> readable, will now delete it")
1295   call s:NetrwDelete(tmpfile)
1296  endif
1297  call s:NetrwOptionRestore("w:")
1298
1299  if a:firstline == 1 && a:lastline == line("$")
1300   " restore modifiability; usually equivalent to set nomod
1301   let &mod= mod
1302  endif
1303
1304  " restore equalalways
1305"  call Dret("netrw#NetWrite")
1306endfun
1307
1308" ---------------------------------------------------------------------
1309" netrw#NetSource: source a remotely hosted vim script {{{2
1310" uses NetRead to get a copy of the file into a temporarily file,
1311"              then sources that file,
1312"              then removes that file.
1313fun! netrw#NetSource(...)
1314"  call Dfunc("netrw#NetSource() a:0=".a:0)
1315  if a:0 > 0 && a:1 == '?'
1316   " give help
1317   echomsg 'NetSource Usage:'
1318   echomsg ':Nsource dav://machine[:port]/path            uses cadaver'
1319   echomsg ':Nsource fetch://machine/path                 uses fetch'
1320   echomsg ':Nsource ftp://[user@]machine[:port]/path     uses ftp   autodetects <.netrc>'
1321   echomsg ':Nsource http://[user@]machine/path           uses http  wget'
1322   echomsg ':Nsource rcp://[user@]machine/path            uses rcp'
1323   echomsg ':Nsource rsync://machine[:port]/path          uses rsync'
1324   echomsg ':Nsource scp://[user@]machine[[:#]port]/path  uses scp'
1325   echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
1326   sleep 4
1327  else
1328   let i= 1
1329   while i <= a:0
1330    call netrw#NetRead(3,a:{i})
1331"    call Decho("(netrw#NetSource) s:netread_tmpfile<".s:netrw_tmpfile.">")
1332    if s:FileReadable(s:netrw_tmpfile)
1333"     call Decho("(netrw#NetSource) exe so ".fnameescape(s:netrw_tmpfile))
1334     exe "so ".fnameescape(s:netrw_tmpfile)
1335"     call Decho("(netrw#NetSource) delete(".s:netrw_tmpfile.")")
1336     call delete(s:netrw_tmpfile)
1337     unlet s:netrw_tmpfile
1338    else
1339     call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
1340    endif
1341    let i= i + 1
1342   endwhile
1343  endif
1344"  call Dret("netrw#NetSource")
1345endfun
1346
1347" ===========================================
1348" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
1349"    readcmd == %r : replace buffer with newly read file
1350"            == 0r : read file at top of buffer
1351"            == r  : read file after current line
1352"            == t  : leave file in temporary form (ie. don't read into buffer)
1353fun! s:NetrwGetFile(readcmd, tfile, method)
1354"  call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
1355
1356  " readcmd=='t': simply do nothing
1357  if a:readcmd == 't'
1358"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
1359"   call Dret("NetrwGetFile : skip read of <".a:tfile.">")
1360   return
1361  endif
1362
1363  " get name of remote filename (ie. url and all)
1364  let rfile= bufname("%")
1365"  call Decho("rfile<".rfile.">")
1366
1367  if exists("*NetReadFixup")
1368   " for the use of NetReadFixup (not otherwise used internally)
1369   let line2= line("$")
1370  endif
1371
1372  if a:readcmd[0] == '%'
1373  " get file into buffer
1374"   call Decho("get file into buffer")
1375
1376   " rename the current buffer to the temp file (ie. tfile)
1377   if g:netrw_cygwin
1378    let tfile= substitute(a:tfile,'/cygdrive/\(.\)','\1:','')
1379   else
1380    let tfile= a:tfile
1381   endif
1382"   call Decho("exe sil! keepalt file ".fnameescape(tfile))
1383   exe "sil! keepalt file ".fnameescape(tfile)
1384
1385   " edit temporary file (ie. read the temporary file in)
1386   if     rfile =~ '\.zip$'
1387"    call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)")
1388    call zip#Browse(tfile)
1389   elseif rfile =~ '\.tar$'
1390"    call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)")
1391    call tar#Browse(tfile)
1392   elseif rfile =~ '\.tar\.gz$'
1393"    call Decho("handling remote gzip-compressed tar file")
1394    call tar#Browse(tfile)
1395   elseif rfile =~ '\.tar\.bz2$'
1396"    call Decho("handling remote bz2-compressed tar file")
1397    call tar#Browse(tfile)
1398   elseif rfile =~ '\.tar\.xz$'
1399"    call Decho("handling remote xz-compressed tar file")
1400    call tar#Browse(tfile)
1401   elseif rfile =~ '\.txz$'
1402"    call Decho("handling remote xz-compressed tar file (.txz)")
1403    call tar#Browse(tfile)
1404   else
1405"    call Decho("edit temporary file")
1406    e!
1407   endif
1408
1409   " rename buffer back to remote filename
1410"   call Decho("exe sil! keepalt file ".fnameescape(rfile))
1411   exe "sil! keepalt file ".fnameescape(rfile)
1412   filetype detect
1413"   call Dredir("renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">","ls!")
1414   let line1 = 1
1415   let line2 = line("$")
1416
1417  elseif s:FileReadable(a:tfile)
1418   " read file after current line
1419"   call Decho("read file<".a:tfile."> after current line")
1420   let curline = line(".")
1421   let lastline= line("$")
1422"   call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile).">  line#".curline)
1423   exe a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
1424   let line1= curline + 1
1425   let line2= line("$") - lastline + 1
1426
1427  else
1428   " not readable
1429"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
1430"   call Decho("tfile<".a:tfile."> not readable")
1431   call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
1432"   call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
1433   return
1434  endif
1435
1436  " User-provided (ie. optional) fix-it-up command
1437  if exists("*NetReadFixup")
1438"   call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")")
1439   call NetReadFixup(a:method, line1, line2)
1440"  else " Decho
1441"   call Decho("NetReadFixup() not called, doesn't exist  (line1=".line1." line2=".line2.")")
1442  endif
1443
1444  if has("gui") && has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
1445   " update the Buffers menu
1446   call s:UpdateBuffersMenu()
1447  endif
1448
1449"  call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile))
1450
1451 " make sure file is being displayed
1452"  redraw!
1453
1454"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
1455"  call Dret("NetrwGetFile")
1456endfun
1457
1458" ------------------------------------------------------------------------
1459" s:NetrwMethod:  determine method of transfer {{{2
1460" Input:
1461"   choice = url   [protocol:]//[userid@]hostname[:port]/[path-to-file]
1462" Output:
1463"  b:netrw_method= 1: rcp                                             
1464"                  2: ftp + <.netrc>                                  
1465"	           3: ftp + machine, id, password, and [path]filename 
1466"	           4: scp                                             
1467"	           5: http (wget)                                     
1468"	           6: dav
1469"	           7: rsync                                           
1470"	           8: fetch                                           
1471"	           9: sftp                                            
1472"  g:netrw_machine= hostname
1473"  b:netrw_fname  = filename
1474"  g:netrw_port   = optional port number (for ftp)
1475"  g:netrw_choice = copy of input url (choice)
1476fun! s:NetrwMethod(choice)
1477"   call Dfunc("NetrwMethod(a:choice<".a:choice.">)")
1478
1479   " record current g:netrw_machine, if any
1480   " curmachine used if protocol == ftp and no .netrc
1481   if exists("g:netrw_machine")
1482    let curmachine= g:netrw_machine
1483"    call Decho("curmachine<".curmachine.">")
1484   else
1485    let curmachine= "N O T A HOST"
1486   endif
1487
1488  " initialization
1489  let b:netrw_method  = 0
1490  let g:netrw_machine = ""
1491  let b:netrw_fname   = ""
1492  let g:netrw_port    = ""
1493  let g:netrw_choice  = a:choice
1494
1495  " Patterns:
1496  " mipf     : a:machine a:id password filename	     Use ftp
1497  " mf	    : a:machine filename		     Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
1498  " ftpurm   : ftp://[user@]host[[#:]port]/filename  Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
1499  " rcpurm   : rcp://[user@]host/filename	     Use rcp
1500  " rcphf    : [user@]host:filename		     Use rcp
1501  " scpurm   : scp://[user@]host[[#:]port]/filename  Use scp
1502  " httpurm  : http://[user@]host/filename	     Use wget
1503  " davurm   : dav[s]://host[:port]/path             Use cadaver/curl
1504  " rsyncurm : rsync://host[:port]/path              Use rsync
1505  " fetchurm : fetch://[user@]host[:http]/filename   Use fetch (defaults to ftp, override for http)
1506  " sftpurm  : sftp://[user@]host/filename  Use scp
1507  let mipf     = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
1508  let mf       = '^\(\S\+\)\s\+\(\S\+\)$'
1509  let ftpurm   = '^ftp://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
1510  let rcpurm   = '^rcp://\%(\([^/@]\{-}\)@\)\=\([^/]\{-}\)/\(.*\)$'
1511  let rcphf    = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
1512  let scpurm   = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
1513  let httpurm  = '^http://\([^/]\{-}\)\(/.*\)\=$'
1514  let davurm   = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
1515  let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
1516  let fetchurm = '^fetch://\(\([^/@]\{-}\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
1517  let sftpurm  = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
1518
1519"  call Decho("determine method:")
1520  " Determine Method
1521  " rcp://user@hostname/...path-to-file
1522  if match(a:choice,rcpurm) == 0
1523"   call Decho("rcp://...")
1524   let b:netrw_method  = 1
1525   let userid          = substitute(a:choice,rcpurm,'\1',"")
1526   let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
1527   let b:netrw_fname   = substitute(a:choice,rcpurm,'\3',"")
1528   if userid != ""
1529    let g:netrw_uid= userid
1530   endif
1531
1532  " scp://user@hostname/...path-to-file
1533  elseif match(a:choice,scpurm) == 0
1534"   call Decho("scp://...")
1535   let b:netrw_method  = 4
1536   let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
1537   let g:netrw_port    = substitute(a:choice,scpurm,'\2',"")
1538   let b:netrw_fname   = substitute(a:choice,scpurm,'\3',"")
1539
1540  " http://user@hostname/...path-to-file
1541  elseif match(a:choice,httpurm) == 0
1542"   call Decho("http://...")
1543   let b:netrw_method = 5
1544   let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
1545   let b:netrw_fname  = substitute(a:choice,httpurm,'\2',"")
1546
1547  " dav://hostname[:port]/..path-to-file..
1548  elseif match(a:choice,davurm) == 0
1549"   call Decho("dav://...")
1550   let b:netrw_method= 6
1551   if a:choice =~ '^s'
1552    let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
1553   else
1554    let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
1555   endif
1556   let b:netrw_fname  = substitute(a:choice,davurm,'\3',"")
1557
1558  " rsync://user@hostname/...path-to-file
1559  elseif match(a:choice,rsyncurm) == 0
1560"   call Decho("rsync://...")
1561   let b:netrw_method = 7
1562   let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
1563   let b:netrw_fname  = substitute(a:choice,rsyncurm,'\2',"")
1564
1565  " ftp://[user@]hostname[[:#]port]/...path-to-file
1566  elseif match(a:choice,ftpurm) == 0
1567"   call Decho("ftp://...")
1568   let userid	      = substitute(a:choice,ftpurm,'\2',"")
1569   let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
1570   let g:netrw_port   = substitute(a:choice,ftpurm,'\4',"")
1571   let b:netrw_fname  = substitute(a:choice,ftpurm,'\5',"")
1572"   call Decho("g:netrw_machine<".g:netrw_machine.">")
1573   if userid != ""
1574    let g:netrw_uid= userid
1575   endif
1576   if exists("s:netrw_passwd") && curmachine != g:netrw_machine
1577    " if there's a change in hostname, require password re-entry
1578    unlet s:netrw_passwd
1579   endif
1580   if exists("g:netrw_uid") && exists("s:netrw_passwd")
1581    let b:netrw_method = 3
1582   else
1583    if s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
1584     let b:netrw_method= 2
1585    else
1586     if !exists("g:netrw_uid") || g:netrw_uid == ""
1587      call NetUserPass()
1588     elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
1589      call NetUserPass(g:netrw_uid)
1590    " else just use current g:netrw_uid and s:netrw_passwd
1591     endif
1592     let b:netrw_method= 3
1593    endif
1594   endif
1595
1596  elseif match(a:choice,fetchurm) == 0
1597"   call Decho("fetch://...")
1598   let b:netrw_method = 8
1599   let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
1600   let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
1601   let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
1602   let b:netrw_fname  = substitute(a:choice,fetchurm,'\5',"")
1603
1604  " Issue an ftp : "machine id password [path/]filename"
1605  elseif match(a:choice,mipf) == 0
1606"   call Decho("(ftp) host id pass file")
1607   let b:netrw_method  = 3
1608   let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
1609   let g:netrw_uid     = substitute(a:choice,mipf,'\2',"")
1610   let s:netrw_passwd  = substitute(a:choice,mipf,'\3',"")
1611   let b:netrw_fname   = substitute(a:choice,mipf,'\4',"")
1612
1613  " Issue an ftp: "hostname [path/]filename"
1614  elseif match(a:choice,mf) == 0
1615"   call Decho("(ftp) host file")
1616   if exists("g:netrw_uid") && exists("s:netrw_passwd")
1617    let b:netrw_method  = 3
1618    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
1619    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
1620
1621   elseif s:FileReadable(expand("$HOME/.netrc"))
1622    let b:netrw_method  = 2
1623    let g:netrw_machine = substitute(a:choice,mf,'\1',"")
1624    let b:netrw_fname   = substitute(a:choice,mf,'\2',"")
1625   endif
1626
1627  " sftp://user@hostname/...path-to-file
1628  elseif match(a:choice,sftpurm) == 0
1629"   call Decho("sftp://...")
1630   let b:netrw_method = 9
1631   let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
1632   let b:netrw_fname  = substitute(a:choice,sftpurm,'\2',"")
1633
1634  " Issue an rcp: hostname:filename"  (this one should be last)
1635  elseif match(a:choice,rcphf) == 0
1636"   call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">")
1637   let b:netrw_method  = 1
1638   let userid          = substitute(a:choice,rcphf,'\2',"")
1639   let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
1640   let b:netrw_fname   = substitute(a:choice,rcphf,'\4',"")
1641"   call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">")
1642"   call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">")
1643"   call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">")
1644"   call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">")
1645   if userid != ""
1646    let g:netrw_uid= userid
1647   endif
1648
1649  else
1650   if !exists("g:netrw_quiet")
1651    call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
1652   endif
1653   let b:netrw_method  = -1
1654  endif
1655
1656  " remove any leading [:#] from port number
1657  if g:netrw_port != ""
1658    let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
1659  endif
1660
1661"  call Decho("a:choice       <".a:choice.">")
1662"  call Decho("b:netrw_method <".b:netrw_method.">")
1663"  call Decho("g:netrw_machine<".g:netrw_machine.">")
1664"  call Decho("g:netrw_port   <".g:netrw_port.">")
1665"  if exists("g:netrw_uid")		"Decho
1666"   call Decho("g:netrw_uid    <".g:netrw_uid.">")
1667"  endif					"Decho
1668"  if exists("s:netrw_passwd")		"Decho
1669"   call Decho("s:netrw_passwd <".s:netrw_passwd.">")
1670"  endif					"Decho
1671"  call Decho("b:netrw_fname  <".b:netrw_fname.">")
1672"  call Dret("NetrwMethod : b:netrw_method=".b:netrw_method)
1673endfun
1674
1675" ------------------------------------------------------------------------
1676" NetReadFixup: this sort of function is typically written by the user {{{2
1677"               to handle extra junk that their system's ftp dumps
1678"               into the transfer.  This function is provided as an
1679"               example and as a fix for a Windows 95 problem: in my
1680"               experience, win95's ftp always dumped four blank lines
1681"               at the end of the transfer.
1682if has("win95") && exists("g:netrw_win95ftp") && g:netrw_win95ftp
1683 fun! NetReadFixup(method, line1, line2)
1684"   call Dfunc("NetReadFixup(method<".a:method."> line1=".a:line1." line2=".a:line2.")")
1685
1686   " sanity checks -- attempt to convert inputs to integers
1687   let method = a:method + 0
1688   let line1  = a:line1 + 0
1689   let line2  = a:line2 + 0
1690   if type(method) != 0 || type(line1) != 0 || type(line2) != 0 || method < 0 || line1 <= 0 || line2 <= 0
1691"    call Dret("NetReadFixup")
1692    return
1693   endif
1694
1695   if method == 3   " ftp (no <.netrc>)
1696    let fourblanklines= line2 - 3
1697    if fourblanklines >= line1
1698     exe "sil keepj ".fourblanklines.",".line2."g/^\s*$/d"
1699     call histdel("/",-1)
1700    endif
1701   endif
1702
1703"   call Dret("NetReadFixup")
1704 endfun
1705endif
1706
1707" ---------------------------------------------------------------------
1708" NetUserPass: set username and password for subsequent ftp transfer {{{2
1709"   Usage:  :call NetUserPass()			-- will prompt for userid and password
1710"	    :call NetUserPass("uid")		-- will prompt for password
1711"	    :call NetUserPass("uid","password") -- sets global userid and password
1712fun! NetUserPass(...)
1713
1714 " get/set userid
1715 if a:0 == 0
1716"  call Dfunc("NetUserPass(a:0<".a:0.">)")
1717  if !exists("g:netrw_uid") || g:netrw_uid == ""
1718   " via prompt
1719   let g:netrw_uid= input('Enter username: ')
1720  endif
1721 else	" from command line
1722"  call Dfunc("NetUserPass(a:1<".a:1.">)")
1723  let g:netrw_uid= a:1
1724 endif
1725
1726 " get password
1727 if a:0 <= 1 " via prompt
1728"  call Decho("a:0=".a:0." case <=1:")
1729  let s:netrw_passwd= inputsecret("Enter Password: ")
1730 else " from command line
1731"  call Decho("a:0=".a:0." case >1: a:2<".a:2.">")
1732  let s:netrw_passwd=a:2
1733 endif
1734
1735"  call Dret("NetUserPass")
1736endfun
1737
1738" ===========================================
1739"  Shared Browsing Support:    {{{1
1740" ===========================================
1741
1742" ---------------------------------------------------------------------
1743" s:BrowserMaps: {{{2
1744fun! s:BrowserMaps(islocal)
1745"  call Dfunc("s:BrowserMaps(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
1746  if a:islocal
1747"   call Decho("make local maps")
1748   nnoremap <buffer> <silent> <cr>	:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
1749   nnoremap <buffer> <silent> -		:exe "norm! 0"<bar>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,'../'))<cr>
1750   nnoremap <buffer> <silent> a		:call <SID>NetrwHide(1)<cr>
1751   nnoremap <buffer> <silent> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
1752   nnoremap <buffer> <silent> mc	:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
1753   nnoremap <buffer> <silent> md	:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
1754   nnoremap <buffer> <silent> me	:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
1755   nnoremap <buffer> <silent> mf	:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1756   nnoremap <buffer> <silent> mg	:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
1757   nnoremap <buffer> <silent> mh	:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
1758   nnoremap <buffer> <silent> mm	:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
1759   nnoremap <buffer> <silent> mp	:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
1760   nnoremap <buffer> <silent> mr	:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
1761   nnoremap <buffer> <silent> ms	:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
1762   nnoremap <buffer> <silent> mT	:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
1763   nnoremap <buffer> <silent> mt	:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
1764   nnoremap <buffer> <silent> mu	:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
1765   nnoremap <buffer> <silent> mx	:<c-u>call <SID>NetrwMarkFileExe(1)<cr>
1766   nnoremap <buffer> <silent> mz	:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
1767   nnoremap <buffer> <silent> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
1768   nnoremap <buffer> <silent> gh	:<c-u>call <SID>NetrwHidden(1)<cr>
1769   nnoremap <buffer> <silent> gp	:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
1770   nnoremap <buffer> <silent> c		:exe "keepjumps lcd ".fnameescape(b:netrw_curdir)<cr>
1771   nnoremap <buffer> <silent> C		:let g:netrw_chgwin= winnr()<cr>
1772   nnoremap <buffer> <silent> d		:call <SID>NetrwMakeDir("")<cr>
1773   nnoremap <buffer> <silent> i		:call <SID>NetrwListStyle(1)<cr>
1774   nnoremap <buffer> <silent> I		:call <SID>NetrwBannerCtrl(1)<cr>
1775   nnoremap <buffer> <silent> o		:call <SID>NetrwSplit(3)<cr>
1776   nnoremap <buffer> <silent> O		:call <SID>NetrwObtain(1)<cr>
1777   nnoremap <buffer> <silent> p		:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
1778   nnoremap <buffer> <silent> P		:call <SID>NetrwPrevWinOpen(1)<cr>
1779   nnoremap <buffer> <silent> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
1780   nnoremap <buffer> <silent> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
1781   nnoremap <buffer> <silent> qf	:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
1782   nnoremap <buffer> <silent> r		: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>
1783   nnoremap <buffer> <silent> s		:call <SID>NetrwSortStyle(1)<cr>
1784   nnoremap <buffer> <silent> S		:call <SID>NetSortSequence(1)<cr>
1785   nnoremap <buffer> <silent> t		:call <SID>NetrwSplit(4)<cr>
1786   nnoremap <buffer> <silent> T		:call <SID>NetrwSplit(4)<bar>norm! gT<cr>
1787   nnoremap <buffer> <silent> u		:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
1788   nnoremap <buffer> <silent> U		:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
1789   nnoremap <buffer> <silent> v		:call <SID>NetrwSplit(5)<cr>
1790   nnoremap <buffer> <silent> x		:call netrw#NetrwBrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
1791   nnoremap <buffer> <silent> %		:call <SID>NetrwOpenFile(1)<cr>
1792   inoremap <buffer> <silent> <cr>	<c-o>:call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord()))<cr>
1793   inoremap <buffer> <silent> -		<c-o>:exe "norm! 0"<bar>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,'../'))<cr>
1794   inoremap <buffer> <silent> a		<c-o>:call <SID>NetrwHide(1)<cr>
1795   inoremap <buffer> <silent> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
1796   inoremap <buffer> <silent> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
1797   inoremap <buffer> <silent> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
1798   inoremap <buffer> <silent> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
1799   inoremap <buffer> <silent> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1800   inoremap <buffer> <silent> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
1801   inoremap <buffer> <silent> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
1802   inoremap <buffer> <silent> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(1)<cr>
1803   inoremap <buffer> <silent> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
1804   inoremap <buffer> <silent> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
1805   inoremap <buffer> <silent> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(1)<cr>
1806   inoremap <buffer> <silent> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(1)<cr>
1807   inoremap <buffer> <silent> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
1808   inoremap <buffer> <silent> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(1)<cr>
1809   inoremap <buffer> <silent> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(1)<cr>
1810   inoremap <buffer> <silent> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
1811   inoremap <buffer> <silent> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
1812   inoremap <buffer> <silent> gh	<c-o>:<c-u>call <SID>NetrwHidden(1)<cr>
1813   inoremap <buffer> <silent> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
1814   inoremap <buffer> <silent> c		<c-o>:exe "keepjumps lcd ".fnameescape(b:netrw_curdir)<cr>
1815   inoremap <buffer> <silent> C		<c-o>:let g:netrw_chgwin= winnr()<cr>
1816   inoremap <buffer> <silent> d		<c-o>:call <SID>NetrwMakeDir("")<cr>
1817   inoremap <buffer> <silent> i		<c-o>:call <SID>NetrwListStyle(1)<cr>
1818   inoremap <buffer> <silent> I		<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
1819   inoremap <buffer> <silent> o		<c-o>:call <SID>NetrwSplit(3)<cr>
1820   inoremap <buffer> <silent> O		<c-o>:call <SID>NetrwObtain(1)<cr>
1821   inoremap <buffer> <silent> p		<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
1822   inoremap <buffer> <silent> P		<c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
1823   inoremap <buffer> <silent> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
1824   inoremap <buffer> <silent> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
1825   inoremap <buffer> <silent> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
1826   inoremap <buffer> <silent> 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>
1827   inoremap <buffer> <silent> s		<c-o>:call <SID>NetrwSortStyle(1)<cr>
1828   inoremap <buffer> <silent> S		<c-o>:call <SID>NetSortSequence(1)<cr>
1829   inoremap <buffer> <silent> t		<c-o>:call <SID>NetrwSplit(4)<cr>
1830   inoremap <buffer> <silent> T		<c-o>:call <SID>NetrwSplit(4)<bar>norm! gT<cr>
1831   inoremap <buffer> <silent> u		<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
1832   inoremap <buffer> <silent> U		<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
1833   inoremap <buffer> <silent> v		<c-o>:call <SID>NetrwSplit(5)<cr>
1834   inoremap <buffer> <silent> x		<c-o>:call netrw#NetrwBrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),0),0)"<cr>
1835   inoremap <buffer> <silent> %		<c-o>:call <SID>NetrwOpenFile(1)<cr>
1836   if !hasmapto('<Plug>NetrwHideEdit')
1837    nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
1838    imap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
1839   endif
1840   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(1)<cr>
1841   if !hasmapto('<Plug>NetrwRefresh')
1842    nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
1843    imap <buffer> <unique> <c-l> <Plug>NetrwRefresh
1844   endif
1845   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./'))<cr>
1846   if s:didstarstar || !mapcheck("<s-down>","n")
1847    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
1848    inoremap <buffer> <silent> <s-down>	:Nexplore<cr>
1849   endif
1850   if s:didstarstar || !mapcheck("<s-up>","n")
1851    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
1852    inoremap <buffer> <silent> <s-up>	:Pexplore<cr>
1853   endif
1854   let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
1855   if g:netrw_mousemaps == 1
1856    nnoremap <buffer> <silent> <leftmouse>   <leftmouse>:call <SID>NetrwLeftmouse(1)<cr>
1857    nnoremap <buffer> <silent> <middlemouse> <leftmouse>:call <SID>NetrwPrevWinOpen(1)<cr>
1858    nnoremap <buffer> <silent> <s-leftmouse> <leftmouse>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1859    exe 'nnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1860    exe 'vnoremap <buffer> <silent> <rightmouse>  <leftmouse>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1861    inoremap <buffer> <silent> <leftmouse>   <c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(1)<cr>
1862    inoremap <buffer> <silent> <middlemouse> <c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(1)<cr>
1863    inoremap <buffer> <silent> <s-leftmouse> <c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
1864    exe 'inoremap <buffer> <silent> <rightmouse>  <c-o><leftmouse><c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1865   endif
1866   exe 'nnoremap <buffer> <silent> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1867   exe 'nnoremap <buffer> <silent> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1868   exe 'nnoremap <buffer> <silent> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
1869   exe 'nnoremap <buffer> <silent> <Leader>m	:call <SID>NetrwMakeDir("")<cr>'
1870   exe 'vnoremap <buffer> <silent> <del>	:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1871   exe 'vnoremap <buffer> <silent> D		:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1872   exe 'vnoremap <buffer> <silent> R		:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
1873   exe 'inoremap <buffer> <silent> <del>	<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1874   exe 'inoremap <buffer> <silent> D		<c-o>:call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
1875   exe 'inoremap <buffer> <silent> R		<c-o>:call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
1876   exe 'inoremap <buffer> <silent> <Leader>m	<c-o>:call <SID>NetrwMakeDir("")<cr>'
1877   nnoremap <buffer> <F1>		:he netrw-quickhelp<cr>
1878
1879  else " remote
1880"   call Decho("make remote maps")
1881   call s:RemotePathAnalysis(b:netrw_curdir)
1882   nnoremap <buffer> <silent> <cr>	:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
1883   nnoremap <buffer> <silent> <c-l>	:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
1884   nnoremap <buffer> <silent> -		:exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'../'))<cr>
1885   nnoremap <buffer> <silent> a		:call <SID>NetrwHide(0)<cr>
1886   nnoremap <buffer> <silent> mb	:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
1887   nnoremap <buffer> <silent> mc	:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
1888   nnoremap <buffer> <silent> md	:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
1889   nnoremap <buffer> <silent> me	:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
1890   nnoremap <buffer> <silent> mf	:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
1891   nnoremap <buffer> <silent> mg	:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
1892   nnoremap <buffer> <silent> mh	:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
1893   nnoremap <buffer> <silent> mm	:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
1894   nnoremap <buffer> <silent> mp	:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
1895   nnoremap <buffer> <silent> mr	:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
1896   nnoremap <buffer> <silent> ms	:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
1897   nnoremap <buffer> <silent> mT	:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
1898   nnoremap <buffer> <silent> mt	:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
1899   nnoremap <buffer> <silent> mu	:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
1900   nnoremap <buffer> <silent> mx	:<c-u>call <SID>NetrwMarkFileExe(0)<cr>
1901   nnoremap <buffer> <silent> mz	:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
1902   nnoremap <buffer> <silent> gb	:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_cur)<cr>
1903   nnoremap <buffer> <silent> gh	:<c-u>call <SID>NetrwHidden(0)<cr>
1904   nnoremap <buffer> <silent> gp	:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
1905   nnoremap <buffer> <silent> C		:let g:netrw_chgwin= winnr()<cr>
1906   nnoremap <buffer> <silent> i		:call <SID>NetrwListStyle(0)<cr>
1907   nnoremap <buffer> <silent> I		:call <SID>NetrwBannerCtrl(1)<cr>
1908   nnoremap <buffer> <silent> o		:call <SID>NetrwSplit(0)<cr>
1909   nnoremap <buffer> <silent> O		:call <SID>NetrwObtain(0)<cr>
1910   nnoremap <buffer> <silent> p		:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
1911   nnoremap <buffer> <silent> P		:call <SID>NetrwPrevWinOpen(0)<cr>
1912   nnoremap <buffer> <silent> qb	:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
1913   nnoremap <buffer> <silent> mB	:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
1914   nnoremap <buffer> <silent> qf	:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
1915   nnoremap <buffer> <silent> r		: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>
1916   nnoremap <buffer> <silent> s		:call <SID>NetrwSortStyle(0)<cr>
1917   nnoremap <buffer> <silent> S		:call <SID>NetSortSequence(0)<cr>
1918   nnoremap <buffer> <silent> t		:call <SID>NetrwSplit(1)<cr>
1919   nnoremap <buffer> <silent> T		:call <SID>NetrwSplit(1)<bar>norm! gT<cr>
1920   nnoremap <buffer> <silent> u		:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
1921   nnoremap <buffer> <silent> U		:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
1922   nnoremap <buffer> <silent> v		:call <SID>NetrwSplit(2)<cr>
1923   nnoremap <buffer> <silent> x		:call netrw#NetrwBrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
1924   nnoremap <buffer> <silent> %		:call <SID>NetrwOpenFile(0)<cr>
1925   inoremap <buffer> <silent> <cr>	<c-o>:call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()))<cr>
1926   inoremap <buffer> <silent> <c-l>	<c-o>:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
1927   inoremap <buffer> <silent> -		<c-o>:exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'../'))<cr>
1928   inoremap <buffer> <silent> a		<c-o>:call <SID>NetrwHide(0)<cr>
1929   inoremap <buffer> <silent> mb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
1930   inoremap <buffer> <silent> mc	<c-o>:<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
1931   inoremap <buffer> <silent> md	<c-o>:<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
1932   inoremap <buffer> <silent> me	<c-o>:<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
1933   inoremap <buffer> <silent> mf	<c-o>:<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
1934   inoremap <buffer> <silent> mg	<c-o>:<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
1935   inoremap <buffer> <silent> mh	<c-o>:<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
1936   inoremap <buffer> <silent> mm	<c-o>:<c-u>call <SID>NetrwMarkFileMove(0)<cr>
1937   inoremap <buffer> <silent> mp	<c-o>:<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
1938   inoremap <buffer> <silent> mr	<c-o>:<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
1939   inoremap <buffer> <silent> ms	<c-o>:<c-u>call <SID>NetrwMarkFileSource(0)<cr>
1940   inoremap <buffer> <silent> mT	<c-o>:<c-u>call <SID>NetrwMarkFileTag(0)<cr>
1941   inoremap <buffer> <silent> mt	<c-o>:<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
1942   inoremap <buffer> <silent> mu	<c-o>:<c-u>call <SID>NetrwUnMarkFile(0)<cr>
1943   inoremap <buffer> <silent> mx	<c-o>:<c-u>call <SID>NetrwMarkFileExe(0)<cr>
1944   inoremap <buffer> <silent> mz	<c-o>:<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
1945   inoremap <buffer> <silent> gb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_cur)<cr>
1946   inoremap <buffer> <silent> gh	<c-o>:<c-u>call <SID>NetrwHidden(0)<cr>
1947   inoremap <buffer> <silent> gp	<c-o>:<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
1948   inoremap <buffer> <silent> C		<c-o>:let g:netrw_chgwin= winnr()<cr>
1949   inoremap <buffer> <silent> i		<c-o>:call <SID>NetrwListStyle(0)<cr>
1950   inoremap <buffer> <silent> I		<c-o>:call <SID>NetrwBannerCtrl(1)<cr>
1951   inoremap <buffer> <silent> o		<c-o>:call <SID>NetrwSplit(0)<cr>
1952   inoremap <buffer> <silent> O		<c-o>:call <SID>NetrwObtain(0)<cr>
1953   inoremap <buffer> <silent> p		<c-o>:call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
1954   inoremap <buffer> <silent> P		<c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
1955   inoremap <buffer> <silent> qb	<c-o>:<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
1956   inoremap <buffer> <silent> mB	<c-o>:<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
1957   inoremap <buffer> <silent> qf	<c-o>:<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
1958   inoremap <buffer> <silent> 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>
1959   inoremap <buffer> <silent> s		<c-o>:call <SID>NetrwSortStyle(0)<cr>
1960   inoremap <buffer> <silent> S		<c-o>:call <SID>NetSortSequence(0)<cr>
1961   inoremap <buffer> <silent> t		<c-o>:call <SID>NetrwSplit(1)<cr>
1962   inoremap <buffer> <silent> T		<c-o>:call <SID>NetrwSplit(1)<bar>norm! gT<cr>
1963   inoremap <buffer> <silent> u		<c-o>:<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
1964   inoremap <buffer> <silent> U		<c-o>:<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
1965   inoremap <buffer> <silent> v		<c-o>:call <SID>NetrwSplit(2)<cr>
1966   inoremap <buffer> <silent> x		<c-o>:call netrw#NetrwBrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
1967   inoremap <buffer> <silent> %		<c-o>:call <SID>NetrwOpenFile(0)<cr>
1968   if !hasmapto('<Plug>NetrwHideEdit')
1969    nmap <buffer> <c-h> <Plug>NetrwHideEdit
1970    imap <buffer> <c-h> <Plug>NetrwHideEdit
1971   endif
1972   nnoremap <buffer> <silent> <Plug>NetrwHideEdit	:call <SID>NetrwHideEdit(0)<cr>
1973   if !hasmapto('<Plug>NetrwRefresh')
1974    nmap <buffer> <c-l> <Plug>NetrwRefresh
1975    imap <buffer> <c-l> <Plug>NetrwRefresh
1976   endif
1977
1978   let mapsafepath     = escape(s:path, s:netrw_map_escape)
1979   let mapsafeusermach = escape(s:user.s:machine, s:netrw_map_escape)
1980
1981   nnoremap <buffer> <silent> <Plug>NetrwRefresh		:call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./'))<cr>
1982   if g:netrw_mousemaps == 1
1983    nnoremap <buffer> <silent> <leftmouse>   <leftmouse>:call <SID>NetrwLeftmouse(0)<cr>
1984    nnoremap <buffer> <silent> <middlemouse> <leftmouse>:call <SID>NetrwPrevWinOpen(0)<cr>
1985    nnoremap <buffer> <silent> <s-leftmouse> <leftmouse>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
1986    exe 'nnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1987    exe 'vnoremap <buffer> <silent> <rightmouse> <leftmouse>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1988    inoremap <buffer> <silent> <leftmouse>   <c-o><leftmouse><c-o>:call <SID>NetrwLeftmouse(0)<cr>
1989    inoremap <buffer> <silent> <middlemouse> <c-o><leftmouse><c-o>:call <SID>NetrwPrevWinOpen(0)<cr>
1990    inoremap <buffer> <silent> <s-leftmouse> <c-o><leftmouse><c-o>:call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
1991    exe 'inoremap <buffer> <silent> <rightmouse> <c-o><leftmouse><c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1992   endif
1993   exe 'nnoremap <buffer> <silent> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1994   exe 'nnoremap <buffer> <silent> d		:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
1995   exe 'nnoremap <buffer> <silent> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1996   exe 'nnoremap <buffer> <silent> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1997   exe 'vnoremap <buffer> <silent> <del>	:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1998   exe 'vnoremap <buffer> <silent> D		:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
1999   exe 'vnoremap <buffer> <silent> R		:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
2000   exe 'inoremap <buffer> <silent> <del>	<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
2001   exe 'inoremap <buffer> <silent> d		<c-o>:call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
2002   exe 'inoremap <buffer> <silent> D		<c-o>:call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
2003   exe 'inoremap <buffer> <silent> R		<c-o>:call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
2004   nnoremap <buffer> <F1>			:he netrw-quickhelp<cr>
2005   inoremap <buffer> <F1>			<c-o>:he netrw-quickhelp<cr>
2006  endif
2007  call s:SetRexDir(a:islocal,b:netrw_curdir)
2008"  call Dret("s:BrowserMaps")
2009endfun
2010
2011" ---------------------------------------------------------------------
2012" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
2013fun! s:ExplorePatHls(pattern)
2014"  call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
2015  let repat= substitute(a:pattern,'^**/\{1,2}','','')
2016"  call Decho("repat<".repat.">")
2017  let repat= escape(repat,'][.\')
2018"  call Decho("repat<".repat.">")
2019  let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
2020"  call Dret("s:ExplorePatHls repat<".repat.">")
2021  return repat
2022endfun
2023
2024" ---------------------------------------------------------------------
2025"  s:NetrwBookHistHandler: {{{2
2026"    0: (user: <mb>)   bookmark current directory
2027"    1: (user: <gb>)   change to the bookmarked directory
2028"    2: (user: <qb>)   list bookmarks
2029"    3: (browsing)     record current directory history
2030"    4: (user: <u>)    go up   (previous) bookmark
2031"    5: (user: <U>)    go down (next)     bookmark
2032"    6: (user: <mB>)   delete bookmark
2033fun! s:NetrwBookHistHandler(chg,curdir)
2034"  call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhist_cnt." histmax=".g:netrw_dirhistmax)
2035
2036  if a:chg == 0
2037   " bookmark the current directory
2038"   call Decho("(user: <b>) bookmark the current directory")
2039   if !exists("g:netrw_bookmarklist")
2040    let g:netrw_bookmarklist= []
2041   endif
2042   if index(g:netrw_bookmarklist,a:curdir) == -1
2043    " curdir not currently in g:netrw_bookmarklist, so include it
2044    call add(g:netrw_bookmarklist,a:curdir)
2045    call sort(g:netrw_bookmarklist)
2046   endif
2047   echo "bookmarked the current directory"
2048
2049  elseif a:chg == 1
2050   " change to the bookmarked directory
2051"   call Decho("(user: <".v:count."mb>) change to the bookmarked directory")
2052   if exists("g:netrw_bookmarklist[v:count-1]")
2053    exe "e ".fnameescape(g:netrw_bookmarklist[v:count-1])
2054   else
2055    echomsg "Sorry, bookmark#".v:count." doesn't exist!"
2056   endif
2057
2058  elseif a:chg == 2
2059"   redraw!
2060   let didwork= 0
2061   " list user's bookmarks
2062"   call Decho("(user: <q>) list user's bookmarks")
2063   if exists("g:netrw_bookmarklist")
2064"    call Decho('list '.len(g:netrw_bookmarklist).' bookmarks')
2065    let cnt= 1
2066    for bmd in g:netrw_bookmarklist
2067"     call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1])
2068     echo "Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1]
2069     let didwork = 1
2070     let cnt     = cnt + 1
2071    endfor
2072   endif
2073
2074   " list directory history
2075   let cnt     = g:netrw_dirhist_cnt
2076   let first   = 1
2077   let histcnt = 0
2078   while ( first || cnt != g:netrw_dirhist_cnt )
2079"    call Decho("first=".first." cnt=".cnt." dirhist_cnt=".g:netrw_dirhist_cnt)
2080    let histcnt= histcnt + 1
2081    if exists("g:netrw_dirhist_{cnt}")
2082"     call Decho("Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt})
2083     echo "Netrw  History#".histcnt.": ".g:netrw_dirhist_{cnt}
2084     let didwork= 1
2085    endif
2086    let first = 0
2087    let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
2088    if cnt < 0
2089     let cnt= cnt + g:netrw_dirhistmax
2090    endif
2091   endwhile
2092   if didwork
2093    call inputsave()|call input("Press <cr> to continue")|call inputrestore()
2094   endif
2095
2096  elseif a:chg == 3
2097   " saves most recently visited directories (when they differ)
2098"   call Decho("(browsing) record curdir history")
2099   if !exists("g:netrw_dirhist_cnt") || !exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}") || g:netrw_dirhist_{g:netrw_dirhist_cnt} != a:curdir
2100    let g:netrw_dirhist_cnt                   = ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
2101    let g:netrw_dirhist_{g:netrw_dirhist_cnt} = a:curdir
2102"    call Decho("save dirhist#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">")
2103   endif
2104
2105  elseif a:chg == 4
2106   " u: change to the previous directory stored on the history list
2107"   call Decho("(user: <u>) chg to prev dir from history")
2108   let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax
2109   if g:netrw_dirhist_cnt < 0
2110    let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
2111   endif
2112   if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
2113"    call Decho("changedir u#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">")
2114    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
2115     setlocal ma noro
2116"     call Decho("setlocal ma noro")
2117     keepj %d
2118     setlocal nomod
2119"     call Decho("setlocal nomod")
2120    endif
2121"    "    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}))
2122    exe "keepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
2123   else
2124    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
2125    echo "Sorry, no predecessor directory exists yet"
2126   endif
2127
2128  elseif a:chg == 5
2129   " U: change to the subsequent directory stored on the history list
2130"   call Decho("(user: <U>) chg to next dir from history")
2131   let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt + 1 ) % g:netrw_dirhistmax
2132   if exists("g:netrw_dirhist_{g:netrw_dirhist_cnt}")
2133"    call Decho("changedir U#".g:netrw_dirhist_cnt."<".g:netrw_dirhist_{g:netrw_dirhist_cnt}.">")
2134    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
2135     setlocal ma noro
2136"     call Decho("setlocal ma noro")
2137     keepj %d
2138"     call Decho("removed all lines from buffer (%d)")
2139     setlocal nomod
2140"     call Decho("setlocal nomod")
2141    endif
2142"    call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt}))
2143    exe "keepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhist_cnt})
2144   else
2145    let g:netrw_dirhist_cnt= ( g:netrw_dirhist_cnt - 1 ) % g:netrw_dirhistmax
2146    if g:netrw_dirhist_cnt < 0
2147     let g:netrw_dirhist_cnt= g:netrw_dirhist_cnt + g:netrw_dirhistmax
2148    endif
2149    echo "Sorry, no successor directory exists yet"
2150   endif
2151
2152  elseif a:chg == 6
2153   " delete the v:count'th bookmark
2154"   call Decho("delete bookmark#".v:count."<".g:netrw_bookmarklist[v:count-1].">")
2155   let savefile= s:NetrwHome()."/.netrwbook"
2156   if filereadable(savefile)
2157    call s:NetrwBookHistSave() " done here to merge bookmarks first
2158    call delete(savefile)
2159   endif
2160   call remove(g:netrw_bookmarklist,v:count-1)
2161  endif
2162  call s:NetrwBookmarkMenu()
2163"  call Dret("s:NetrwBookHistHandler")
2164endfun
2165
2166" ---------------------------------------------------------------------
2167" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
2168"                      Sister function: s:NetrwBookHistSave()
2169fun! s:NetrwBookHistRead()
2170"  call Dfunc("s:NetrwBookHistRead()")
2171  if !exists("s:netrw_initbookhist")
2172   let home    = s:NetrwHome()
2173   let savefile= home."/.netrwbook"
2174   if filereadable(savefile)
2175"    call Decho("sourcing .netrwbook")
2176    exe "so ".savefile
2177   endif
2178   let savefile= home."/.netrwhist"
2179   if filereadable(savefile)
2180"    call Decho("sourcing .netrwhist")
2181    exe "so ".savefile
2182   endif
2183   let s:netrw_initbookhist= 1
2184   au VimLeave * call s:NetrwBookHistSave()
2185  endif
2186"  call Dret("s:NetrwBookHistRead")
2187endfun
2188
2189" ---------------------------------------------------------------------
2190" s:NetrwBookHistSave: this function saves bookmarks and history {{{2
2191"                      Sister function: s:NetrwBookHistRead()
2192"                      I used to do this via viminfo but that appears to
2193"                      be unreliable for long-term storage
2194"                      COMBAK: does $HOME work under windows???
2195fun! s:NetrwBookHistSave()
2196"  call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax)
2197  let savefile= s:NetrwHome()."/.netrwhist"
2198  1split
2199  call s:NetrwEnew()
2200  setlocal cino= com= cpo-=aA fo=nroql2 tw=0 report=10000 noswf
2201  setlocal nocin noai noci magic nospell nohid wig= noaw
2202  setlocal ma noro write
2203  if exists("&acd") | setlocal noacd | endif
2204  silent %d
2205
2206  " save .netrwhist -- no attempt to merge
2207  silent! file .netrwhist
2208  call setline(1,"let g:netrw_dirhistmax  =".g:netrw_dirhistmax)
2209  call setline(2,"let g:netrw_dirhist_cnt =".g:netrw_dirhist_cnt)
2210  let lastline = line("$")
2211  let cnt      = 1
2212  while cnt <= g:netrw_dirhist_cnt
2213   call setline((cnt+lastline),'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
2214   let cnt= cnt + 1
2215  endwhile
2216  exe "sil! w! ".savefile
2217
2218  sil keepj %d
2219  if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
2220   " merge and write .netrwbook
2221   let savefile= s:NetrwHome()."/.netrwbook"
2222
2223   if filereadable(savefile)
2224    let booklist= deepcopy(g:netrw_bookmarklist)
2225    exe "sil keepj so ".savefile
2226    for bdm in booklist
2227     if index(g:netrw_bookmarklist,bdm) == -1
2228      call add(g:netrw_bookmarklist,bdm)
2229     endif
2230    endfor
2231    call sort(g:netrw_bookmarklist)
2232    exe "sil! w! ".savefile
2233   endif
2234
2235   " construct and save .netrwbook
2236   call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
2237   exe "sil! w! ".savefile
2238  endif
2239  let bgone= bufnr("%")
2240  q!
2241  exe bgone."bwipe!"
2242
2243"  call Dret("s:NetrwBookHistSave")
2244endfun
2245
2246" ---------------------------------------------------------------------
2247" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
2248"  list of the contents of a local or remote directory.  It is assumed that the
2249"  g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
2250"  with the requested remote hostname first.
2251fun! s:NetrwBrowse(islocal,dirname)
2252  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
2253"  call Dfunc("s:NetrwBrowse(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".w:netrw_liststyle." ".g:loaded_netrw." buf#".bufnr("%")."<".bufname("%")."> win#".winnr())
2254"  call Decho("tab#".tabpagenr()." win#".winnr())
2255"  call Dredir("ls!")
2256  if !exists("s:netrw_initbookhist")
2257   call s:NetrwBookHistRead()
2258  endif
2259
2260  " simplify the dirname (especially for ".."s in dirnames)
2261  if a:dirname !~ '^\a\+://'
2262   let dirname= simplify(a:dirname)
2263  else
2264   let dirname= a:dirname
2265  endif
2266
2267  if exists("s:netrw_skipbrowse")
2268   unlet s:netrw_skipbrowse
2269"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2270"   call Dret("s:NetrwBrowse : s:netrw_skipbrowse=".s:netrw_skipbrowse)
2271   return
2272  endif
2273  if !exists("*shellescape")
2274   call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
2275"   call Dret("s:NetrwBrowse : missing shellescape()")
2276   return
2277  endif
2278  if !exists("*fnameescape")
2279   call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
2280"   call Dret("s:NetrwBrowse : missing fnameescape()")
2281   return
2282  endif
2283
2284  call s:NetrwOptionSave("w:")                                                                                                            
2285
2286  " re-instate any marked files
2287  if exists("s:netrwmarkfilelist_{bufnr('%')}")
2288"   call Decho("clearing marked files")
2289   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
2290  endif
2291
2292  if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
2293"   call Decho("handle w:netrw_acdkeep:")
2294"   call Decho("keepjumps lcd ".fnameescape(dirname)." (due to w:netrw_acdkeep=".w:netrw_acdkeep." - acd=".&acd.")")
2295   exe 'keepj lcd '.fnameescape(dirname)
2296   call s:NetrwSafeOptions()
2297"   call Decho("getcwd<".getcwd().">")
2298
2299  elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
2300   " looks like a regular file, attempt transfer
2301"   call Decho("attempt transfer as regular file<".dirname.">")
2302
2303   " remove any filetype indicator from end of dirname, except for the {{{3
2304   " "this is a directory" indicator (/).
2305   " There shouldn't be one of those here, anyway.
2306   let path= substitute(dirname,'[*=@|]\r\=$','','e')
2307"   call Decho("new path<".path.">")
2308   call s:RemotePathAnalysis(dirname)
2309
2310   " remote-read the requested file into current buffer {{{3
2311   keepj mark '
2312   call s:NetrwEnew(dirname)
2313   call s:NetrwSafeOptions()
2314   setlocal ma noro
2315"   call Decho("setlocal ma noro")
2316   let b:netrw_curdir= dirname
2317"   call Decho("exe sil! keepalt file ".fnameescape(s:method."://".s:user.s:machine."/".s:path)." (bt=".&bt.")")
2318   exe "sil! keepalt file ".fnameescape(s:method."://".s:user.s:machine."/".s:path)
2319   exe "sil! keepalt doau BufReadPre ".fnameescape(s:fname)
2320   silent call netrw#NetRead(2,s:method."://".s:user.s:machine."/".s:path)
2321   if s:path !~ '.tar.bz2$' && s:path !~ '.tar.gz' && s:path !~ '.tar.xz' && s:path !~ '.txz'
2322    " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
2323    exe "sil keepalt doau BufReadPost ".fnameescape(s:fname)
2324   endif
2325
2326   " save certain window-oriented variables into buffer-oriented variables {{{3
2327   call s:SetBufWinVars()
2328   call s:NetrwOptionRestore("w:")
2329   setlocal ma nomod
2330
2331"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2332"   call Dret("s:NetrwBrowse : file<".s:fname.">")
2333   return
2334  endif
2335
2336  " use buffer-oriented WinVars if buffer ones exist but window ones don't {{{3
2337  call s:UseBufWinVars()
2338
2339  " set up some variables {{{3
2340  let b:netrw_browser_active = 1
2341  let dirname                = dirname
2342  let s:last_sort_by         = g:netrw_sort_by
2343
2344  " set up menu {{{3
2345  call s:NetrwMenu(1)
2346
2347  " set up buffer {{{3
2348  let reusing= s:NetrwGetBuffer(a:islocal,dirname)
2349  " maintain markfile highlighting
2350  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
2351"   call Decho("bufnr(%)=".bufnr('%'))
2352"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/")
2353   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
2354  else
2355"   call Decho("2match none")
2356   2match none
2357  endif
2358  if reusing
2359   call s:NetrwOptionRestore("w:")
2360   setlocal noma nomod nowrap
2361"   call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2362"   call Dret("s:NetrwBrowse : re-using buffer")
2363   return
2364  endif
2365
2366  " set b:netrw_curdir to the new directory name {{{3
2367"  call Decho("set b:netrw_curdir to the new directory name:  (buf#".bufnr("%").")")
2368  let b:netrw_curdir= dirname
2369  if b:netrw_curdir =~ '[/\\]$'
2370   let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
2371  endif
2372  if b:netrw_curdir == ''
2373   if has("amiga")
2374    " On the Amiga, the empty string connotes the current directory
2375    let b:netrw_curdir= getcwd()
2376   else
2377    " under unix, when the root directory is encountered, the result
2378    " from the preceding substitute is an empty string.
2379    let b:netrw_curdir= '/'
2380   endif
2381  endif
2382  if !a:islocal && b:netrw_curdir !~ '/$'
2383   let b:netrw_curdir= b:netrw_curdir.'/'
2384  endif
2385"  call Decho("b:netrw_curdir<".b:netrw_curdir.">")
2386
2387  " ------------
2388  " (local only) {{{3
2389  " ------------
2390  if a:islocal
2391"   call Decho("local only:")
2392
2393   " Set up ShellCmdPost handling.  Append current buffer to browselist
2394   call s:LocalFastBrowser()
2395
2396  " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
2397   if !g:netrw_keepdir
2398"    call Decho("handle g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd)
2399"    call Decho("l:acd".(exists("&l:acd")? "=".&l:acd : " doesn't exist"))
2400    if !exists("&l:acd") || !&l:acd
2401"     call Decho('exe keepjumps lcd '.fnameescape(b:netrw_curdir))
2402     try
2403      exe 'keepj lcd '.fnameescape(b:netrw_curdir)
2404     catch /^Vim\%((\a\+)\)\=:E472/
2405      call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".b:netrw_curdir."> (permissions?)",61)
2406      if exists("w:netrw_prvdir")
2407       let b:netrw_curdir= w:netrw_prvdir
2408      else
2409       call s:NetrwOptionRestore("w:")
2410       setlocal noma nomod nowrap
2411       let b:netrw_curdir= dirname
2412"       call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2413"       call Dret("s:NetrwBrowse : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
2414       return
2415      endif
2416     endtry
2417    endif
2418   endif
2419
2420  " --------------------------------
2421  " remote handling: {{{3
2422  " --------------------------------
2423  else
2424"   call Decho("remote only:")
2425
2426   " analyze dirname and g:netrw_list_cmd {{{4
2427"   call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist")."> dirname<".dirname.">")
2428   if dirname =~ "^NetrwTreeListing\>"
2429    let dirname= b:netrw_curdir
2430"    call Decho("(dirname was ".dirname.") dirname<".dirname.">")
2431   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
2432    let dirname= substitute(b:netrw_curdir,'\\','/','g')
2433    if dirname !~ '/$'
2434     let dirname= dirname.'/'
2435    endif
2436    let b:netrw_curdir = dirname
2437"    call Decho("(liststyle is TREELIST) dirname<".dirname.">")
2438   else
2439    let dirname = substitute(dirname,'\\','/','g')
2440"    call Decho("(normal) dirname<".dirname.">")
2441   endif
2442
2443   let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
2444   if dirname !~ dirpat
2445    if !exists("g:netrw_quiet")
2446     call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
2447    endif
2448    call s:NetrwOptionRestore("w:")
2449    setlocal noma nomod nowrap
2450"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2451"    call Dret("s:NetrwBrowse : badly formatted dirname<".dirname.">")
2452    return
2453   endif
2454   let b:netrw_curdir= dirname
2455"   call Decho("b:netrw_curdir<".b:netrw_curdir."> (remote)")
2456  endif  " (additional remote handling)
2457
2458  " -----------------------
2459  " Directory Listing: {{{3
2460  " -----------------------
2461  call s:BrowserMaps(a:islocal)
2462  call s:PerformListing(a:islocal)
2463
2464  " The s:LocalBrowseShellCmdRefresh() function is called by an autocmd
2465  " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow, medium speed).
2466  " However, s:NetrwBrowse() causes the ShellCmdPost event itself to fire once; setting
2467  " the variable below avoids that second refresh of the screen.  The s:LocalBrowseShellCmdRefresh()
2468  " function gets called due to that autocmd; it notices that the following variable is set
2469  " and skips the refresh and sets s:locbrowseshellcmd to zero. Oct 13, 2008
2470  let s:locbrowseshellcmd= 1
2471
2472"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
2473"  call Dret("s:NetrwBrowse : did PerformListing")
2474  return
2475endfun
2476
2477" ---------------------------------------------------------------------
2478" s:NetrwFileInfo: supports qf (query for file information) {{{2
2479fun! s:NetrwFileInfo(islocal,fname)
2480"  call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">)")
2481  if a:islocal
2482   if (has("unix") || has("macunix")) && executable("/bin/ls")
2483    if exists("b:netrw_curdir")
2484"     call Decho('using ls with b:netrw_curdir<'.b:netrw_curdir.'>')
2485     if b:netrw_curdir =~ '/$'
2486      echo system("/bin/ls -lsad ".shellescape(b:netrw_curdir.a:fname))
2487     else
2488      echo system("/bin/ls -lsad ".shellescape(b:netrw_curdir."/".a:fname))
2489     endif
2490    else
2491"     call Decho('using ls '.a:fname." using cwd<".getcwd().">")
2492     echo system("/bin/ls -lsad ".shellescape(a:fname))
2493    endif
2494   else
2495    " use vim functions to return information about file below cursor
2496"    call Decho("using vim functions to query for file info")
2497    if !isdirectory(a:fname) && !filereadable(a:fname) && a:fname =~ '[*@/]'
2498     let fname= substitute(a:fname,".$","","")
2499    else
2500     let fname= a:fname
2501    endif
2502    let t  = getftime(fname)
2503    let sz = getfsize(fname)
2504    echo a:fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname))
2505"    call Decho(fname.":  ".sz."  ".strftime(g:netrw_timefmt,getftime(fname)))
2506   endif
2507  else
2508   echo "sorry, \"qf\" not supported yet for remote files"
2509  endif
2510"  call Dret("s:NetrwFileInfo")
2511endfun
2512
2513" ---------------------------------------------------------------------
2514" s:NetrwGetBuffer: {{{2
2515"   returns 0=cleared buffer
2516"           1=re-used buffer
2517fun! s:NetrwGetBuffer(islocal,dirname)
2518"  call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
2519  let dirname= a:dirname
2520
2521  " re-use buffer if possible {{{3
2522"  call Decho("--re-use a buffer if possible--")
2523  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
2524   " find NetrwTreeList buffer if there is one
2525"   call Decho("find NetrwTreeList buffer if there is one")
2526   if exists("w:netrw_treebufnr") && w:netrw_treebufnr > 0
2527"    call Decho("  re-use w:netrw_treebufnr=".w:netrw_treebufnr)
2528    let eikeep= &ei
2529    set ei=all
2530    exe "sil! b ".w:netrw_treebufnr
2531    let &ei= eikeep
2532"    call Dret("s:NetrwGetBuffer : bufnum#".w:netrw_treebufnr."<NetrwTreeListing>")
2533    return
2534   endif
2535   let bufnum= -1
2536"   call Decho("  liststyle=TREE but w:netrw_treebufnr doesn't exist")
2537
2538  else
2539   " find buffer number of buffer named precisely the same as dirname {{{3
2540"   call Decho("--find buffer numnber of buffer named precisely the same as dirname--")
2541"   call Dredir("ls!")
2542
2543   " get dirname and associated buffer number
2544   let bufnum  = bufnr(escape(dirname,'\'))
2545"   call Decho("  find buffer<".dirname.">'s number ")
2546"   call Decho("  bufnr(dirname<".escape(dirname,'\').">)=".bufnum)
2547
2548   if bufnum < 0 && dirname !~ '/$'
2549    " try appending a trailing /
2550"    call Decho("  try appending a trailing / to dirname<".dirname.">")
2551    let bufnum= bufnr(escape(dirname.'/','\'))
2552    if bufnum > 0
2553     let dirname= dirname.'/'
2554    endif
2555   endif
2556
2557   if bufnum < 0 && dirname =~ '/$'
2558    " try removing a trailing /
2559"    call Decho("  try removing a trailing / from dirname<".dirname.">")
2560    let bufnum= bufnr(escape(substitute(dirname,'/$','',''),'\'))
2561    if bufnum > 0
2562     let dirname= substitute(dirname,'/$','','')
2563    endif
2564   endif
2565
2566"   call Decho("  findbuf1: bufnum=bufnr('".dirname."')=".bufnum." bufname(".bufnum.")<".bufname(bufnum)."> (initial)")
2567   " note: !~ was used just below, but that means using ../ to go back would match (ie. abc/def/  and abc/ matches)
2568   if bufnum > 0 && bufname(bufnum) != dirname && bufname(bufnum) != '.'
2569    " handle approximate matches
2570"    call Decho("  handling approx match: bufnum#".bufnum."<".bufname(bufnum)."> approx-dirname<".dirname.">")
2571    let ibuf    = 1
2572    let buflast = bufnr("$")
2573"    call Decho("  findbuf2: buflast=bufnr($)=".buflast)
2574    while ibuf <= buflast
2575     let bname= substitute(bufname(ibuf),'\\','/','g')
2576     let bname= substitute(bname,'.\zs/$','','')
2577"     call Decho("  findbuf3: while [ibuf=",ibuf."]<=[buflast=".buflast."]: dirname<".dirname."> bname=bufname(".ibuf.")<".bname.">")
2578     if bname != '' && dirname =~ '/'.bname.'/\=$' && dirname !~ '^/'
2579      " bname is not empty
2580      " dirname ends with bname,
2581      " dirname doesn't start with /, so its not a absolute path
2582"      call Decho("  findbuf3a: passes test 1 : dirname<".dirname.'> =~ /'.bname.'/\=$ && dirname !~ ^/')
2583      break
2584     endif
2585     if bname =~ '^'.dirname.'/\=$'
2586      " bname begins with dirname
2587"      call Decho('  findbuf3b: passes test 2 : bname<'.bname.'>=~^'.dirname.'/\=$')
2588      break
2589     endif
2590     if dirname =~ '^'.bname.'/$'
2591"      call Decho('  findbuf3c: passes test 3 : dirname<'.dirname.'>=~^'.bname.'/$')
2592      break
2593     endif
2594     if bname != '' && dirname =~ '/'.bname.'$' && bname == bufname("%") && line("$") == 1
2595"      call Decho('  findbuf3d: passes test 4 : dirname<'.dirname.'>=~ /'.bname.'$')
2596      break
2597     endif
2598     let ibuf= ibuf + 1
2599    endwhile
2600    if ibuf > buflast
2601     let bufnum= -1
2602    else
2603     let bufnum= ibuf
2604    endif
2605"    call Decho("  findbuf4: bufnum=".bufnum." (ibuf=".ibuf." buflast=".buflast.")")
2606   endif
2607  endif
2608
2609  " get enew buffer and name it -or- re-use buffer {{{3
2610  sil! keepj mark '
2611  if bufnum < 0 || !bufexists(bufnum)
2612"   call Decho("--get enew buffer and name it (bufexists([bufnum=".bufnum."])=".bufexists(bufnum).")")
2613   call s:NetrwEnew(dirname)
2614"   call Decho("  got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)")
2615   " name the buffer
2616   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
2617    " Got enew buffer; transform into a NetrwTreeListing
2618"    call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --")
2619    if !exists("s:netrw_treelistnum")
2620     let s:netrw_treelistnum= 1
2621    else
2622     let s:netrw_treelistnum= s:netrw_treelistnum + 1
2623    endif
2624    let w:netrw_treebufnr= bufnr("%")
2625"    call Decho("  exe sil! keepalt file NetrwTreeListing ".fnameescape(s:netrw_treelistnum))
2626    exe 'sil! keepalt file NetrwTreeListing\ '.fnameescape(s:netrw_treelistnum)
2627    set bt=nofile noswf
2628    nnoremap <silent> <buffer> [	:silent call <SID>TreeListMove('[')<cr>
2629    nnoremap <silent> <buffer> ]	:silent call <SID>TreeListMove(']')<cr>
2630    nnoremap <silent> <buffer> [[       :silent call <SID>TreeListMove('[')<cr>
2631    nnoremap <silent> <buffer> ]]       :silent call <SID>TreeListMove(']')<cr>
2632"    call Decho("  tree listing#".s:netrw_treelistnum." bufnr=".w:netrw_treebufnr)
2633   else
2634"    let v:errmsg= "" " Decho
2635    let escdirname= fnameescape(dirname)
2636"    call Decho("  errmsg<".v:errmsg."> bufnr(escdirname<".escdirname.">)=".bufnr(escdirname)." bufname()<".bufname(bufnr(escdirname)).">")
2637"    call Decho('  exe sil! keepalt file '.escdirname)
2638"    let v:errmsg= "" " Decho
2639    exe 'sil! keepalt file '.escdirname
2640"    call Decho("  errmsg<".v:errmsg."> bufnr(".escdirname.")=".bufnr(escdirname)."<".bufname(bufnr(escdirname)).">")
2641   endif
2642"   call Decho("  named enew buffer#".bufnr("%")."<".bufname("%").">")
2643
2644  else " Re-use the buffer
2645"   call Decho("--re-use buffer#".bufnum." (bufexists([bufnum=".bufnum."])=".bufexists(bufnum).")")
2646   let eikeep= &ei
2647   set ei=all
2648   if getline(2) =~ '^" Netrw Directory Listing'
2649"    call Decho("  re-use buffer#".bufnum."<".((bufnum > 0)? bufname(bufnum) : "")."> using:  keepalt b ".bufnum)
2650    exe "sil! keepalt b ".bufnum
2651   else
2652"    call Decho("  reusing buffer#".bufnum."<".((bufnum > 0)? bufname(bufnum) : "")."> using:  b ".bufnum)
2653    exe "sil! b ".bufnum
2654   endif
2655   if bufname("%") == '.'
2656"    call Decho("exe sil! keepalt file ".fnameescape(getcwd()))
2657    exe "sil! keepalt file ".fnameescape(getcwd())
2658   endif
2659   let &ei= eikeep
2660   if line("$") <= 1
2661    call s:NetrwListSettings(a:islocal)
2662"    call Dret("s:NetrwGetBuffer 0 : re-using buffer#".bufnr("%").", but its empty, so refresh it")
2663    return 0
2664   elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
2665"    call Decho("--re-use tree listing--")
2666"    call Decho("  clear buffer<".expand("%")."> with :%d")
2667    sil keepj %d
2668    call s:NetrwListSettings(a:islocal)
2669"    call Dret("s:NetrwGetBuffer 0 : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
2670    return 0
2671   else
2672"    call Dret("s:NetrwGetBuffer 1 : buf#".bufnr("%"))
2673    return 1
2674   endif
2675  endif
2676
2677  " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
2678  "     fastbrowse  Local  Remote   Hiding a buffer implies it may be re-used (fast)
2679  "  slow   0         D      D      Deleting a buffer implies it will not be re-used (slow)
2680  "  med    1         D      H
2681  "  fast   2         H      H
2682"  call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--")
2683  let fname= expand("%")
2684  call s:NetrwListSettings(a:islocal)
2685"  call Decho("exe sil! keepalt file ".fnameescape(fname))
2686  exe "sil! keepalt file ".fnameescape(fname)
2687
2688  " delete all lines from buffer {{{3
2689"  call Decho("--delete all lines from buffer--")
2690"  call Decho("  clear buffer<".expand("%")."> with :%d")
2691  sil! keepalt keepj %d
2692
2693"  call Dret("s:NetrwGetBuffer 0 : buf#".bufnr("%"))
2694  return 0
2695endfun
2696
2697" ---------------------------------------------------------------------
2698" s:NetrwGetcwd: get the current directory. {{{2
2699"   Change backslashes to forward slashes, if any.
2700"   If doesc is true, escape certain troublesome characters
2701fun! s:NetrwGetcwd(doesc)
2702"  call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
2703  let curdir= substitute(getcwd(),'\\','/','ge')
2704  if curdir !~ '[\/]$'
2705   let curdir= curdir.'/'
2706  endif
2707  if a:doesc
2708   let curdir= fnameescape(curdir)
2709  endif
2710"  call Dret("NetrwGetcwd <".curdir.">")
2711  return curdir
2712endfun
2713
2714" ---------------------------------------------------------------------
2715"  s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
2716fun! s:NetrwGetWord()
2717"  call Dfunc("s:NetrwGetWord() line#".line(".")." liststyle=".g:netrw_liststyle." virtcol=".virtcol("."))
2718  call s:UseBufWinVars()
2719
2720  " insure that w:netrw_liststyle is set up
2721  if !exists("w:netrw_liststyle")
2722   if exists("g:netrw_liststyle")
2723    let w:netrw_liststyle= g:netrw_liststyle
2724   else
2725    let w:netrw_liststyle= s:THINLIST
2726   endif
2727"   call Decho("w:netrw_liststyle=".w:netrw_liststyle)
2728  endif
2729
2730  if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
2731   " Active Banner support
2732"   call Decho("active banner handling")
2733   keepj norm! 0
2734   let dirname= "./"
2735   let curline= getline('.')
2736
2737   if curline =~ '"\s*Sorted by\s'
2738    keepj norm s
2739    let s:netrw_skipbrowse= 1
2740    echo 'Pressing "s" also works'
2741
2742   elseif curline =~ '"\s*Sort sequence:'
2743    let s:netrw_skipbrowse= 1
2744    echo 'Press "S" to edit sorting sequence'
2745
2746   elseif curline =~ '"\s*Quick Help:'
2747    keepj norm ?
2748    let s:netrw_skipbrowse= 1
2749    echo 'Pressing "?" also works'
2750
2751   elseif curline =~ '"\s*\%(Hiding\|Showing\):'
2752    keepj norm a
2753    let s:netrw_skipbrowse= 1
2754    echo 'Pressing "a" also works'
2755
2756   elseif line("$") > w:netrw_bannercnt
2757    exe 'sil keepj '.w:netrw_bannercnt
2758   endif
2759
2760  elseif w:netrw_liststyle == s:THINLIST
2761"   call Decho("thin column handling")
2762   keepj norm! 0
2763   let dirname= getline('.')
2764
2765  elseif w:netrw_liststyle == s:LONGLIST
2766"   call Decho("long column handling")
2767   keepj norm! 0
2768   let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
2769
2770  elseif w:netrw_liststyle == s:TREELIST
2771"   call Decho("treelist handling")
2772   let dirname= substitute(getline('.'),'^\(| \)*','','e')
2773
2774  else
2775"   call Decho("obtain word from wide listing")
2776   let dirname= getline('.')
2777
2778   if !exists("b:netrw_cpf")
2779    let b:netrw_cpf= 0
2780    exe 'silent keepjumps '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
2781    call histdel("/",-1)
2782"   call Decho("computed cpf=".b:netrw_cpf)
2783   endif
2784
2785"   call Decho("buf#".bufnr("%")."<".bufname("%").">")
2786   let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
2787"   call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart."  bannercnt=".w:netrw_bannercnt)
2788"   call Decho("1: dirname<".dirname.">")
2789   if filestart == 0
2790    keepj norm! 0ma
2791   else
2792    call cursor(line("."),filestart+1)
2793    keepj norm! ma
2794   endif
2795   let rega= @a
2796   let eofname= filestart + b:netrw_cpf + 1
2797   if eofname <= col("$")
2798    call cursor(line("."),filestart+b:netrw_cpf+1)
2799    keepj norm! "ay`a
2800   else
2801    keepj norm! "ay$
2802   endif
2803   let dirname = @a
2804   let @a      = rega
2805"   call Decho("2: dirname<".dirname.">")
2806   let dirname= substitute(dirname,'\s\+$','','e')
2807"   call Decho("3: dirname<".dirname.">")
2808  endif
2809
2810  " symlinks are indicated by a trailing "@".  Remove it before further processing.
2811  let dirname= substitute(dirname,"@$","","")
2812
2813  " executables are indicated by a trailing "*".  Remove it before further processing.
2814  let dirname= substitute(dirname,"\*$","","")
2815
2816"  call Dret("s:NetrwGetWord <".dirname.">")
2817  return dirname
2818endfun
2819
2820" ---------------------------------------------------------------------
2821" s:NetrwListSettings: make standard settings for a netrw listing {{{2
2822fun! s:NetrwListSettings(islocal)
2823"  call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
2824  let fname= bufname("%")
2825"  call Decho("setlocal bt=nofile nobl ma nonu nowrap noro")
2826  setlocal bt=nofile nobl ma nonu nowrap noro
2827"  call Decho("exe sil! keepalt file ".fnameescape(fname))
2828  exe "sil! keepalt file ".fnameescape(fname)
2829  if g:netrw_use_noswf
2830   setlocal noswf
2831  endif
2832"  call Dredir("ls!")
2833"  call Decho("exe setlocal ts=".g:netrw_maxfilenamelen)
2834  exe "setlocal ts=".g:netrw_maxfilenamelen
2835  setlocal isk+=.,~,-
2836  if g:netrw_fastbrowse > a:islocal
2837   setlocal bh=hide
2838  else
2839   setlocal bh=delete
2840  endif
2841"  call Dret("s:NetrwListSettings")
2842endfun
2843
2844" ---------------------------------------------------------------------
2845"  s:NetrwListStyle: {{{2
2846"  islocal=0: remote browsing
2847"         =1: local browsing
2848fun! s:NetrwListStyle(islocal)
2849"  call Dfunc("NetrwListStyle(islocal=".a:islocal.") w:netrw_liststyle=".w:netrw_liststyle)
2850  let fname             = s:NetrwGetWord()
2851  if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
2852  let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
2853"  call Decho("fname<".fname.">")
2854"  call Decho("chgd w:netrw_liststyle to ".w:netrw_liststyle)
2855"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "doesn't exist").">")
2856
2857  if w:netrw_liststyle == s:THINLIST
2858   " use one column listing
2859"   call Decho("use one column list")
2860   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
2861
2862  elseif w:netrw_liststyle == s:LONGLIST
2863   " use long list
2864"   call Decho("use long list")
2865   let g:netrw_list_cmd = g:netrw_list_cmd." -l"
2866
2867  elseif w:netrw_liststyle == s:WIDELIST
2868   " give wide list
2869"   call Decho("use wide list")
2870   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
2871
2872  elseif w:netrw_liststyle == s:TREELIST
2873"   call Decho("use tree list")
2874   let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
2875
2876  else
2877   call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
2878   let g:netrw_liststyle = s:THINLIST
2879   let w:netrw_liststyle = g:netrw_liststyle
2880   let g:netrw_list_cmd  = substitute(g:netrw_list_cmd,' -l','','ge')
2881  endif
2882  setlocal ma noro
2883"  call Decho("setlocal ma noro")
2884
2885  " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
2886"  call Decho("clear buffer<".expand("%")."> with :%d")
2887  sil! keepj %d
2888  " following prevents tree listing buffer from being marked "modified"
2889  setlocal nomod
2890
2891  " refresh the listing
2892"  call Decho("refresh the listing")
2893  let svpos= netrw#NetrwSavePosn()
2894  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
2895  call netrw#NetrwRestorePosn(svpos)
2896  call s:NetrwCursorline()
2897
2898  " keep cursor on the filename
2899  sil! keepj $
2900  let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
2901"  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'))
2902  if result <= 0 && exists("w:netrw_bannercnt")
2903   exe "sil! keepj ".w:netrw_bannercnt
2904  endif
2905
2906"  call Dret("NetrwListStyle".(exists("w:netrw_liststyle")? ' : w:netrw_liststyle='.w:netrw_liststyle : ""))
2907endfun
2908
2909" ---------------------------------------------------------------------
2910" s:NetrwBannerCtrl: toggles the display of the banner {{{2
2911fun! s:NetrwBannerCtrl(islocal)
2912"  call Dfunc("s:NetrwBannerCtrl(islocal=".a:islocal.") g:netrw_banner=".g:netrw_banner)
2913
2914  " toggle the banner (enable/suppress)
2915  let g:netrw_banner= !g:netrw_banner
2916
2917  " refresh the listing
2918  let svpos= netrw#NetrwSavePosn()
2919  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
2920
2921  " keep cursor on the filename
2922  let fname= s:NetrwGetWord()
2923  sil keepj $
2924  let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
2925"  call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'))
2926  if result <= 0 && exists("w:netrw_bannercnt")
2927   exe "keepj ".w:netrw_bannercnt
2928  endif
2929"  call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
2930endfun
2931
2932" ---------------------------------------------------------------------
2933" s:NetrwBookmarkMenu: Uses menu priorities {{{2
2934"                      .2.[cnt] for bookmarks, and
2935"                      .3.[cnt] for history
2936"                      (see s:NetrwMenu())
2937fun! s:NetrwBookmarkMenu()
2938  if !exists("s:netrw_menucnt")
2939   return
2940  endif
2941"  call Dfunc("NetrwBookmarkMenu()  histcnt=".g:netrw_dirhist_cnt." menucnt=".s:netrw_menucnt)
2942
2943  " the following test assures that gvim is running, has menus available, and has menus enabled.
2944  if has("gui") && has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
2945   if exists("g:NetrwTopLvlMenu")
2946"    call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)")
2947    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
2948    exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
2949   endif
2950   if !exists("s:netrw_initbookhist")
2951    call s:NetrwBookHistRead()
2952   endif
2953
2954   " show bookmarked places
2955   if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
2956    let cnt= 1
2957    for bmd in g:netrw_bookmarklist
2958"     call Decho('silent! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.'	:e '.bmd)
2959     let bmd= escape(bmd,g:netrw_menu_escape)
2960
2961     " show bookmarks for goto menu
2962     exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.'	:e '.bmd."\<cr>"
2963
2964     " show bookmarks for deletion menu
2965     exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.'	'.cnt."mB"
2966     let cnt= cnt + 1
2967    endfor
2968
2969   endif
2970
2971   " show directory browsing history
2972   let cnt     = g:netrw_dirhist_cnt
2973   let first   = 1
2974   let histcnt = 0
2975   while ( first || cnt != g:netrw_dirhist_cnt )
2976    let histcnt  = histcnt + 1
2977    let priority = g:netrw_dirhist_cnt + histcnt
2978    if exists("g:netrw_dirhist_{cnt}")
2979     let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
2980"     call Decho('silent! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir)
2981     exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.'	:e '.histdir."\<cr>"
2982    endif
2983    let first = 0
2984    let cnt   = ( cnt - 1 ) % g:netrw_dirhistmax
2985    if cnt < 0
2986     let cnt= cnt + g:netrw_dirhistmax
2987    endif
2988   endwhile
2989
2990  endif
2991"  call Dret("NetrwBookmarkMenu")
2992endfun
2993
2994" ---------------------------------------------------------------------
2995"  s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
2996"                       directory and a new directory name.  Also, if the
2997"                       "new directory name" is actually a file,
2998"                       NetrwBrowseChgDir() edits the file.
2999fun! s:NetrwBrowseChgDir(islocal,newdir,...)
3000"  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 : "").">")
3001
3002  if !exists("b:netrw_curdir")
3003   " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
3004   " and the current window is the NetrwMessage window.
3005"   call Decho("(NetrwBrowseChgDir) b:netrw_curdir doesn't exist!")
3006"   call Decho("getcwd<".getcwd().">")
3007"   call Dredir("ls!")
3008"   call Dret("s:NetrwBrowseChgDir")
3009   return
3010  endif
3011
3012  call s:NetrwOptionSave("s:")
3013  call s:NetrwSafeOptions()
3014  let nbcd_curpos                = netrw#NetrwSavePosn()
3015  let s:nbcd_curpos_{bufnr('%')} = nbcd_curpos
3016  if (has("win32") || has("win95") || has("win64") || has("win16"))
3017   let dirname                   = substitute(b:netrw_curdir,'\\','/','ge')
3018  else
3019   let dirname= b:netrw_curdir
3020  endif
3021  let newdir    = a:newdir
3022  let dolockout = 0
3023
3024  " set up o/s-dependent directory recognition pattern
3025  if has("amiga")
3026   let dirpat= '[\/:]$'
3027  else
3028   let dirpat= '[\/]$'
3029  endif
3030"  call Decho("dirname<".dirname.">  dirpat<".dirpat.">")
3031
3032  if dirname !~ dirpat
3033   " apparently vim is "recognizing" that it is in a directory and
3034   " is removing the trailing "/".  Bad idea, so I put it back.
3035   let dirname= dirname.'/'
3036"   call Decho("adjusting dirname<".dirname.">")
3037  endif
3038
3039  if newdir !~ dirpat
3040   " ------------
3041   " edit a file:
3042   " ------------
3043"   call Decho('case "handling a file": newdir<'.newdir.'> !~ dirpat<'.dirpat.">")
3044   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
3045    let dirname= s:NetrwTreeDir()
3046    if dirname =~ '/$'
3047     let dirname= dirname.newdir
3048    else
3049     let dirname= s:NetrwTreeDir()."/".newdir
3050    endif
3051"    call Decho("dirname<".dirname.">")
3052"    call Decho("tree listing")
3053   elseif newdir =~ '^\(/\|\a:\)'
3054    let dirname= newdir
3055   else
3056    let dirname= s:ComposePath(dirname,newdir)
3057   endif
3058"   call Decho("handling a file: dirname<".dirname."> (a:0=".a:0.")")
3059   " this lets NetrwBrowseX avoid the edit
3060   if a:0 < 1
3061"    call Decho("set up windows for editing<".fnameescape(dirname).">  didsplit=".(exists("s:didsplit")? s:didsplit : "doesn't exist"))
3062    call s:NetrwOptionRestore("s:")
3063    if !exists("s:didsplit")
3064     if     g:netrw_browse_split == 1
3065      new
3066      if !&ea
3067       wincmd _
3068      endif
3069     elseif g:netrw_browse_split == 2
3070      rightb vert new
3071      if !&ea
3072       wincmd |
3073      endif
3074     elseif g:netrw_browse_split == 3
3075      tabnew
3076     elseif g:netrw_browse_split == 4
3077      if s:NetrwPrevWinOpen(2) == 3
3078"       call Dret("s:NetrwBrowseChgDir")
3079       return
3080      endif
3081     else
3082      " handling a file, didn't split, so remove menu
3083"      call Decho("handling a file+didn't split, so remove menu")
3084      call s:NetrwMenu(0)
3085      " optional change to window
3086      if g:netrw_chgwin >= 1
3087       exe "keepjumps ".g:netrw_chgwin."wincmd w"
3088      endif
3089     endif
3090    endif
3091
3092    " the point where netrw actually edits the (local) file
3093    " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
3094    if a:islocal
3095"     call Decho("edit local file: exe e! ".fnameescape(dirname))
3096     exe "e! ".fnameescape(dirname)
3097    else
3098"     call Decho("remote file: NetrwBrowse will edit it")
3099    endif
3100    let dolockout= 1
3101
3102    " handle g:Netrw_funcref -- call external-to-netrw functions
3103    "   This code will handle g:Netrw_funcref as an individual function reference
3104    "   or as a list of function references.  It will ignore anything that's not
3105    "   a function reference.  See  :help Funcref  for information about function references.
3106    if exists("g:Netrw_funcref")
3107"     call Decho("handle optional Funcrefs")
3108     if type(g:Netrw_funcref) == 2
3109"      call Decho("handling a g:Netrw_funcref")
3110      call g:Netrw_funcref()
3111     elseif type(g:Netrw_funcref) == 3
3112"      call Decho("handling a list of g:Netrw_funcrefs")
3113      for Fncref in g:Netrw_funcref
3114       if type(FncRef) == 2
3115        call FncRef()
3116       endif
3117      endfor
3118     endif
3119    endif
3120   endif
3121
3122  elseif newdir =~ '^/'
3123   " ---------------------------------
3124   " just go to the new directory spec
3125   " ---------------------------------
3126"   call Decho('case "just go to new directory spec": newdir<'.newdir.'>')
3127   let dirname= newdir
3128   call s:SetRexDir(a:islocal,dirname)
3129   call s:NetrwOptionRestore("s:")
3130
3131  elseif newdir == './'
3132   " --------------------------
3133   " refresh the directory list
3134   " --------------------------
3135"   call Decho('case "refresh directory listing": newdir == "./"')
3136   call s:SetRexDir(a:islocal,dirname)
3137
3138  elseif newdir == '../'
3139   " -------------------
3140   " go up one directory
3141   " -------------------
3142"   call Decho('case "go up one directory": newdir == "../"')
3143
3144   if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
3145    " force a refresh
3146"    call Decho("clear buffer<".expand("%")."> with :%d")
3147    setlocal noro ma
3148"    call Decho("setlocal noro ma")
3149    keepj %d
3150   endif
3151
3152   if has("amiga")
3153    " amiga
3154"    call Decho('case "go up one directory": newdir == "../" and amiga')
3155    if a:islocal
3156     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
3157     let dirname= substitute(dirname,'/$','','')
3158    else
3159     let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
3160    endif
3161"    call Decho("amiga: dirname<".dirname."> (go up one dir)")
3162
3163   else
3164    " unix or cygwin
3165"    call Decho('case "go up one directory": newdir == "../" and unix or cygwin')
3166    if a:islocal
3167     let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
3168     if dirname == ""
3169      let dirname= '/'
3170     endif
3171    else
3172     let dirname= substitute(dirname,'^\(\a\+://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
3173    endif
3174"    call Decho("unix: dirname<".dirname."> (go up one dir)")
3175   endif
3176   call s:SetRexDir(a:islocal,dirname)
3177
3178  elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
3179"   call Decho('case liststyle is TREELIST and w:netrw_treedict exists')
3180   " force a refresh (for TREELIST, wait for NetrwTreeDir() to force the refresh)
3181   setlocal noro ma
3182"   call Decho("setlocal noro ma")
3183   if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
3184"    call Decho("clear buffer<".expand("%")."> with :%d")
3185    keepj %d
3186   endif
3187   let treedir      = s:NetrwTreeDir()
3188   let s:treecurpos = nbcd_curpos
3189   let haskey= 0
3190"   call Decho("w:netrw_treedict<".string(w:netrw_treedict).">")
3191
3192   " search treedict for tree dir as-is
3193   if has_key(w:netrw_treedict,treedir)
3194"    call Decho('....searched for treedir<'.treedir.'> : found it!')
3195    let haskey= 1
3196   else
3197"    call Decho('....searched for treedir<'.treedir.'> : not found')
3198   endif
3199
3200   " search treedict for treedir with a / appended
3201   if !haskey && treedir !~ '/$'
3202    if has_key(w:netrw_treedict,treedir."/")
3203     let treedir= treedir."/"
3204"     call Decho('....searched.for treedir<'.treedir.'> found it!')
3205     let haskey = 1
3206    else
3207"     call Decho('....searched for treedir<'.treedir.'/> : not found')
3208    endif
3209   endif
3210
3211   " search treedict for treedir with any trailing / elided
3212   if !haskey && treedir =~ '/$'
3213    let treedir= substitute(treedir,'/$','','')
3214    if has_key(w:netrw_treedict,treedir)
3215"     call Decho('....searched.for treedir<'.treedir.'> found it!')
3216     let haskey = 1
3217    else
3218"     call Decho('....searched for treedir<'.treedir.'> : not found')
3219    endif
3220   endif
3221
3222   if haskey
3223    " close tree listing for selected subdirectory
3224"    call Decho("closing selected subdirectory<".dirname.">")
3225    call remove(w:netrw_treedict,treedir)
3226"    call Decho("removed     entry<".treedir."> from treedict")
3227"    call Decho("yielding treedict<".string(w:netrw_treedict).">")
3228    let dirname= w:netrw_treetop
3229   else
3230    " go down one directory
3231    let dirname= substitute(treedir,'/*$','/','')
3232"    call Decho("go down one dir: treedir<".treedir.">")
3233   endif
3234   call s:SetRexDir(a:islocal,dirname)
3235   let s:treeforceredraw = 1
3236
3237  else
3238   " go down one directory
3239   let dirname= s:ComposePath(dirname,newdir)
3240"   call Decho("go down one dir: dirname<".dirname."> newdir<".newdir.">")
3241   call s:SetRexDir(a:islocal,dirname)
3242  endif
3243
3244  call s:NetrwOptionRestore("s:")
3245  if dolockout
3246"   call Decho("filewritable(dirname<".dirname.">)=".filewritable(dirname))
3247   if filewritable(dirname)
3248"    call Decho("doing modification lockout settings: ma nomod noro")
3249    setlocal ma nomod noro
3250   else
3251"    call Decho("doing modification lockout settings: ma nomod ro")
3252    setlocal ma nomod ro
3253   endif
3254"   call Decho("setlocal ma nomod noro")
3255  endif
3256
3257"  call Dret("s:NetrwBrowseChgDir <".dirname."> : curpos<".string(getpos(".")).">")
3258  return dirname
3259endfun
3260
3261" ---------------------------------------------------------------------
3262" s:NetrwBrowseX:  (implements "x") executes a special "viewer" script or program for the {{{2
3263"              given filename; typically this means given their extension.
3264"              0=local, 1=remote
3265fun! netrw#NetrwBrowseX(fname,remote)
3266"  call Dfunc("NetrwBrowseX(fname<".a:fname."> remote=".a:remote.")")
3267
3268  " special core dump handler
3269  if a:fname =~ '/core\(\.\d\+\)\=$'
3270   if exists("g:Netrw_corehandler")
3271    if type(g:Netrw_corehandler) == 2
3272     " g:Netrw_corehandler is a function reference (see :help Funcref)
3273"     call Decho("g:Netrw_corehandler is a funcref")
3274     call g:Netrw_corehandler(a:fname)
3275    elseif type(g:netrw_corehandler) == 3)
3276     " g:Netrw_corehandler is a List of function references (see :help Funcref)
3277"     call Decho("g:Netrw_corehandler is a List")
3278     for Fncref in g:Netrw_corehandler
3279      if type(FncRef) == 2
3280       call FncRef(a:fname)
3281      endif
3282     endfor
3283    endif
3284"    call Dret("NetrwBrowseX : coredump handler invoked")
3285    return
3286   endif
3287  endif
3288
3289  " set up the filename
3290  " (lower case the extension, make a local copy of a remote file)
3291  let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
3292  if has("win32") || has("win95") || has("win64") || has("win16")
3293   let exten= substitute(exten,'^.*$','\L&\E','')
3294  endif
3295"  call Decho("exten<".exten.">")
3296
3297  " seems kde systems often have gnome-open due to dependencies, even though
3298  " gnome-open's subsidiary display tools are largely absent.  Kde systems
3299  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
3300  if !exists("s:haskdeinit")
3301   if has("unix")
3302    let s:haskdeinit= system("ps -e") =~ 'kdeinit' 
3303    if v:shell_error
3304     let s:haskdeinit = 0
3305    endif
3306   else
3307    let s:haskdeinit= 0
3308   endif
3309"   call Decho("setting s:haskdeinit=".s:haskdeinit)
3310  endif
3311
3312  if a:remote == 1
3313   " create a local copy
3314"   call Decho("a:remote=".a:remote.": create a local copy of <".a:fname.">")
3315   setlocal bh=delete
3316   call netrw#NetRead(3,a:fname)
3317   " attempt to rename tempfile
3318   let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
3319   let newname= substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
3320"   call Decho("basename<".basename.">")
3321"   call Decho("newname <".newname.">")
3322   if rename(s:netrw_tmpfile,newname) == 0
3323    " renaming succeeded
3324    let fname= newname
3325   else
3326    " renaming failed
3327    let fname= s:netrw_tmpfile
3328   endif
3329  else
3330   let fname= a:fname
3331   " special ~ handler for local
3332   if fname =~ '^\~' && expand("$HOME") != ""
3333"    call Decho('invoking special ~ handler')
3334    let fname= substitute(fname,'^\~',expand("$HOME"),'')
3335   endif
3336  endif
3337"  call Decho("fname<".fname.">")
3338"  call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten))
3339
3340  " set up redirection
3341  if &srr =~ "%s"
3342   if (has("win32") || has("win95") || has("win64") || has("win16"))
3343    let redir= substitute(&srr,"%s","nul","")
3344   else
3345    let redir= substitute(&srr,"%s","/dev/null","")
3346   endif
3347  elseif (has("win32") || has("win95") || has("win64") || has("win16"))
3348   let redir= &srr . "nul"
3349  else
3350   let redir= &srr . "/dev/null"
3351  endif
3352"  call Decho("redir{".redir."} srr{".&srr."}")
3353
3354  " extract any viewing options.  Assumes that they're set apart by quotes.
3355  if exists("g:netrw_browsex_viewer")
3356"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">")
3357   if g:netrw_browsex_viewer =~ '\s'
3358    let viewer  = substitute(g:netrw_browsex_viewer,'\s.*$','','')
3359    let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
3360    let oviewer = ''
3361    let cnt     = 1
3362    while !executable(viewer) && viewer != oviewer
3363     let viewer  = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
3364     let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
3365     let cnt     = cnt + 1
3366     let oviewer = viewer
3367"     call Decho("!exe: viewer<".viewer.">  viewopt<".viewopt.">")
3368    endwhile
3369   else
3370    let viewer  = g:netrw_browsex_viewer
3371    let viewopt = ""
3372   endif
3373"   call Decho("viewer<".viewer.">  viewopt<".viewopt.">")
3374  endif
3375
3376  " execute the file handler
3377  if exists("g:netrw_browsex_viewer") && g:netrw_browsex_viewer == '-'
3378"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">")
3379   let ret= netrwFileHandlers#Invoke(exten,fname)
3380
3381  elseif exists("g:netrw_browsex_viewer") && executable(viewer)
3382"   call Decho("g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">")
3383"   call Decho("exe silent !".viewer." ".viewopt.shellescape(fname,1).redir)
3384   exe "silent !".viewer." ".viewopt.shellescape(fname,1).redir
3385   let ret= v:shell_error
3386
3387  elseif has("win32") || has("win64")
3388   if executable("start")
3389"    call Decho('exe silent !start rundll32 url.dll,FileProtocolHandler '.shellescape(fname,1))
3390    exe 'silent !start rundll32 url.dll,FileProtocolHandler '.shellescape(fname,1)
3391   elseif executable("rundll32")
3392"    call Decho('exe silent !rundll32 url.dll,FileProtocolHandler '.shellescape(fname,1))
3393    exe 'silent !rundll32 url.dll,FileProtocolHandler '.shellescape(fname,1)
3394   else
3395    call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
3396   endif
3397   call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3398   let ret= v:shell_error
3399
3400  elseif has("unix") && executable("gnome-open") && !s:haskdeinit
3401"   call Decho("exe silent !gnome-open ".shellescape(fname,1)." ".redir)
3402   exe "sil !gnome-open ".shellescape(fname,1).redir
3403   let ret= v:shell_error
3404
3405  elseif has("unix") && executable("kfmclient") && s:haskdeinit
3406"   call Decho("exe silent !kfmclient exec ".shellescape(fname,1)." ".redir)
3407   exe "sil !kfmclient exec ".shellescape(fname,1)." ".redir
3408   let ret= v:shell_error
3409
3410  elseif has("macunix") && executable("open")
3411"   call Decho("exe silent !open ".shellescape(fname,1)." ".redir)
3412   exe "sil !open ".shellescape(fname,1)." ".redir
3413   let ret= v:shell_error
3414
3415  else
3416   " netrwFileHandlers#Invoke() always returns 0
3417   let ret= netrwFileHandlers#Invoke(exten,fname)
3418  endif
3419
3420  " if unsuccessful, attempt netrwFileHandlers#Invoke()
3421  if ret
3422   let ret= netrwFileHandlers#Invoke(exten,fname)
3423  endif
3424
3425  " restoring redraw! after external file handlers
3426  redraw!
3427
3428  " cleanup: remove temporary file,
3429  "          delete current buffer if success with handler,
3430  "          return to prior buffer (directory listing)
3431  "          Feb 12, 2008: had to de-activiate removal of
3432  "          temporary file because it wasn't getting seen.
3433"  if a:remote == 1 && fname != a:fname
3434"   call Decho("deleting temporary file<".fname.">")
3435"   call s:NetrwDelete(fname)
3436"  endif
3437
3438  if a:remote == 1
3439   setlocal bh=delete bt=nofile
3440   if g:netrw_use_noswf
3441    setlocal noswf
3442   endif
3443   exe "keepj norm! \<c-o>"
3444"   redraw!
3445  endif
3446
3447"  call Dret("NetrwBrowseX")
3448endfun
3449
3450" ---------------------------------------------------------------------
3451" s:NetrwChgPerm: (implements "gp") change file permission {{{2
3452fun! s:NetrwChgPerm(islocal,curdir)
3453"  call Dfunc("s:NetrwChgPerm(islocal=".a:islocal." curdir<".a:curdir.">)")
3454  call inputsave()
3455  let newperm= input("Enter new permission: ")
3456  call inputrestore()
3457  let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',shellescape(expand("<cfile>")),'')
3458  let chgperm= substitute(chgperm,'\<PERM\>',shellescape(newperm),'')
3459"  call Decho("chgperm<".chgperm.">")
3460  call system(chgperm)
3461  if v:shell_error != 0
3462   call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
3463  endif
3464  if a:islocal
3465   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
3466  endif
3467"  call Dret("s:NetrwChgPerm")
3468endfun
3469
3470" ---------------------------------------------------------------------
3471" s:NetrwClearExplore: clear explore variables (if any) {{{2
3472fun! s:NetrwClearExplore()
3473"  call Dfunc("s:NetrwClearExplore()")
3474  2match none
3475  if exists("s:explore_match")        |unlet s:explore_match        |endif
3476  if exists("s:explore_indx")         |unlet s:explore_indx         |endif
3477  if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
3478  if exists("s:dirstarstar")          |unlet s:dirstarstar          |endif
3479  if exists("s:explore_prvdir")       |unlet s:explore_prvdir       |endif
3480  if exists("w:netrw_explore_indx")   |unlet w:netrw_explore_indx   |endif
3481  if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
3482  if exists("w:netrw_explore_list")   |unlet w:netrw_explore_list   |endif
3483  if exists("w:netrw_explore_bufnr")  |unlet w:netrw_explore_bufnr  |endif
3484"   redraw!
3485  echo " "
3486  echo " "
3487"  call Dret("s:NetrwClearExplore")
3488endfun
3489
3490" ---------------------------------------------------------------------
3491" netrw#Explore: launch the local browser in the directory of the current file {{{2
3492"          indx:  == -1: Nexplore
3493"                 == -2: Pexplore
3494"                 ==  +: this is overloaded:
3495"                      * If Nexplore/Pexplore is in use, then this refers to the
3496"                        indx'th item in the w:netrw_explore_list[] of items which
3497"                        matched the */pattern **/pattern *//pattern **//pattern
3498"                      * If Hexplore or Vexplore, then this will override
3499"                        g:netrw_winsize to specify the qty of rows or columns the
3500"                        newly split window should have.
3501"          dosplit==0: the window will be split iff the current file has been modified
3502"          dosplit==1: the window will be split before running the local browser
3503"          style == 0: Explore     style == 1: Explore!
3504"                == 2: Hexplore    style == 3: Hexplore!
3505"                == 4: Vexplore    style == 5: Vexplore!
3506"                == 6: Texplore
3507fun! netrw#Explore(indx,dosplit,style,...)
3508"  call Dfunc("netrw#Explore(indx=".a:indx." dosplit=".a:dosplit." style=".a:style.",a:1<".a:1.">) &modified=".&modified." a:0=".a:0)
3509  if !exists("b:netrw_curdir")
3510   let b:netrw_curdir= getcwd()
3511"   call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)")
3512  endif
3513  let curdir     = simplify(b:netrw_curdir)
3514  let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
3515"  call Decho("curdir<".curdir.">  curfiledir<".curfiledir.">")
3516
3517  " save registers
3518  sil! let keepregstar = @*
3519  sil! let keepregplus = @+
3520  sil! let keepregslash= @/
3521
3522  " if dosplit or file has been modified
3523  if a:dosplit || &modified || a:style == 6
3524"   call Decho("case dosplit=".a:dosplit." modified=".&modified." a:style=".a:style.": dosplit or file has been modified")
3525   call s:SaveWinVars()
3526   let winsize= g:netrw_winsize
3527   if a:indx > 0
3528    let winsize= a:indx
3529   endif
3530
3531   if a:style == 0      " Explore, Sexplore
3532"    call Decho("style=0: Explore or Sexplore")
3533    exe winsize."wincmd s"
3534
3535   elseif a:style == 1  "Explore!, Sexplore!
3536"    call Decho("style=1: Explore! or Sexplore!")
3537    exe winsize."wincmd v"
3538
3539   elseif a:style == 2  " Hexplore
3540"    call Decho("style=2: Hexplore")
3541    exe "bel ".winsize."wincmd s"
3542
3543   elseif a:style == 3  " Hexplore!
3544"    call Decho("style=3: Hexplore!")
3545    exe "abo ".winsize."wincmd s"
3546
3547   elseif a:style == 4  " Vexplore
3548"    call Decho("style=4: Vexplore")
3549    exe "lefta ".winsize."wincmd v"
3550
3551   elseif a:style == 5  " Vexplore!
3552"    call Decho("style=5: Vexplore!")
3553    exe "rightb ".winsize."wincmd v"
3554
3555   elseif a:style == 6  " Texplore
3556    call s:SaveBufVars()
3557"    call Decho("style  = 6: Texplore")
3558    tabnew
3559    call s:RestoreBufVars()
3560   endif
3561   call s:RestoreWinVars()
3562"  else " Decho
3563"   call Decho("case a:dosplit=".a:dosplit." AND modified=".&modified." AND a:style=".a:style." is not 6")
3564  endif
3565  keepj norm! 0
3566
3567  if a:0 > 0
3568"   call Decho("case [a:0=".a:0."] > 0: a:1<".a:1.">")
3569   if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
3570"    call Decho("case a:1: ~ and unix or cygwin")
3571    let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
3572"    call Decho("using dirname<".dirname.">  (case: ~ && unix||cygwin)")
3573   elseif a:1 == '.'
3574"    call Decho("case a:1: .")
3575    let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
3576    if dirname !~ '/$'
3577     let dirname= dirname."/"
3578    endif
3579"    call Decho("using dirname<".dirname.">  (case: ".(exists("b:netrw_curdir")? "b:netrw_curdir" : "getcwd()").")")
3580   elseif a:1 =~ '\$'
3581"    call Decho("case a:1: $")
3582    let dirname= simplify(expand(a:1))
3583"    call Decho("using user-specified dirname<".dirname."> with $env-var")
3584   elseif a:1 !~ '^\*/'
3585"    call Decho("case a:1: other, not pattern or filepattern")
3586    let dirname= simplify(a:1)
3587"    call Decho("using user-specified dirname<".dirname.">")
3588   else
3589"    call Decho("case a:1: pattern or filepattern")
3590    let dirname= a:1
3591   endif
3592  else
3593   " clear explore
3594"   call Decho("case a:0=".a:0.": clearing Explore list")
3595   call s:NetrwClearExplore()
3596"   call Dret("netrw#Explore : cleared list")
3597   return
3598  endif
3599
3600"  call Decho("dirname<".dirname.">")
3601  if dirname =~ '\.\./\=$'
3602   let dirname= simplify(fnamemodify(dirname,':p:h'))
3603  elseif dirname =~ '\.\.' || dirname == '.'
3604   let dirname= simplify(fnamemodify(dirname,':p'))
3605  endif
3606"  call Decho("dirname<".dirname.">  (after simplify)")
3607
3608  if dirname =~ '/\*\*/'
3609   " handle .../**/.../filepat
3610"   call Decho("case Explore .../**/.../filepat")
3611   let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
3612   if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && (has("win32") || has("win95") || has("win64") || has("win16")))
3613    let b:netrw_curdir = prefixdir
3614   else
3615    let b:netrw_curdir= getcwd().'/'.prefixdir
3616   endif
3617   let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
3618   let starpat= 4;
3619"   call Decho("pwd<".getcwd()."> dirname<".dirname.">")
3620"   call Decho("case Explore ../**/../filepat (starpat=".starpat.")")
3621
3622  elseif dirname =~ '^\*//'
3623   " starpat=1: Explore *//pattern   (current directory only search for files containing pattern)
3624"   call Decho("case Explore *//pattern")
3625   let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
3626   let starpat= 1
3627"   call Decho("Explore *//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">")
3628   if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
3629
3630  elseif dirname =~ '^\*\*//'
3631   " starpat=2: Explore **//pattern  (recursive descent search for files containing pattern)
3632"   call Decho("case Explore **//pattern")
3633   let pattern= substitute(dirname,'^\*\*//','','')
3634   let starpat= 2
3635"   call Decho("Explore **//pat: (starpat=".starpat.") dirname<".dirname."> -> pattern<".pattern.">")
3636
3637  elseif dirname =~ '^\*/'
3638   " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
3639   let starpat= 3
3640"   call Decho("case Explore */filepat (starpat=".starpat.")")
3641
3642  elseif dirname=~ '^\*\*/'
3643   " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
3644   let starpat= 4
3645"   call Decho("case Explore **/filepat (starpat=".starpat.")")
3646
3647  else
3648   let starpat= 0
3649"   call Decho("default case: starpat=".starpat)
3650  endif
3651
3652  if starpat == 0 && a:indx >= 0
3653   " [Explore Hexplore Vexplore Sexplore] [dirname]
3654"   call Decho("case starpat==0 && a:indx=".a:indx.": dirname<".dirname."> Explore Hexplore Vexplore Sexplore")
3655   if dirname == ""
3656    let dirname= curfiledir
3657"    call Decho("empty dirname, using current file's directory<".dirname.">")
3658   endif
3659   if dirname =~ '^scp:' || dirname =~ '^ftp:'
3660"    call Decho("calling NetrwBrowse(0,dirname<".dirname.">)")
3661    call s:NetrwBrowse(0,dirname)
3662   else
3663    if dirname == ""|let dirname= getcwd()|endif
3664"    call Decho("calling LocalBrowseCheck(dirname<".dirname.">)")
3665    call netrw#LocalBrowseCheck(dirname)
3666   endif
3667
3668"   call Decho("curdir<".curdir.">")
3669   if has("win32") || has("win95") || has("win64") || has("win16")
3670    keepj call search('\<'.substitute(curdir,'^.*[/\\]','','e').'\>','cW')
3671   else
3672    keepj call search('\<'.substitute(curdir,'^.*/','','e').'\>','cW')
3673   endif
3674
3675  " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
3676  " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
3677  " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
3678  " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
3679  elseif a:indx <= 0
3680   " Nexplore, Pexplore, Explore: handle starpat
3681"   call Decho("case a:indx<=0: Nexplore, Pexplore, <s-down>, <s-up> starpat=".starpat." a:indx=".a:indx)
3682   if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
3683"    call Decho("set up <s-up> and <s-down> maps")
3684    let s:didstarstar= 1
3685    nnoremap <buffer> <silent> <s-up>	:Pexplore<cr>
3686    nnoremap <buffer> <silent> <s-down>	:Nexplore<cr>
3687   endif
3688
3689   if has("path_extra")
3690"    call Decho("starpat=".starpat.": has +path_extra")
3691    if !exists("w:netrw_explore_indx")
3692     let w:netrw_explore_indx= 0
3693    endif
3694
3695    let indx = a:indx
3696"    call Decho("starpat=".starpat.": set indx= [a:indx=".indx."]")
3697
3698    if indx == -1
3699     " Nexplore
3700"     call Decho("case Nexplore with starpat=".starpat.": (indx=".indx.")")
3701     if !exists("w:netrw_explore_list") " sanity check
3702      call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
3703      sil! let @* = keepregstar
3704      sil! let @+ = keepregstar
3705      sil! let @/ = keepregslash
3706"      call Dret("netrw#Explore")
3707      return
3708     endif
3709     let indx= w:netrw_explore_indx
3710     if indx < 0                        | let indx= 0                           | endif
3711     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
3712     let curfile= w:netrw_explore_list[indx]
3713"     call Decho("indx=".indx." curfile<".curfile.">")
3714     while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
3715      let indx= indx + 1
3716"      call Decho("indx=".indx." (Nexplore while loop)")
3717     endwhile
3718     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
3719"     call Decho("Nexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx)
3720
3721    elseif indx == -2
3722     " Pexplore
3723"     call Decho("case Pexplore with starpat=".starpat.": (indx=".indx.")")
3724     if !exists("w:netrw_explore_list") " sanity check
3725      call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
3726      sil! let @* = keepregstar
3727      sil! let @+ = keepregstar
3728      sil! let @/ = keepregslash
3729"      call Dret("netrw#Explore")
3730      return
3731     endif
3732     let indx= w:netrw_explore_indx
3733     if indx < 0                        | let indx= 0                           | endif
3734     if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
3735     let curfile= w:netrw_explore_list[indx]
3736"     call Decho("indx=".indx." curfile<".curfile.">")
3737     while indx >= 0 && curfile == w:netrw_explore_list[indx]
3738      let indx= indx - 1
3739"      call Decho("indx=".indx." (Pexplore while loop)")
3740     endwhile
3741     if indx < 0                        | let indx= 0                           | endif
3742"     call Decho("Pexplore: indx= [w:netrw_explore_indx=".w:netrw_explore_indx."]=".indx)
3743
3744    else
3745     " Explore -- initialize
3746     " build list of files to Explore with Nexplore/Pexplore
3747"     call Decho("starpat=".starpat.": case Explore: initialize (indx=".indx.")")
3748     call s:NetrwClearExplore()
3749     let w:netrw_explore_indx= 0
3750     if !exists("b:netrw_curdir")
3751      let b:netrw_curdir= getcwd()
3752     endif
3753"     call Decho("starpat=".starpat.": b:netrw_curdir<".b:netrw_curdir.">")
3754
3755     " switch on starpat to build the w:netrw_explore_list of files
3756     if starpat == 1
3757      " starpat=1: Explore *//pattern  (current directory only search for files containing pattern)
3758"      call Decho("starpat=".starpat.": build *//pattern list")
3759"      call Decho("pattern<".pattern.">")
3760      try
3761       exe "keepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
3762      catch /^Vim\%((\a\+)\)\=:E480/
3763       call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
3764"       call Dret("netrw#Explore : unable to find pattern<".pattern.">")
3765       return
3766      endtry
3767      let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
3768      if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
3769
3770     elseif starpat == 2
3771      " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
3772"      call Decho("starpat=".starpat.": build **//pattern list")
3773      try
3774       exe "sil keepj noautocmd vimgrep /".pattern."/gj "."**/*"
3775      catch /^Vim\%((\a\+)\)\=:E480/
3776       call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
3777       if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
3778       silent! let @* = keepregstar
3779       silent! let @+ = keepregstar
3780       silent! let @/ = keepregslash
3781"       call Dret("netrw#Explore : no files matched pattern")
3782       return
3783      endtry
3784      let s:netrw_curdir       = b:netrw_curdir
3785      let w:netrw_explore_list = getqflist()
3786      let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
3787
3788     elseif starpat == 3
3789      " starpat=3: Explore */filepat   (search in current directory for filenames matching filepat)
3790"      call Decho("starpat=".starpat.": build */filepat list")
3791      let filepat= substitute(dirname,'^\*/','','')
3792      let filepat= substitute(filepat,'^[%#<]','\\&','')
3793"      call Decho("b:netrw_curdir<".b:netrw_curdir.">")
3794"      call Decho("filepat<".filepat.">")
3795      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
3796      if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
3797
3798     elseif starpat == 4
3799      " starpat=4: Explore **/filepat  (recursive descent search for filenames matching filepat)
3800"      call Decho("starpat=".starpat.": build **/filepat list")
3801      let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
3802      if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
3803     endif " switch on starpat to build w:netrw_explore_list
3804
3805     let w:netrw_explore_listlen = len(w:netrw_explore_list)
3806"     call Decho("w:netrw_explore_list<".string(w:netrw_explore_list).">")
3807"     call Decho("w:netrw_explore_listlen=".w:netrw_explore_listlen)
3808
3809     if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
3810      call netrw#ErrorMsg(s:WARNING,"no files matched",42)
3811      sil! let @* = keepregstar
3812      sil! let @+ = keepregstar
3813      sil! let @/ = keepregslash
3814"      call Dret("netrw#Explore : no files matched")
3815      return
3816     endif
3817    endif  " if indx ... endif
3818
3819    " NetrwStatusLine support - for exploring support
3820    let w:netrw_explore_indx= indx
3821"    call Decho("w:netrw_explore_list<".join(w:netrw_explore_list,',')."> len=".w:netrw_explore_listlen)
3822
3823    " wrap the indx around, but issue a note
3824    if indx >= w:netrw_explore_listlen || indx < 0
3825"     call Decho("wrap indx (indx=".indx." listlen=".w:netrw_explore_listlen.")")
3826     let indx                = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
3827     let w:netrw_explore_indx= indx
3828     call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
3829    endif
3830
3831    exe "let dirfile= w:netrw_explore_list[".indx."]"
3832"    call Decho("dirfile=w:netrw_explore_list[indx=".indx."]= <".dirfile.">")
3833    let newdir= substitute(dirfile,'/[^/]*$','','e')
3834"    call Decho("newdir<".newdir.">")
3835
3836"    call Decho("calling LocalBrowseCheck(newdir<".newdir.">)")
3837    call netrw#LocalBrowseCheck(newdir)
3838    if !exists("w:netrw_liststyle")
3839     let w:netrw_liststyle= g:netrw_liststyle
3840    endif
3841    if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
3842     keepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
3843    else
3844     keepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
3845    endif
3846    let w:netrw_explore_mtchcnt = indx + 1
3847    let w:netrw_explore_bufnr   = bufnr("%")
3848    let w:netrw_explore_line    = line(".")
3849    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
3850"    call Decho("explore: mtchcnt=".w:netrw_explore_mtchcnt." bufnr=".w:netrw_explore_bufnr." line#".w:netrw_explore_line)
3851
3852   else
3853"    call Decho("your vim does not have +path_extra")
3854    if !exists("g:netrw_quiet")
3855     call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
3856    endif
3857    sil! let @* = keepregstar
3858    sil! let @+ = keepregstar
3859    sil! let @/ = keepregslash
3860"    call Dret("netrw#Explore : missing +path_extra")
3861    return
3862   endif
3863
3864  else
3865"   call Decho("default case: Explore newdir<".dirname.">")
3866   if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
3867    sil! unlet w:netrw_treedict
3868    sil! unlet w:netrw_treetop
3869   endif
3870   let newdir= dirname
3871   if !exists("b:netrw_curdir")
3872    call netrw#LocalBrowseCheck(getcwd())
3873   else
3874    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir))
3875   endif
3876  endif
3877
3878  " visual display of **/ **// */ Exploration files
3879"  call Decho("w:netrw_explore_indx=".(exists("w:netrw_explore_indx")? w:netrw_explore_indx : "doesn't exist"))
3880"  call Decho("b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : "n/a").">")
3881  if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
3882"   call Decho("s:explore_prvdir<".(exists("s:explore_prvdir")? s:explore_prvdir : "-doesn't exist-"))
3883   if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
3884    " only update match list if current directory isn't the same as before
3885"    call Decho("only update match list if current directory not the same as before")
3886    let s:explore_prvdir = b:netrw_curdir
3887    let s:explore_match  = ""
3888    let dirlen           = s:Strlen(b:netrw_curdir)
3889    if b:netrw_curdir !~ '/$'
3890     let dirlen= dirlen + 1
3891    endif
3892    let prvfname= ""
3893    for fname in w:netrw_explore_list
3894"     call Decho("fname<".fname.">")
3895     if fname =~ '^'.b:netrw_curdir
3896      if s:explore_match == ""
3897       let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
3898      else
3899       let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
3900      endif
3901     elseif fname !~ '^/' && fname != prvfname
3902      if s:explore_match == ""
3903       let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
3904      else
3905       let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
3906      endif
3907     endif
3908     let prvfname= fname
3909    endfor
3910"    call Decho("explore_match<".s:explore_match.">")
3911    exe "2match netrwMarkFile /".s:explore_match."/"
3912   endif
3913   echo "<s-up>==Pexplore  <s-down>==Nexplore"
3914  else
3915   2match none
3916   if exists("s:explore_match")  | unlet s:explore_match  | endif
3917   if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
3918   echo " "
3919"   call Decho("cleared explore match list")
3920  endif
3921
3922  sil! let @* = keepregstar
3923  sil! let @+ = keepregstar
3924  sil! let @/ = keepregslash
3925"  call Dret("netrw#Explore : @/<".@/.">")
3926endfun
3927
3928" ---------------------------------------------------------------------
3929" s:NetrwExploreListUniq: {{{2
3930fun! s:NetrwExploreListUniq(explist)
3931"  call Dfunc("s:NetrwExploreListUniq(explist)")
3932
3933  " this assumes that the list is already sorted
3934  let newexplist= []
3935  for member in a:explist
3936   if !exists("uniqmember") || member != uniqmember
3937    let uniqmember = member
3938    let newexplist = newexplist + [ member ]
3939   endif
3940  endfor
3941
3942"  call Dret("s:NetrwExploreListUniq")
3943  return newexplist
3944endfun
3945
3946" ---------------------------------------------------------------------
3947" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
3948"          and switches the hiding mode.  The actual hiding is done by
3949"          s:NetrwListHide().
3950"             g:netrw_hide= 0: show all
3951"                           1: show not-hidden files
3952"                           2: show hidden files only
3953fun! s:NetrwHide(islocal)
3954"  call Dfunc("NetrwHide(islocal=".a:islocal.") g:netrw_hide=".g:netrw_hide)
3955  let svpos= netrw#NetrwSavePosn()
3956
3957  if exists("s:netrwmarkfilelist_{bufnr('%')}")
3958"   call Decho(((g:netrw_hide == 1)? "unhide" : "hide")." files in markfilelist<".string(s:netrwmarkfilelist_{bufnr("%")}).">")
3959"   call Decho("g:netrw_list_hide<".g:netrw_list_hide.">")
3960
3961   " hide the files in the markfile list
3962   for fname in s:netrwmarkfilelist_{bufnr("%")}
3963"    call Decho("match(g:netrw_list_hide<".g:netrw_list_hide.'> fname<\<'.fname.'\>>)='.match(g:netrw_list_hide,'\<'.fname.'\>')." isk=".&isk)
3964    if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
3965     " remove fname from hiding list
3966     let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
3967     let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
3968     let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
3969"     call Decho("unhide: g:netrw_list_hide<".g:netrw_list_hide.">")
3970    else
3971     " append fname to hiding list
3972     if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
3973      let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
3974     else
3975      let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
3976     endif
3977"     call Decho("hide: g:netrw_list_hide<".g:netrw_list_hide.">")
3978    endif
3979   endfor
3980   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
3981   let g:netrw_hide= 1
3982
3983  else
3984
3985   " switch between show-all/show-not-hidden/show-hidden
3986   let g:netrw_hide=(g:netrw_hide+1)%3
3987   exe "keepj norm! 0"
3988   if g:netrw_hide && g:netrw_list_hide == ""
3989    call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
3990"    call Dret("NetrwHide")
3991    return
3992   endif
3993  endif
3994
3995  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
3996  call netrw#NetrwRestorePosn(svpos)
3997"  call Dret("NetrwHide")
3998endfun
3999
4000" ---------------------------------------------------------------------
4001" s:NetrwHidden: invoked by "gh" {{{2
4002fun! s:NetrwHidden(islocal)
4003"  call Dfunc("s:NetrwHidden()")
4004  "  save current position
4005  let svpos= netrw#NetrwSavePosn()
4006
4007  if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
4008   " remove pattern from hiding list
4009   let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
4010  elseif s:Strlen(g:netrw_list_hide) >= 1
4011   let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
4012  else
4013   let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
4014  endif
4015
4016  " refresh screen and return to saved position
4017  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4018  call netrw#NetrwRestorePosn(svpos)
4019"  call Dret("s:NetrwHidden")
4020endfun
4021
4022" ---------------------------------------------------------------------
4023"  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
4024fun! s:NetrwHome()
4025  if exists("g:netrw_home")
4026   let home= g:netrw_home
4027  else
4028   " go to vim plugin home
4029   for home in split(&rtp,',') + ['']
4030    if isdirectory(home) && filewritable(home) | break | endif
4031     let basehome= substitute(home,'[/\\]\.vim$','','')
4032    if isdirectory(basehome) && filewritable(basehome)
4033     let home= basehome."/.vim"
4034     break
4035    endif
4036   endfor
4037   if home == ""
4038    " just pick the first directory
4039    let home= substitute(&rtp,',.*$','','')
4040   endif
4041   if (has("win32") || has("win95") || has("win64") || has("win16"))
4042    let home= substitute(home,'/','\\','g')
4043   endif
4044  endif
4045  " insure that the home directory exists
4046  if !isdirectory(home)
4047   if exists("g:netrw_mkdir")
4048    call system(g:netrw_mkdir." ".shellescape(home))
4049   else
4050    call mkdir(home)
4051   endif
4052  endif
4053  let g:netrw_home= home
4054  return home
4055endfun
4056
4057" ---------------------------------------------------------------------
4058" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
4059fun! s:NetrwLeftmouse(islocal)
4060"  call Dfunc("s:NetrwLeftmouse(islocal=".a:islocal.")")
4061
4062  " check if the status bar was clicked on instead of a file/directory name
4063  call feedkeys("\<LeftMouse>")
4064  let c= getchar()
4065  let mouse_lnum = v:mouse_lnum
4066  let wlastline  = line('w$')
4067  let lastline   = line('$')
4068"  call Decho("v:mouse_lnum=".mouse_lnum." line(w$)=".wlastline." line($)=".lastline." v:mouse_win=".v:mouse_win." winnr#".winnr())
4069"  call Decho("v:mouse_col =".v:mouse_col."     col=".col(".")."  wincol =".wincol()." winwidth   =".winwidth(0))
4070  if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
4071   " appears to be a status bar leftmouse click
4072"   call Dret("s:NetrwLeftmouse : detected a status bar leftmouse click")
4073   return
4074  endif
4075  if v:mouse_col != col('.')
4076"   call Dret("s:NetrwLeftmouse : detected a vertical separator bar leftmouse click")
4077   return
4078  endif
4079
4080  if a:islocal
4081   if exists("b:netrw_curdir")
4082    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
4083   endif
4084  else
4085   if exists("b:netrw_curdir")
4086    call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
4087   endif
4088  endif
4089"  call Dret("s:NetrwLeftmouse")
4090endfun
4091
4092" ---------------------------------------------------------------------
4093" s:NetrwListHide: uses [range]g~...~d to delete files that match comma {{{2
4094" separated patterns given in g:netrw_list_hide
4095fun! s:NetrwListHide()
4096"  call Dfunc("NetrwListHide() hide=".g:netrw_hide." listhide<".g:netrw_list_hide.">")
4097
4098  " find a character not in the "hide" string to use as a separator for :g and :v commands
4099  " How-it-works: take the hiding command, convert it into a range.  Duplicate
4100  " characters don't matter.  Remove all such characters from the '/~...90'
4101  " string.  Use the first character left as a separator character.
4102  let listhide= g:netrw_list_hide
4103  let sep     = strpart(substitute('/~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
4104"  call Decho("sep=".sep)
4105
4106  while listhide != ""
4107   if listhide =~ ','
4108    let hide     = substitute(listhide,',.*$','','e')
4109    let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
4110   else
4111    let hide     = listhide
4112    let listhide = ""
4113   endif
4114
4115   " Prune the list by hiding any files which match
4116   if g:netrw_hide == 1
4117"    call Decho("hiding<".hide."> listhide<".listhide.">")
4118    exe 'sil keepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
4119   elseif g:netrw_hide == 2
4120"    call Decho("showing<".hide."> listhide<".listhide.">")
4121    exe 'sil keepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
4122   endif
4123  endwhile
4124  if g:netrw_hide == 2
4125   exe 'sil keepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
4126   exe 'sil keepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
4127  endif
4128
4129"  call Dret("NetrwListHide")
4130endfun
4131
4132" ---------------------------------------------------------------------
4133" NetrwHideEdit: allows user to edit the file/directory hiding list
4134fun! s:NetrwHideEdit(islocal)
4135"  call Dfunc("NetrwHideEdit(islocal=".a:islocal.")")
4136
4137  " save current cursor position
4138  let svpos= netrw#NetrwSavePosn()
4139
4140  " get new hiding list from user
4141  call inputsave()
4142  let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
4143  call inputrestore()
4144  let g:netrw_list_hide= newhide
4145"  call Decho("new g:netrw_list_hide<".g:netrw_list_hide.">")
4146
4147  " refresh the listing
4148  silent keepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./"))
4149
4150  " restore cursor position
4151  call netrw#NetrwRestorePosn(svpos)
4152
4153"  call Dret("NetrwHideEdit")
4154endfun
4155
4156" ---------------------------------------------------------------------
4157" NetSortSequence: allows user to edit the sorting sequence
4158fun! s:NetSortSequence(islocal)
4159"  call Dfunc("NetSortSequence(islocal=".a:islocal.")")
4160
4161  let svpos= netrw#NetrwSavePosn()
4162  call inputsave()
4163  let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
4164  call inputrestore()
4165
4166  " refresh the listing
4167  let g:netrw_sort_sequence= newsortseq
4168  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4169  call netrw#NetrwRestorePosn(svpos)
4170
4171"  call Dret("NetSortSequence")
4172endfun
4173
4174" ---------------------------------------------------------------------
4175" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
4176fun! s:NetrwMakeDir(usrhost)
4177"  call Dfunc("NetrwMakeDir(usrhost<".a:usrhost.">)")
4178
4179  " get name of new directory from user.  A bare <CR> will skip.
4180  " if its currently a directory, also request will be skipped, but with
4181  " a message.
4182  call inputsave()
4183  let newdirname= input("Please give directory name: ")
4184  call inputrestore()
4185"  call Decho("newdirname<".newdirname.">")
4186
4187  if newdirname == ""
4188"   call Dret("NetrwMakeDir : user aborted with bare <cr>")
4189   return
4190  endif
4191
4192  if a:usrhost == ""
4193"   call Decho("local mkdir")
4194
4195   " Local mkdir:
4196   " sanity checks
4197   let fullnewdir= b:netrw_curdir.'/'.newdirname
4198"   call Decho("fullnewdir<".fullnewdir.">")
4199   if isdirectory(fullnewdir)
4200    if !exists("g:netrw_quiet")
4201     call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
4202    endif
4203"    call Dret("NetrwMakeDir : directory<".newdirname."> exists previously")
4204    return
4205   endif
4206   if s:FileReadable(fullnewdir)
4207    if !exists("g:netrw_quiet")
4208     call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
4209    endif
4210"    call Dret("NetrwMakeDir : file<".newdirname."> exists previously")
4211    return
4212   endif
4213
4214   " requested new local directory is neither a pre-existing file or
4215   " directory, so make it!
4216   if exists("*mkdir")
4217    call mkdir(fullnewdir,"p")
4218   else
4219    let netrw_origdir= s:NetrwGetcwd(1)
4220    exe 'keepj lcd '.fnameescape(b:netrw_curdir)
4221"    call Decho("netrw_origdir<".netrw_origdir.">: lcd b:netrw_curdir<".fnameescape(b:netrw_curdir).">")
4222"    call Decho("exe silent! !".g:netrw_local_mkdir.' '.shellescape(newdirname,1))
4223    exe "sil! !".g:netrw_local_mkdir.' '.shellescape(newdirname,1)
4224    if !g:netrw_keepdir
4225     exe 'keepj lcd '.fnameescape(netrw_origdir)
4226"     call Decho("netrw_keepdir=".g:netrw_keepdir.": keepjumps lcd ".fnameescape(netrw_origdir)." getcwd<".getcwd().">")
4227    endif
4228   endif
4229
4230   if v:shell_error == 0
4231    " refresh listing
4232"    call Decho("refresh listing")
4233    let svpos= netrw#NetrwSavePosn()
4234    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
4235    call netrw#NetrwRestorePosn(svpos)
4236   elseif !exists("g:netrw_quiet")
4237    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
4238   endif
4239"   redraw!
4240
4241  elseif !exists("b:netrw_method") || b:netrw_method == 4
4242   " Remote mkdir:
4243"   call Decho("remote mkdir")
4244   let mkdircmd  = s:MakeSshCmd(g:netrw_mkdir_cmd)
4245   let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
4246"   call Decho("exe silent! !".mkdircmd." ".shellescape(newdirname,1))
4247   exe "sil! !".mkdircmd." ".shellescape(newdirname,1)
4248   if v:shell_error == 0
4249    " refresh listing
4250    let svpos= netrw#NetrwSavePosn()
4251    call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
4252    call netrw#NetrwRestorePosn(svpos)
4253   elseif !exists("g:netrw_quiet")
4254    call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
4255   endif
4256"   redraw!
4257
4258  elseif b:netrw_method == 2
4259   " COMBAK -- future work
4260   call netrw#ErrorMsg(s:ERROR,"making directories via ftp not currently supported",68)
4261  elseif b:netrw_method == 3
4262   " COMBAK -- future work
4263   call netrw#ErrorMsg(s:ERROR,"making directories via ftp not currently supported",68)
4264  endif
4265
4266"  call Dret("NetrwMakeDir")
4267endfun
4268
4269" ---------------------------------------------------------------------
4270" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
4271"                  mark and unmark files.  If a markfile list exists,
4272"                  then the rename and delete functions will use it instead
4273"                  of whatever may happen to be under the cursor at that
4274"                  moment.  When the mouse and gui are available,
4275"                  shift-leftmouse may also be used to mark files.
4276"
4277"  Creates two lists
4278"    s:netrwmarkfilelist    -- holds complete paths to all marked files
4279"    s:netrwmarkfilelist_#  -- holds list of marked files in current-buffer's directory (#==bufnr())
4280"
4281"  Creates a marked file match string
4282"    s:netrwmarfilemtch_#   -- used with 2match to display marked files
4283"
4284"  Creates a buffer version of islocal
4285"    b:netrw_islocal
4286"
4287fun! s:NetrwMarkFile(islocal,fname)
4288"  call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
4289  let curbufnr= bufnr("%")
4290  let curdir  = b:netrw_curdir
4291  let trailer = '[@=|\/\*]\=\>'
4292  if exists("s:netrwmarkfilelist_{curbufnr}")
4293   " markfile list exists
4294"   call Decho("starting s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">")
4295"   call Decho("starting s:netrwmarkfilemtch_{curbufnr}<".s:netrwmarkfilemtch_{curbufnr}.">")
4296   let b:netrw_islocal= a:islocal
4297
4298   if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
4299    " append filename to buffer's markfilelist
4300"    call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">")
4301    call add(s:netrwmarkfilelist_{curbufnr},a:fname)
4302    let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|\<'.escape(a:fname,g:netrw_markfileesc."'".g:netrw_markfileesc."'").trailer
4303
4304   else
4305    " remove filename from buffer's markfilelist
4306"    call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">")
4307    call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
4308    if s:netrwmarkfilelist_{curbufnr} == []
4309     " local markfilelist is empty; remove it entirely
4310"     call Decho("markfile list now empty")
4311     call s:NetrwUnmarkList(curbufnr,curdir)
4312    else
4313     " rebuild match list to display markings correctly
4314"     call Decho("rebuild s:netrwmarkfilemtch_".curbufnr)
4315     let s:netrwmarkfilemtch_{curbufnr}= ""
4316     let first                           = 1
4317     for fname in s:netrwmarkfilelist_{curbufnr}
4318      if first
4319       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\<'.escape(fname,g:netrw_markfileesc."'".g:netrw_markfileesc."'").trailer
4320      else
4321       let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|\<'.escape(fname,g:netrw_markfileesc."'".g:netrw_markfileesc."'").trailer
4322      endif
4323      let first= 0
4324     endfor
4325"     call Decho("ending s:netrwmarkfilelist_"curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">")
4326"     call Decho("ending s:netrwmarkfilemtch_"curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">")
4327    endif
4328   endif
4329
4330  else
4331   " initialize new markfilelist
4332
4333"   call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr)
4334   let s:netrwmarkfilelist_{curbufnr}= []
4335   call add(s:netrwmarkfilelist_{curbufnr},a:fname)
4336"   call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">")
4337
4338   " build initial markfile matching pattern
4339   if a:fname =~ '/$'
4340    let s:netrwmarkfilemtch_{curbufnr}= '\<'.escape(a:fname,g:netrw_markfileesc)
4341   else
4342    let s:netrwmarkfilemtch_{curbufnr}= '\<'.escape(a:fname,g:netrw_markfileesc).trailer
4343   endif
4344"   call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">")
4345  endif
4346
4347  " handle global markfilelist
4348  if exists("s:netrwmarkfilelist")
4349   let dname= s:ComposePath(b:netrw_curdir,a:fname)
4350   if index(s:netrwmarkfilelist,dname) == -1
4351    " append new filename to global markfilelist
4352    call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
4353"    call Decho("append filename<".a:fname."> to global markfilelist<".string(s:netrwmarkfilelist).">")
4354   else
4355    " remove new filename from global markfilelist
4356"    call Decho("filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")")
4357    call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
4358"    call Decho("ending s:netrwmarkfilelist  <".string(s:netrwmarkfilelist).">")
4359    if s:netrwmarkfilelist == []
4360     unlet s:netrwmarkfilelist
4361    endif
4362   endif
4363  else
4364   " initialize new global-directory markfilelist
4365   let s:netrwmarkfilelist= []
4366   call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
4367"   call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">")
4368  endif
4369
4370  " set up 2match'ing to netrwmarkfilemtch list
4371  if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
4372"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/")
4373   if exists("g:did_drchip_netrwlist_syntax")
4374    exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
4375   endif
4376  else
4377"   call Decho("2match none")
4378   2match none
4379  endif
4380"  call Dret("s:NetrwMarkFile : netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist").">")
4381endfun
4382
4383" ---------------------------------------------------------------------
4384" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
4385"                          compress/decompress files using the programs
4386"                          in g:netrw_compress and g:netrw_uncompress,
4387"                          using g:netrw_compress_suffix to know which to
4388"                          do.  By default:
4389"                            g:netrw_compress        = "gzip"
4390"                            g:netrw_decompress      = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
4391fun! s:NetrwMarkFileCompress(islocal)
4392"  call Dfunc("s:NetrwMarkFileCompress(islocal=".a:islocal.")")
4393  let svpos    = netrw#NetrwSavePosn()
4394  let curdir   = b:netrw_curdir
4395  let curbufnr = bufnr("%")
4396
4397  if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
4398   for fname in s:netrwmarkfilelist_{curbufnr}
4399    " for every filename in the marked list
4400    for sfx in sort(keys(g:netrw_decompress))
4401     if fname =~ '\'.sfx.'$'
4402      " fname has a suffix indicating that its compressed; apply associated decompression routine
4403      let exe= netrw#WinPath(g:netrw_decompress[sfx])
4404"      call Decho("fname<".fname."> is compressed so decompress with <".exe.">")
4405      if a:islocal
4406       if g:netrw_keepdir
4407        let fname= shellescape(s:ComposePath(curdir,fname))
4408       endif
4409      else
4410       let fname= shellescape(b:netrw_curdir.fname,1)
4411      endif
4412      if executable(exe)
4413       if a:islocal
4414	call system(exe." ".fname)
4415       else
4416        call s:RemoteSystem(exe." ".fname)
4417       endif
4418      else
4419       call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
4420      endif
4421      break
4422     endif
4423     unlet sfx
4424    endfor
4425    if exists("exe")
4426     unlet exe
4427    elseif a:islocal
4428     " fname not a compressed file, so compress it
4429     call system(netrw#WinPath(g:netrw_compress)." ".shellescape(s:ComposePath(b:netrw_curdir,fname)))
4430    else
4431     " fname not a compressed file, so compress it
4432     call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".shellescape(fname))
4433    endif
4434   endfor
4435   call s:NetrwUnmarkList(curbufnr,curdir)
4436   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4437   call netrw#NetrwRestorePosn(svpos)
4438  endif
4439"  call Dret("s:NetrwMarkFileCompress")
4440endfun
4441
4442" ---------------------------------------------------------------------
4443" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
4444"                      If no marked files, then set up directory as the
4445"                      target.  Currently does not support copying entire
4446"                      directories.  Uses the local-buffer marked file list.
4447"                      Returns 1=success  (used by NetrwMarkFileMove())
4448"                              0=failure
4449fun! s:NetrwMarkFileCopy(islocal)
4450"  call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---').">")
4451
4452  " sanity checks
4453  if !exists("s:netrwmarkfilelist_{bufnr('%')}") || empty(s:netrwmarkfilelist_{bufnr('%')})
4454   call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
4455"   call Dret("s:NetrwMarkFileCopy 0")
4456   return 0
4457  endif
4458"  call Decho("sanity chk passed: s:netrwmarkfilelist_".bufnr('%')."<".string(s:netrwmarkfilelist_{bufnr('%')}))
4459  if !exists("s:netrwmftgt")
4460   call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
4461"   call Dret("s:NetrwMarkFileCopy 0")
4462   return 0
4463  endif
4464"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">")
4465  let curdir   = b:netrw_curdir
4466  let curbufnr = bufnr("%")
4467
4468  if      a:islocal &&  s:netrwmftgt_islocal
4469   " Copy marked files, local directory to local directory
4470"   call Decho("copy from local to local")
4471   let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"shellescape(b:netrw_curdir.\"/\".v:val)"))
4472"   call Decho("system(".g:netrw_localcopycmd." ".args." ".shellescape(s:netrwmftgt).")")
4473   call system(netrw#WinPath(g:netrw_localcopycmd)." ".args." ".shellescape(s:netrwmftgt))
4474
4475  elseif  a:islocal && !s:netrwmftgt_islocal
4476   " Copy marked files, local directory to remote directory
4477"   call Decho("copy from local to remote")
4478   call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
4479
4480  elseif !a:islocal &&  s:netrwmftgt_islocal
4481"   call Decho("copy from remote to local")
4482   call netrw#NetrwObtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
4483
4484  elseif !a:islocal && !s:netrwmftgt_islocal
4485"   call Decho("copy from remote to remote")
4486   let curdir = getcwd()
4487   let tmpdir = s:GetTempfile("")
4488   if tmpdir !~ '/'
4489    let tmpdir= curdir."/".tmpdir
4490   endif
4491   if exists("*mkdir")
4492    call mkdir(tmpdir)
4493   else
4494    exe "sil! !".g:netrw_local_mkdir.' '.shellescape(tmpdir,1)
4495   endif
4496   if isdirectory(tmpdir)
4497    exe "keepj lcd ".fnameescape(tmpdir)
4498    call netrw#NetrwObtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
4499    let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
4500    call s:NetrwUpload(localfiles,s:netrwmftgt)
4501    if getcwd() == tmpdir
4502     for fname in s:netrwmarkfilelist_{bufnr('%')}
4503      call s:NetrwDelete(fname)
4504     endfor
4505     exe "keepj lcd ".fnameescape(curdir)
4506     exe "sil !".g:netrw_local_rmdir." ".shellescape(tmpdir,1)
4507    else
4508     exe "keepj lcd ".fnameescape(curdir)
4509    endif
4510   endif
4511  endif
4512
4513  " -------
4514  " cleanup
4515  " -------
4516"  call Decho("cleanup")
4517
4518  " remove markings from local buffer
4519  call s:NetrwUnmarkList(curbufnr,curdir)
4520
4521  " refresh buffers
4522  if !s:netrwmftgt_islocal
4523   call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
4524  endif
4525  if a:islocal
4526   call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
4527  endif
4528  if g:netrw_fastbrowse <= 1
4529   call s:LocalBrowseShellCmdRefresh()
4530  endif
4531  
4532"  call Dret("s:NetrwMarkFileCopy 1")
4533  return 1
4534endfun
4535
4536" ---------------------------------------------------------------------
4537" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
4538"                      invoke vim's diff mode on the marked files.
4539"                      Either two or three files can be so handled.
4540"                      Uses the global marked file list.
4541fun! s:NetrwMarkFileDiff(islocal)
4542"  call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
4543  let curbufnr= bufnr("%")
4544
4545  if exists("s:netrwmarkfilelist_{curbufnr}")
4546   let cnt    = 0
4547   let curdir = b:netrw_curdir
4548   for fname in s:netrwmarkfilelist
4549    let cnt= cnt + 1
4550    if cnt == 1
4551"     call Decho("diffthis: fname<".fname.">")
4552     exe "e ".fnameescape(fname)
4553     diffthis
4554    elseif cnt == 2 || cnt == 3
4555     vsplit
4556     wincmd l
4557"     call Decho("diffthis: ".fname)
4558     exe "e ".fnameescape(fname)
4559     diffthis
4560    else
4561     break
4562    endif
4563   endfor
4564   call s:NetrwUnmarkList(curbufnr,curdir)
4565  endif
4566
4567"  call Dret("s:NetrwMarkFileDiff")
4568endfun
4569
4570" ---------------------------------------------------------------------
4571" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
4572"                       Uses global markfilelist
4573fun! s:NetrwMarkFileEdit(islocal)
4574"  call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
4575
4576  let curdir   = b:netrw_curdir
4577  let curbufnr = bufnr("%")
4578  if exists("s:netrwmarkfilelist_{curbufnr}")
4579   call s:SetRexDir(a:islocal,curdir)
4580   let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
4581   " unmark markedfile list
4582"   call s:NetrwUnmarkList(curbufnr,curdir)
4583   call s:NetrwUnmarkAll()
4584"   call Decho("exe silent args ".flist)
4585   exe "silent args ".flist
4586  endif
4587  
4588"  call Dret("s:NetrwMarkFileEdit")
4589endfun
4590
4591" ---------------------------------------------------------------------
4592" s:NetrwMarkFileExe: (invoked by mx) execute arbitrary command on marked files, one at a time {{{2
4593"                     Uses the local marked-file list.
4594fun! s:NetrwMarkFileExe(islocal)
4595"  call Dfunc("s:NetrwMarkFileExe(islocal=".a:islocal.")")
4596  let svpos    = netrw#NetrwSavePosn()
4597  let curdir   = b:netrw_curdir
4598  let curbufnr = bufnr("%")
4599
4600  if exists("s:netrwmarkfilelist_{curbufnr}")
4601   " get the command
4602   call inputsave()
4603   let cmd= input("Enter command: ","","file")
4604   call inputrestore()
4605"   call Decho("cmd<".cmd.">")
4606
4607   " apply command to marked files.  Substitute: filename -> %
4608   " If no %, then append a space and the filename to the command
4609   for fname in s:netrwmarkfilelist_{curbufnr}
4610    if a:islocal
4611     if g:netrw_keepdir
4612      let fname= shellescape(netrw#WinPath(s:ComposePath(curdir,fname)))
4613     endif
4614    else
4615     let fname= shellescape(netrw#WinPath(b:netrw_curdir.fname))
4616    endif
4617    if cmd =~ '%'
4618     let xcmd= substitute(cmd,'%',fname,'g')
4619    else
4620     let xcmd= cmd.' '.fname
4621    endif
4622    if a:islocal
4623"     call Decho("local: xcmd<".xcmd.">")
4624     let ret= system(xcmd)
4625    else
4626"     call Decho("remote: xcmd<".xcmd.">")
4627     let ret= s:RemoteSystem(xcmd)
4628    endif
4629    if v:shell_error < 0
4630     call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
4631     break
4632    else
4633     echo ret
4634    endif
4635   endfor
4636
4637   " unmark marked file list
4638   call s:NetrwUnmarkList(curbufnr,curdir)
4639
4640   " refresh the listing
4641   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4642   call netrw#NetrwRestorePosn(svpos)
4643  else
4644   call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
4645  endif
4646  
4647"  call Dret("s:NetrwMarkFileExe")
4648endfun
4649
4650" ---------------------------------------------------------------------
4651" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
4652"                  as the marked file(s) (toggles suffix presence)
4653"                  Uses the local marked file list.
4654fun! s:NetrwMarkHideSfx(islocal)
4655"  call Dfunc("s:NetrwMarkHideSfx(islocal=".a:islocal.")")
4656  let svpos    = netrw#NetrwSavePosn()
4657  let curbufnr = bufnr("%")
4658
4659  " s:netrwmarkfilelist_{curbufnr}: the List of marked files
4660  if exists("s:netrwmarkfilelist_{curbufnr}")
4661
4662   for fname in s:netrwmarkfilelist_{curbufnr}
4663"     call Decho("s:NetrwMarkFileCopy: fname<".fname.">")
4664     " construct suffix pattern
4665     if fname =~ '\.'
4666      let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
4667     else
4668      let sfxpat= '^\%(\%(\.\)\@!.\)*$'
4669     endif
4670     " determine if its in the hiding list or not
4671     let inhidelist= 0
4672     if g:netrw_list_hide != ""
4673      let itemnum = 0
4674      let hidelist= split(g:netrw_list_hide,',')
4675      for hidepat in hidelist
4676       if sfxpat == hidepat
4677        let inhidelist= 1
4678        break
4679       endif
4680       let itemnum= itemnum + 1
4681      endfor
4682     endif
4683"     call Decho("fname<".fname."> inhidelist=".inhidelist." sfxpat<".sfxpat.">")
4684     if inhidelist
4685      " remove sfxpat from list
4686      call remove(hidelist,itemnum)
4687      let g:netrw_list_hide= join(hidelist,",")
4688     elseif g:netrw_list_hide != ""
4689      " append sfxpat to non-empty list
4690      let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
4691     else
4692      " set hiding list to sfxpat
4693      let g:netrw_list_hide= sfxpat
4694     endif
4695    endfor
4696
4697   " refresh the listing
4698   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
4699   call netrw#NetrwRestorePosn(svpos)
4700  else
4701   call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
4702  endif
4703
4704"  call Dret("s:NetrwMarkHideSfx")
4705endfun
4706
4707" ---------------------------------------------------------------------
4708" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
4709"                     Uses the global markfilelist
4710fun! s:NetrwMarkFileGrep(islocal)
4711"  call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
4712  let svpos    = netrw#NetrwSavePosn()
4713  let curbufnr = bufnr("%")
4714
4715  if exists("s:netrwmarkfilelist")
4716"  call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">")
4717   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
4718   call s:NetrwUnmarkAll()
4719
4720   " ask user for pattern
4721   call inputsave()
4722   let pat= input("Enter pattern: ","")
4723   call inputrestore()
4724   if pat !~ '^\s'
4725    if pat !~ '^/'
4726     let pat= '/'.pat.'/'
4727    endif
4728    let pat= " ".pat
4729   endif
4730
4731   " use vimgrep for both local and remote
4732"   call Decho("exe vimgrep".pat." ".netrwmarkfilelist)
4733   try
4734    exe "keepj noautocmd vimgrep".pat." ".netrwmarkfilelist
4735    catch /^Vim\%((\a\+)\)\=:E480/
4736     call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
4737"     call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pattern.">")
4738     return
4739   endtry
4740
4741   2match none
4742   call netrw#NetrwRestorePosn(svpos)
4743  endif
4744
4745"  call Dret("s:NetrwMarkFileGrep")
4746endfun
4747
4748" ---------------------------------------------------------------------
4749" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
4750"                      uses the global marked file list
4751"                      s:netrwmfloc= 0: target directory is remote
4752"                                  = 1: target directory is local
4753fun! s:NetrwMarkFileMove(islocal)
4754"  call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
4755  let curdir   = b:netrw_curdir
4756  let curbufnr = bufnr("%")
4757
4758  " sanity check
4759  if !exists("s:netrwmarkfilelist_{bufnr('%')}") || empty(s:netrwmarkfilelist_{bufnr('%')})
4760   call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
4761"   call Dret("s:NetrwMarkFileMove")
4762   return
4763  endif
4764"  call Decho("sanity chk passed: s:netrwmarkfilelist_".bufnr('%')."<".string(s:netrwmarkfilelist_{bufnr('%')}))
4765  if !exists("s:netrwmftgt")
4766   call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
4767"   call Dret("s:NetrwMarkFileCopy 0")
4768   return 0
4769  endif
4770"  call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">")
4771
4772  if      a:islocal &&  s:netrwmftgt_islocal
4773   " move: local -> local
4774"   call Decho("move from local to local")
4775"   call Decho("(s:NetrwMarkFileMove) local to local move")
4776   if executable(g:netrw_localmovecmd)
4777    for fname in s:netrwmarkfilelist_{bufnr("%")}
4778"     call Decho("system(".g:netrw_localmovecmd." ".shellescape(fname)." ".shellescape(s:netrwmftgt).")")
4779     let ret= system(g:netrw_localmovecmd." ".shellescape(fname)." ".shellescape(s:netrwmftgt))
4780     if v:shell_error < 0
4781      call netrw#ErrorMsg(s:ERROR,"command<".g:netrw_localmovecmd."> failed, aborting",54)
4782      break
4783     endif
4784    endfor
4785   else
4786    call netrw#ErrorMsg(s:ERROR,"command<".g:netrw_localmovecmd."> is not executable!",57)
4787   endif
4788
4789  elseif  a:islocal && !s:netrwmftgt_islocal
4790   " move: local -> remote
4791"   call Decho("move from local to remote")
4792"   call Decho("copy")
4793   let mflist= s:netrwmarkfilelist_{bufnr("%")}
4794   call s:NetrwMarkFileCopy(a:islocal)
4795"   call Decho("remove")
4796   for fname in mflist
4797    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
4798    let ok        = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
4799   endfor
4800   unlet mflist
4801
4802  elseif !a:islocal &&  s:netrwmftgt_islocal
4803   " move: remote -> local
4804"   call Decho("move from remote to local")
4805"   call Decho("copy")
4806   let mflist= s:netrwmarkfilelist_{bufnr("%")}
4807   call s:NetrwMarkFileCopy(a:islocal)
4808"   call Decho("remove")
4809   for fname in mflist
4810    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
4811    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
4812   endfor
4813   unlet mflist
4814
4815  elseif !a:islocal && !s:netrwmftgt_islocal
4816   " move: remote -> remote
4817"   call Decho("move from remote to remote")
4818"   call Decho("copy")
4819   let mflist= s:netrwmarkfilelist_{bufnr("%")}
4820   call s:NetrwMarkFileCopy(a:islocal)
4821"   call Decho("remove")
4822   for fname in mflist
4823    let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
4824    let ok        = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
4825   endfor
4826   unlet mflist
4827  endif
4828
4829  " -------
4830  " cleanup
4831  " -------
4832"  call Decho("cleanup")
4833
4834  " remove markings from local buffer
4835  call s:NetrwUnmarkList(curbufnr,curdir)                   " remove markings from local buffer
4836
4837  " refresh buffers
4838  if !s:netrwmftgt_islocal
4839   call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
4840  endif
4841  if a:islocal
4842   call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
4843  endif
4844  if g:netrw_fastbrowse <= 1
4845   call s:LocalBrowseShellCmdRefresh()
4846  endif
4847  
4848"  call Dret("s:NetrwMarkFileMove")
4849endfun
4850
4851" ---------------------------------------------------------------------
4852" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
4853"                       using the hardcopy command.  Local marked-file list only.
4854fun! s:NetrwMarkFilePrint(islocal)
4855"  call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
4856  let curbufnr= bufnr("%")
4857  if exists("s:netrwmarkfilelist_{curbufnr}")
4858   let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
4859   let curdir            = b:netrw_curdir
4860   call s:NetrwUnmarkList(curbufnr,curdir)
4861   for fname in netrwmarkfilelist
4862    if a:islocal
4863     if g:netrw_keepdir
4864      let fname= s:ComposePath(curdir,fname)
4865     endif
4866    else
4867     let fname= curdir.fname
4868    endif
4869    1split
4870    " the autocmds will handle both local and remote files
4871"    call Decho("exe silent e ".escape(fname,' '))
4872    exe "silent e ".fnameescape(fname)
4873"    call Decho("hardcopy")
4874    hardcopy
4875    q
4876   endfor
4877   2match none
4878  endif
4879"  call Dret("s:NetrwMarkFilePrint")
4880endfun
4881
4882" ---------------------------------------------------------------------
4883" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
4884"                        files when given a regexp (for which a prompt is
4885"                        issued).
4886fun! s:NetrwMarkFileRegexp(islocal)
4887"  call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
4888
4889  " get the regular expression
4890  call inputsave()
4891  let regexp= input("Enter regexp: ","","file")
4892  call inputrestore()
4893
4894  if a:islocal
4895   " get the matching list of files using local glob()
4896"   call Decho("handle local regexp")
4897   let dirname  = escape(b:netrw_curdir,g:netrw_glob_escape)
4898   let files = glob(s:ComposePath(dirname,regexp))
4899"   call Decho("files<".files.">")
4900   let filelist= split(files,"\n")
4901
4902  " mark the list of files
4903  for fname in filelist
4904"   call Decho("fname<".fname.">")
4905   call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
4906  endfor
4907
4908  else
4909"   call Decho("handle remote regexp")
4910
4911   " convert displayed listing into a filelist
4912   let eikeep = &ei
4913   let areg   = @a
4914   sil keepj %y a
4915   set ei=all ma
4916"   call Decho("set ei=all ma")
4917   1split
4918   call s:NetrwEnew()
4919   call s:NetrwSafeOptions()
4920   sil keepj norm! "ap
4921   keepj 2
4922   let bannercnt= search('^" =====','W')
4923   exe "sil keepj 1,".bannercnt."d"
4924   set bt=nofile
4925   if     g:netrw_liststyle == s:LONGLIST
4926    sil keepj %s/\s\{2,}\S.*$//e
4927    call histdel("/",-1)
4928   elseif g:netrw_liststyle == s:WIDELIST
4929    sil keepj %s/\s\{2,}/\r/ge
4930    call histdel("/",-1)
4931   elseif g:netrw_liststyle == s:TREELIST
4932    sil keepj %s/^| //e
4933    sil! keepj g/^ .*$/d
4934    call histdel("/",-1)
4935    call histdel("/",-1)
4936   endif
4937   " convert regexp into the more usual glob-style format
4938   let regexp= substitute(regexp,'\*','.*','g')
4939"   call Decho("regexp<".regexp.">")
4940   exe "sil! keepj v/".escape(regexp,'/')."/d"
4941   call histdel("/",-1)
4942   let filelist= getline(1,line("$"))
4943   q!
4944   for filename in filelist
4945    call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
4946   endfor
4947   unlet filelist
4948   let @a  = areg
4949   let &ei = eikeep
4950  endif
4951
4952"  call Dret("s:NetrwMarkFileRegexp")
4953endfun
4954
4955" ---------------------------------------------------------------------
4956" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
4957"                        Uses the local marked file list.
4958fun! s:NetrwMarkFileSource(islocal)
4959"  call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
4960  let curbufnr= bufnr("%")
4961  if exists("s:netrwmarkfilelist_{curbufnr}")
4962   let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
4963   let curdir            = b:netrw_curdir
4964   call s:NetrwUnmarkList(curbufnr,curdir)
4965   for fname in netrwmarkfilelist
4966    if a:islocal
4967     if g:netrw_keepdir
4968      let fname= s:ComposePath(curdir,fname)
4969     endif
4970    else
4971     let fname= curdir.fname
4972    endif
4973    " the autocmds will handle sourcing both local and remote files
4974"    call Decho("exe so ".fnameescape(fname))
4975    exe "so ".fnameescape(fname)
4976   endfor
4977   2match none
4978  endif
4979"  call Dret("s:NetrwMarkFileSource")
4980endfun
4981
4982" ---------------------------------------------------------------------
4983" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
4984"                     Uses the global markfilelist
4985fun! s:NetrwMarkFileTag(islocal)
4986"  call Dfunc("s:NetrwMarkFileTag(islocal=".a:islocal.")")
4987  let svpos    = netrw#NetrwSavePosn()
4988  let curdir   = b:netrw_curdir
4989  let curbufnr = bufnr("%")
4990
4991  if exists("s:netrwmarkfilelist")
4992"   call Decho("s:netrwmarkfilelist".string(s:netrwmarkfilelist).">")
4993   let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "shellescape(v:val,".!a:islocal.")"))
4994   call s:NetrwUnmarkAll()
4995
4996   if a:islocal
4997    if executable(g:netrw_ctags)
4998"     call Decho("call system(".g:netrw_ctags." ".netrwmarkfilelist.")")
4999     call system(g:netrw_ctags." ".netrwmarkfilelist)
5000    else
5001     call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
5002    endif
5003   else
5004    let cmd   = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
5005    call netrw#NetrwObtain(a:islocal,"tags")
5006    let curdir= b:netrw_curdir
5007    1split
5008    e tags
5009    let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
5010"    call Decho("curdir<".curdir."> path<".path.">")
5011    exe 'keepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
5012    call histdel("/",-1)
5013    wq!
5014   endif
5015   2match none
5016   call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5017   call netrw#NetrwRestorePosn(svpos)
5018  endif
5019
5020"  call Dret("s:NetrwMarkFileTag")
5021endfun
5022
5023" ---------------------------------------------------------------------
5024" s:NetrwMarkFileTgt:  (invoked by mt) This function sets up a marked file target {{{2
5025"   Sets up two variables, 
5026"     s:netrwmftgt : holds the target directory
5027"     s:netrwmftgt_islocal : 0=target directory is remote
5028"                    1=target directory is local
5029fun! s:NetrwMarkFileTgt(islocal)
5030"  call Dfunc("s:NetrwMarkFileTgt(islocal=".a:islocal.")")
5031  let svpos  = netrw#NetrwSavePosn()
5032  let curdir = b:netrw_curdir
5033  let hadtgt = exists("s:netrwmftgt")
5034  if !exists("w:netrw_bannercnt")
5035   let w:netrw_bannercnt= b:netrw_bannercnt
5036  endif
5037
5038  " set up target
5039  if line(".") < w:netrw_bannercnt
5040   " if cursor in banner region, use b:netrw_curdir for the target
5041   let s:netrwmftgt= b:netrw_curdir
5042"   call Decho("inbanner: s:netrwmftgt<".s:netrwmftgt.">")
5043
5044  else
5045   " get word under cursor.
5046   "  * If directory, use it for the target.
5047   "  * If file, use b:netrw_curdir for the target
5048   let curword= s:NetrwGetWord()
5049   let tgtdir = s:ComposePath(curdir,curword)
5050   if a:islocal && isdirectory(tgtdir)
5051    let s:netrwmftgt = tgtdir
5052"    call Decho("local isdir: s:netrwmftgt<".s:netrwmftgt.">")
5053   elseif !a:islocal && tgtdir =~ '/$'
5054    let s:netrwmftgt = tgtdir
5055"    call Decho("remote isdir: s:netrwmftgt<".s:netrwmftgt.">")
5056   else
5057    let s:netrwmftgt = curdir
5058"    call Decho("isfile: s:netrwmftgt<".s:netrwmftgt.">")
5059   endif
5060  endif
5061  if a:islocal
5062   " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
5063   let s:netrwmftgt= simplify(s:netrwmftgt)
5064"   call Decho("simplify: s:netrwmftgt<".s:netrwmftgt.">")
5065  endif
5066  if g:netrw_cygwin
5067   let s:netrwmftgt= substitute(system("cygpath ".shellescape(s:netrwmftgt)),'\n$','','')
5068   let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
5069  endif
5070  let s:netrwmftgt_islocal= a:islocal
5071
5072  if g:netrw_fastbrowse <= 1
5073   call s:LocalBrowseShellCmdRefresh()
5074  endif
5075  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5076  call netrw#NetrwRestorePosn(svpos)
5077  if !hadtgt
5078   sil! keepj norm! j
5079  endif
5080
5081"  call Dret("s:NetrwMarkFileTgt : netrwmftgt<".(exists("s:netrwmftgt")? s:netrwmftgt : "").">")
5082endfun
5083
5084" ---------------------------------------------------------------------
5085" s:NetrwOpenFile: query user for a filename and open it {{{2
5086fun! s:NetrwOpenFile(islocal)
5087"  call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
5088  call inputsave()
5089  let fname= input("Enter filename: ")
5090  call inputrestore()
5091  if fname !~ '[/\\]'
5092   if exists("b:netrw_curdir")
5093    if exists("g:netrw_quiet")
5094     let netrw_quiet_keep = g:netrw_quiet
5095    endif
5096    let g:netrw_quiet    = 1
5097    if b:netrw_curdir =~ '/$'
5098     exe "e ".fnameescape(b:netrw_curdir.fname)
5099    else
5100     exe "e ".fnameescape(b:netrw_curdir."/".fname)
5101    endif
5102    if exists("netrw_quiet_keep")
5103     let g:netrw_quiet= netrw_quiet_keep
5104    else
5105     unlet g:netrw_quiet
5106    endif
5107   endif
5108  else
5109   exe "e ".fnameescape(fname)
5110  endif
5111"  call Dret("s:NetrwOpenFile")
5112endfun
5113
5114" ---------------------------------------------------------------------
5115" s:NetrwUnmarkList: delete local marked file lists and remove their contents from the global marked-file list {{{2
5116fun! s:NetrwUnmarkList(curbufnr,curdir)
5117"  call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
5118
5119  "  remove all files in local marked-file list from global list
5120  if exists("s:netrwmarkfilelist_{a:curbufnr}")
5121   for mfile in s:netrwmarkfilelist_{a:curbufnr}
5122    let dfile = s:ComposePath(a:curdir,mfile)       " prepend directory to mfile
5123    let idx   = index(s:netrwmarkfilelist,dfile)    " get index in list of dfile
5124    call remove(s:netrwmarkfilelist,idx)            " remove from global list
5125   endfor
5126   if s:netrwmarkfilelist == []
5127    unlet s:netrwmarkfilelist
5128   endif
5129 
5130   " getting rid of the local marked-file lists is easy
5131   unlet s:netrwmarkfilelist_{a:curbufnr}
5132  endif
5133  if exists("s:netrwmarkfilemtch_{a:curbufnr}")
5134   unlet s:netrwmarkfilemtch_{a:curbufnr}
5135  endif
5136  2match none
5137"  call Dret("s:NetrwUnmarkList")
5138endfun
5139
5140" ---------------------------------------------------------------------
5141" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
5142fun! s:NetrwUnmarkAll()
5143"  call Dfunc("s:NetrwUnmarkAll()")
5144  if exists("s:netrwmarkfilelist")
5145   unlet s:netrwmarkfilelist
5146  endif
5147  silent call s:NetrwUnmarkAll2()
5148  2match none
5149"  call Dret("s:NetrwUnmarkAll")
5150endfun
5151
5152" ---------------------------------------------------------------------
5153" s:NetrwUnmarkAll2: {{{2
5154fun! s:NetrwUnmarkAll2()
5155"  call Dfunc("s:NetrwUnmarkAll2()")
5156  redir => netrwmarkfilelist_let
5157  let
5158  redir END
5159  let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n')          " convert let string into a let list
5160  call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_ 
5161  call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')")    " remove what the entries are equal to
5162  for flist in netrwmarkfilelist_list
5163   let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
5164   unlet s:netrwmarkfilelist_{curbufnr}
5165   unlet s:netrwmarkfilemtch_{curbufnr}
5166  endfor
5167"  call Dret("s:NetrwUnmarkAll2")
5168endfun
5169
5170" ---------------------------------------------------------------------
5171" s:NetrwUnMarkFile: {{{2
5172fun! s:NetrwUnMarkFile(islocal)
5173"  call Dfunc("s:NetrwUnMarkFile(islocal=".a:islocal.")")
5174  let svpos    = netrw#NetrwSavePosn()
5175  let curbufnr = bufnr("%")
5176
5177  " unmark marked file list (although I expect s:NetrwUpload()
5178  " to do it, I'm just making sure)
5179  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5180"   call Decho("unlet'ing: s:netrwmarkfile[list|mtch]_".bufnr("%"))
5181   unlet s:netrwmarkfilelist
5182   unlet s:netrwmarkfilelist_{curbufnr}
5183   unlet s:netrwmarkfilemtch_{curbufnr}
5184   2match none
5185  endif
5186
5187"  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5188  call netrw#NetrwRestorePosn(svpos)
5189"  call Dret("s:NetrwUnMarkFile")
5190endfun
5191
5192" ---------------------------------------------------------------------
5193" s:NetrwMenu: generates the menu for gvim and netrw {{{2
5194fun! s:NetrwMenu(domenu)
5195
5196  if !exists("g:NetrwMenuPriority")
5197   let g:NetrwMenuPriority= 80
5198  endif
5199
5200  if has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
5201"   call Dfunc("NetrwMenu(domenu=".a:domenu.")")
5202
5203   if !exists("s:netrw_menu_enabled") && a:domenu
5204"    call Decho("initialize menu")
5205    let s:netrw_menu_enabled= 1
5206    exe 'sil! menu '.g:NetrwMenuPriority.'.1     '.g:NetrwTopLvlMenu.'Help<tab><F1>	<F1>'
5207    exe 'sil! menu '.g:NetrwMenuPriority.'.5     '.g:NetrwTopLvlMenu.'-Sep1-	:'
5208    exe 'sil! menu '.g:NetrwMenuPriority.'.6     '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>-	-'
5209    exe 'sil! menu '.g:NetrwMenuPriority.'.7     '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x	x'
5210    exe 'sil! menu '.g:NetrwMenuPriority.'.8.1   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb	mb'
5211    exe 'sil! menu '.g:NetrwMenuPriority.'.8.4   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u	u'
5212    exe 'sil! menu '.g:NetrwMenuPriority.'.8.5   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U	U'
5213    exe 'sil! menu '.g:NetrwMenuPriority.'.8.6   '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb	qb'
5214    exe 'sil! menu '.g:NetrwMenuPriority.'.9.1   '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'."	\<c-h>'"
5215    exe 'sil! menu '.g:NetrwMenuPriority.'.9.2   '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S	S'
5216    exe 'sil! menu '.g:NetrwMenuPriority.'.9.3   '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh	gh"
5217    exe 'sil! menu '.g:NetrwMenuPriority.'.9.4   '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l>	\<c-l>"
5218    exe 'sil! menu '.g:NetrwMenuPriority.'.9.5   '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings	'.":NetrwSettings\<cr>"
5219    exe 'sil! menu '.g:NetrwMenuPriority.'.10    '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D	D'
5220    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>%	%'
5221    exe 'sil! menu '.g:NetrwMenuPriority.'.11.1  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr>	'."\<cr>"
5222    exe 'sil! menu '.g:NetrwMenuPriority.'.11.2  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p	p'
5223    exe 'sil! menu '.g:NetrwMenuPriority.'.11.3  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P	P'
5224    exe 'sil! menu '.g:NetrwMenuPriority.'.11.4  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o	o'
5225    exe 'sil! menu '.g:NetrwMenuPriority.'.11.5  '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v	v'
5226    exe 'sil! menu '.g:NetrwMenuPriority.'.12.1  '.g:NetrwTopLvlMenu.'Explore.Directory\ Name	:Explore '
5227    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2  '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */	:Explore */'
5228    exe 'sil! menu '.g:NetrwMenuPriority.'.12.2  '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/	:Explore **/'
5229    exe 'sil! menu '.g:NetrwMenuPriority.'.12.3  '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *//	:Explore *//'
5230    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4  '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **//	:Explore **//'
5231    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4  '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore	:Nexplore<cr>'
5232    exe 'sil! menu '.g:NetrwMenuPriority.'.12.4  '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore	:Pexplore<cr>'
5233    exe 'sil! menu '.g:NetrwMenuPriority.'.13    '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d	d'
5234    exe 'sil! menu '.g:NetrwMenuPriority.'.14.1  '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf	mf'
5235    exe 'sil! menu '.g:NetrwMenuPriority.'.14.2  '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr	mr'
5236    exe 'sil! menu '.g:NetrwMenuPriority.'.14.3  '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a	a'
5237    exe 'sil! menu '.g:NetrwMenuPriority.'.14.4  '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc	mc'
5238    exe 'sil! menu '.g:NetrwMenuPriority.'.14.5  '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D	D'
5239    exe 'sil! menu '.g:NetrwMenuPriority.'.14.6  '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md	md'
5240    exe 'sil! menu '.g:NetrwMenuPriority.'.14.7  '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me	me'
5241    exe 'sil! menu '.g:NetrwMenuPriority.'.14.8  '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx	mx'
5242    exe 'sil! menu '.g:NetrwMenuPriority.'.14.9  '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm	mm'
5243    exe 'sil! menu '.g:NetrwMenuPriority.'.14.10 '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O	O'
5244    exe 'sil! menu '.g:NetrwMenuPriority.'.14.11 '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp	mp'
5245    exe 'sil! menu '.g:NetrwMenuPriority.'.14.12 '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R	R'
5246    exe 'sil! menu '.g:NetrwMenuPriority.'.14.13 '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt	mt'
5247    exe 'sil! menu '.g:NetrwMenuPriority.'.14.14 '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT	mT'
5248    exe 'sil! menu '.g:NetrwMenuPriority.'.14.15 '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz	mz'
5249    exe 'sil! menu '.g:NetrwMenuPriority.'.15    '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O	O'
5250    exe 'sil! menu '.g:NetrwMenuPriority.'.16.1  '.g:NetrwTopLvlMenu.'Style.Listing\ Style\ (thin-long-wide-tree)<tab>i	i'
5251    exe 'sil! menu '.g:NetrwMenuPriority.'.16.2  '.g:NetrwTopLvlMenu.'Style.Normal-Hide-Show<tab>a	a'
5252    exe 'sil! menu '.g:NetrwMenuPriority.'.16.3  '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r	r"
5253    exe 'sil! menu '.g:NetrwMenuPriority.'.16.4  '.g:NetrwTopLvlMenu.'Style.Sorting\ Method\ (name-time-size)<tab>s	s'
5254    exe 'sil! menu '.g:NetrwMenuPriority.'.17    '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R	R'
5255    exe 'sil! menu '.g:NetrwMenuPriority.'.18    '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c	c'
5256    call s:NetrwBookmarkMenu() " provide some history!  uses priorities 2,3, reserves 4, 8.2.x
5257    let s:netrw_menucnt= 28
5258
5259   elseif !a:domenu
5260    let s:netrwcnt = 0
5261    let curwin     = winnr()
5262    windo if getline(2) =~ "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
5263    exe curwin."wincmd w"
5264
5265    if s:netrwcnt <= 1
5266"     call Decho("clear menus")
5267     exe 'sil! unmenu '.g:NetrwTopLvlMenu
5268"     call Decho('exe silent! unmenu '.g:NetrwTopLvlMenu.'*')
5269     sil! unlet s:netrw_menu_enabled
5270    endif
5271   endif
5272"   call Dret("NetrwMenu")
5273  endif
5274
5275endfun
5276
5277" ---------------------------------------------------------------------
5278" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
5279"                Used by the O maps (as <SID>NetrwObtain())
5280fun! s:NetrwObtain(islocal)
5281"  call Dfunc("NetrwObtain(islocal=".a:islocal.")")
5282
5283  if exists("s:netrwmarkfilelist_{bufnr('%')}")
5284   let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\+://'
5285   call netrw#NetrwObtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
5286   call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
5287  else
5288   call netrw#NetrwObtain(a:islocal,expand("<cWORD>"))
5289  endif
5290
5291"  call Dret("NetrwObtain")
5292endfun
5293
5294" ---------------------------------------------------------------------
5295" netrw#NetrwObtain: {{{2
5296"   netrw#NetrwObtain(islocal,fname[,tgtdirectory])
5297"     islocal=0  obtain from remote source
5298"            =1  obtain from local source
5299"     fname  :   a filename or a list of filenames
5300"     tgtdir :   optional place where files are to go  (not present, uses getcwd())
5301fun! netrw#NetrwObtain(islocal,fname,...)
5302"  call Dfunc("netrw#NetrwObtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
5303  " NetrwStatusLine support - for obtaining support
5304
5305  if type(a:fname) == 1
5306   let fnamelist= [ a:fname ]
5307  elseif type(a:fname) == 3
5308   let fnamelist= a:fname
5309  else
5310   call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
5311"   call Dret("netrw#NetrwObtain")
5312   return
5313  endif
5314"  call Decho("fnamelist<".string(fnamelist).">")
5315  if a:0 > 0
5316   let tgtdir= a:1
5317  else
5318   let tgtdir= getcwd()
5319  endif
5320"  call Decho("tgtdir<".tgtdir.">")
5321
5322  if exists("b:netrw_islocal") && b:netrw_islocal
5323   " obtain a file from local b:netrw_curdir to (local) tgtdir
5324"   call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir)
5325   if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
5326    let topath= s:ComposePath(tgtdir,"")
5327    if (has("win32") || has("win95") || has("win64") || has("win16"))
5328     " transfer files one at time
5329"     call Decho("transfer files one at a time")
5330     for fname in fnamelist
5331"      call Decho("system(".g:netrw_localcopycmd." ".shellescape(fname)." ".shellescape(topath).")")
5332      call system(g:netrw_localcopycmd." ".shellescape(fname)." ".shellescape(topath))
5333     endfor
5334    else
5335     " transfer files with one command
5336"     call Decho("transfer files with one command")
5337     let filelist= join(map(deepcopy(fnamelist),"shellescape(v:val)"))
5338"     call Decho("system(".g:netrw_localcopycmd." ".filelist." ".shellescape(topath).")")
5339     call system(g:netrw_localcopycmd." ".filelist." ".shellescape(topath))
5340    endif
5341   elseif !exists("b:netrw_curdir")
5342    call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
5343   else
5344    call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
5345   endif
5346
5347  else
5348   " obtain files from remote b:netrw_curdir to local tgtdir
5349"   call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir)
5350   if type(a:fname) == 1
5351    call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
5352   endif
5353   call s:NetrwMethod(b:netrw_curdir)
5354
5355   if b:netrw_method == 4
5356    " obtain file using scp
5357"    call Decho("obtain via scp (method#4)")
5358    if exists("g:netrw_port") && g:netrw_port != ""
5359     let useport= " ".g:netrw_scpport." ".g:netrw_port
5360    else
5361     let useport= ""
5362    endif
5363    if b:netrw_fname =~ '/'
5364     let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
5365    else
5366     let path= ""
5367    endif
5368    let filelist= join(map(deepcopy(fnamelist),'shellescape(g:netrw_machine.":".path.v:val,1)'))
5369"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_scp_cmd.shellescape(useport,1)." ".filelist." ".shellescape(tgtdir,1))
5370    exe s:netrw_silentxfer."!".g:netrw_scp_cmd.shellescape(useport,1)." ".filelist." ".shellescape(tgtdir,1)
5371
5372   elseif b:netrw_method == 2
5373    " obtain file using ftp + .netrc
5374"     call Decho("obtain via ftp+.netrc (method #2)")
5375     call s:SaveBufVars()|silent keepjumps new|call s:RestoreBufVars()
5376     let tmpbufnr= bufnr("%")
5377     setlocal ff=unix
5378     if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
5379      keepj put =g:netrw_ftpmode
5380"      call Decho("filter input: ".getline('$'))
5381     endif
5382
5383     if exists("b:netrw_fname") && b:netrw_fname != ""
5384      call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
5385"      call Decho("filter input: ".getline('$'))
5386     endif
5387
5388     if exists("g:netrw_ftpextracmd")
5389      keepj put =g:netrw_ftpextracmd
5390"      call Decho("filter input: ".getline('$'))
5391     endif
5392     for fname in fnamelist
5393      call setline(line("$")+1,'get "'.fname.'"')
5394"      call Decho("filter input: ".getline('$'))
5395     endfor
5396     if exists("g:netrw_port") && g:netrw_port != ""
5397"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1))
5398      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1)
5399     else
5400"      call Decho("executing: %!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
5401      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
5402     endif
5403     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
5404     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
5405      let debugkeep= &debug
5406      setlocal debug=msg
5407      call netrw#ErrorMsg(s:ERROR,getline(1),4)
5408      let &debug= debugkeep
5409     endif
5410
5411   elseif b:netrw_method == 3
5412    " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
5413"    call Decho("obtain via ftp+mipf (method #3)")
5414    call s:SaveBufVars()|silent keepjumps new|call s:RestoreBufVars()
5415    let tmpbufnr= bufnr("%")
5416    setlocal ff=unix
5417
5418    if exists("g:netrw_port") && g:netrw_port != ""
5419     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
5420"     call Decho("filter input: ".getline('$'))
5421    else
5422     keepj put ='open '.g:netrw_machine
5423"     call Decho("filter input: ".getline('$'))
5424    endif
5425
5426    if exists("g:netrw_ftp") && g:netrw_ftp == 1
5427     keepj put =g:netrw_uid
5428"     call Decho("filter input: ".getline('$'))
5429     keepj put ='\"'.s:netrw_passwd.'\"'
5430"     call Decho("filter input: ".getline('$'))
5431    else
5432     keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
5433"     call Decho("filter input: ".getline('$'))
5434    endif
5435
5436    if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
5437     keepj put =g:netrw_ftpmode
5438"     call Decho("filter input: ".getline('$'))
5439    endif
5440
5441    if exists("b:netrw_fname") && b:netrw_fname != ""
5442     keepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
5443"     call Decho("filter input: ".getline('$'))
5444    endif
5445
5446    if exists("g:netrw_ftpextracmd")
5447     keepj put =g:netrw_ftpextracmd
5448"     call Decho("filter input: ".getline('$'))
5449    endif
5450
5451    if exists("g:netrw_ftpextracmd")
5452     keepj put =g:netrw_ftpextracmd
5453"     call Decho("filter input: ".getline('$'))
5454    endif
5455    for fname in fnamelist
5456     keepj call setline(line("$")+1,'get "'.fname.'"')
5457    endfor
5458"    call Decho("filter input: ".getline('$'))
5459
5460    " perform ftp:
5461    " -i       : turns off interactive prompting from ftp
5462    " -n  unix : DON'T use <.netrc>, even though it exists
5463    " -n  win32: quit being obnoxious about password
5464    keepj norm! 1Gdd
5465"    call Decho("executing: %!".g:netrw_ftp_cmd." -i -n")
5466    exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
5467    " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
5468    if getline(1) !~ "^$"
5469"     call Decho("error<".getline(1).">")
5470     if !exists("g:netrw_quiet")
5471      call netrw#ErrorMsg(s:ERROR,getline(1),5)
5472     endif
5473    endif
5474   elseif !exists("b:netrw_method") || b:netrw_method < 0
5475"    call Dfunc("netrw#NetrwObtain : unsupported method")
5476    return
5477   endif
5478
5479   " restore status line
5480   if type(a:fname) == 1 && exists("s:netrw_users_stl")
5481    call s:SetupNetrwStatusLine(s:netrw_users_stl)
5482   endif
5483
5484  endif
5485
5486  " cleanup
5487  if exists("tmpbufnr")
5488   if bufnr("%") != tmpbufnr
5489    exe tmpbufnr."bw!"
5490   else
5491    q!
5492   endif
5493  endif
5494
5495"  call Dret("netrw#NetrwObtain")
5496endfun
5497
5498" ---------------------------------------------------------------------
5499" s:NetrwPrevWinOpen: open file/directory in previous window.  {{{2
5500"   If there's only one window, then the window will first be split.
5501"   Returns:
5502"     choice = 0 : didn't have to choose
5503"     choice = 1 : saved modified file in window first
5504"     choice = 2 : didn't save modified file, opened window
5505"     choice = 3 : cancel open
5506fun! s:NetrwPrevWinOpen(islocal)
5507"  call Dfunc("NetrwPrevWinOpen(islocal=".a:islocal.")")
5508
5509  " grab a copy of the b:netrw_curdir to pass it along to newly split windows
5510  let curdir    = b:netrw_curdir
5511
5512  " get last window number and the word currently under the cursor
5513  let lastwinnr = winnr("$")
5514  let curword   = s:NetrwGetWord()
5515  let choice    = 0
5516"  call Decho("lastwinnr=".lastwinnr." curword<".curword.">")
5517
5518  let didsplit  = 0
5519  if lastwinnr == 1
5520   " if only one window, open a new one first
5521"   call Decho("only one window, so open a new one (g:netrw_alto=".g:netrw_alto.")")
5522   if g:netrw_preview
5523"    call Decho("exe ".(g:netrw_alto? "top " : "bot ")."vert ".g:netrw_winsize."wincmd s")
5524    exe (g:netrw_alto? "top " : "bot ")."vert ".g:netrw_winsize."wincmd s"
5525   else
5526"    call Decho("exe ".(g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s")
5527    exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
5528   endif
5529   let didsplit  = 1
5530
5531  else
5532   call s:SaveBufVars()
5533"   call Decho("wincmd p")
5534   wincmd p
5535   call s:RestoreBufVars()
5536   " if the previous window's buffer has been changed (is modified),
5537   " and it doesn't appear in any other extant window, then ask the
5538   " user if s/he wants to abandon modifications therein.
5539   let bnr    = winbufnr(0)
5540   let bnrcnt = 0
5541   if &mod
5542"    call Decho("detected: prev window's buffer has been modified: bnr=".bnr." winnr#".winnr())
5543    let eikeep= &ei
5544    set ei=all
5545    windo if winbufnr(0) == bnr | let bnrcnt=bnrcnt+1 | endif
5546    exe bnr."wincmd p"
5547    let &ei= eikeep
5548"    call Decho("bnr=".bnr." bnrcnt=".bnrcnt." buftype=".&bt." winnr#".winnr())
5549    if bnrcnt == 1
5550     let bufname = bufname(winbufnr(winnr()))
5551     let choice  = confirm("Save modified file<".bufname.">?","&Yes\n&No\n&Cancel")
5552"     call Decho("bufname<".bufname."> choice=".choice." winnr#".winnr())
5553
5554     if choice == 1
5555      " Yes -- write file & then browse
5556      let v:errmsg= ""
5557      silent w
5558      if v:errmsg != ""
5559       call netrw#ErrorMsg(s:ERROR,"unable to write <".bufname.">!",30)
5560       if didsplit
5561       	q
5562       else
5563       	wincmd p
5564       endif
5565"       call Dret("NetrwPrevWinOpen ".choice." : unable to write <".bufname.">")
5566       return choice
5567      endif
5568
5569     elseif choice == 2
5570      " No -- don't worry about changed file, just browse anyway
5571      setlocal nomod
5572      call netrw#ErrorMsg(s:WARNING,bufname." changes to ".bufname." abandoned",31)
5573      wincmd p
5574
5575     else
5576      " Cancel -- don't do this
5577      if didsplit
5578       q
5579      else
5580       wincmd p
5581      endif
5582"      call Dret("NetrwPrevWinOpen ".choice." : cancelled")
5583      return choice
5584     endif
5585    endif
5586   endif
5587  endif
5588
5589  " restore b:netrw_curdir (window split/enew may have lost it)
5590  let b:netrw_curdir= curdir
5591  if a:islocal < 2
5592   if a:islocal
5593    call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword))
5594   else
5595    call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword))
5596   endif
5597  endif
5598"  call Dret("NetrwPrevWinOpen ".choice)
5599  return choice
5600endfun
5601
5602" ---------------------------------------------------------------------
5603" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
5604"                Always assumed to be local -> remote
5605"                call s:NetrwUpload(filename, target)
5606"                call s:NetrwUpload(filename, target, fromdirectory)
5607fun! s:NetrwUpload(fname,tgt,...)
5608"  call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
5609
5610  if a:tgt =~ '^\a\+://'
5611   let tgtdir= substitute(a:tgt,'^\a\+://[^/]\+/\(.\{-}\)$','\1','')
5612  else
5613   let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
5614  endif
5615"  call Decho("tgtdir<".tgtdir.">")
5616
5617  if a:0 > 0
5618   let fromdir= a:1
5619  else
5620   let fromdir= getcwd()
5621  endif
5622"  call Decho("fromdir<".fromdir.">")
5623
5624  if type(a:fname) == 1
5625   " handle uploading a single file using NetWrite
5626"   call Decho("handle uploading a single file via NetWrite")
5627   1split
5628"   call Decho("exe e ".fnameescape(a:fname))
5629   exe "e ".fnameescape(a:fname)
5630"   call Decho("now locally editing<".expand("%").">, has ".line("$")." lines")
5631   if a:tgt =~ '/$'
5632    let wfname= substitute(a:fname,'^.*/','','')
5633"    call Decho("exe w! ".fnameescape(wfname))
5634    exe "w! ".fnameescape(a:tgt.wfname)
5635   else
5636"    call Decho("writing local->remote: exe w ".fnameescape(a:tgt))
5637    exe "w ".fnameescape(a:tgt)
5638"    call Decho("done writing local->remote")
5639   endif
5640   q!
5641
5642  elseif type(a:fname) == 3
5643   " handle uploading a list of files via scp
5644"   call Decho("handle uploading a list of files via scp")
5645   let curdir= getcwd()
5646   if a:tgt =~ '^scp:'
5647    exe "keepjumps silent lcd ".fnameescape(fromdir)
5648    let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
5649    let args    = join(map(filelist,"shellescape(v:val, 1)"))
5650    if exists("g:netrw_port") && g:netrw_port != ""
5651     let useport= " ".g:netrw_scpport." ".g:netrw_port
5652    else
5653     let useport= ""
5654    endif
5655    let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
5656    let tgt     = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
5657"    call Decho("exe ".s:netrw_silentxfer."!".g:netrw_scp_cmd.shellescape(useport,1)." ".args." ".shellescape(machine.":".tgt,1))
5658    exe s:netrw_silentxfer."!".g:netrw_scp_cmd.shellescape(useport,1)." ".args." ".shellescape(machine.":".tgt,1)
5659    exe "keepjumps silent lcd ".fnameescape(curdir)
5660
5661   elseif a:tgt =~ '^ftp:'
5662    call s:NetrwMethod(a:tgt)
5663
5664    if b:netrw_method == 2
5665     " handle uploading a list of files via ftp+.netrc
5666     let netrw_fname = b:netrw_fname
5667     sil keepj new
5668"     call Decho("filter input window#".winnr())
5669
5670     keepj put =g:netrw_ftpmode
5671"     call Decho("filter input: ".getline('$'))
5672
5673     if exists("g:netrw_ftpextracmd")
5674      keepj put =g:netrw_ftpextracmd
5675"      call Decho("filter input: ".getline('$'))
5676     endif
5677
5678     keepj call setline(line("$")+1,'lcd "'.fromdir.'"')
5679"     call Decho("filter input: ".getline('$'))
5680
5681     keepj call setline(line("$")+1,'cd "'.tgtdir.'"')
5682"     call Decho("filter input: ".getline('$'))
5683
5684     for fname in a:fname
5685      keepj call setline(line("$")+1,'put "'.fname.'"')
5686"      call Decho("filter input: ".getline('$'))
5687     endfor
5688
5689     if exists("g:netrw_port") && g:netrw_port != ""
5690"      call Decho("executing: ".s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1))
5691      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1)
5692     else
5693"      call Decho("filter input window#".winnr())
5694"      call Decho("executing: ".s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
5695      exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
5696     endif
5697     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
5698     sil keepj g/Local directory now/d
5699     call histdel("/",-1)
5700     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
5701      call netrw#ErrorMsg(s:ERROR,getline(1),14)
5702     else
5703      bw!|q
5704     endif
5705
5706    elseif b:netrw_method == 3
5707     " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
5708     let netrw_fname= b:netrw_fname
5709     call s:SaveBufVars()|silent keepjumps new|call s:RestoreBufVars()
5710     let tmpbufnr= bufnr("%")
5711     setlocal ff=unix
5712
5713     if exists("g:netrw_port") && g:netrw_port != ""
5714      keepj put ='open '.g:netrw_machine.' '.g:netrw_port
5715"      call Decho("filter input: ".getline('$'))
5716     else
5717      keepj put ='open '.g:netrw_machine
5718"      call Decho("filter input: ".getline('$'))
5719     endif
5720
5721     if exists("g:netrw_ftp") && g:netrw_ftp == 1
5722      keepj put =g:netrw_uid
5723"      call Decho("filter input: ".getline('$'))
5724      keepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
5725"      call Decho("filter input: ".getline('$'))
5726     else
5727      keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
5728"      call Decho("filter input: ".getline('$'))
5729     endif
5730
5731     keepj call setline(line("$")+1,'lcd "'.fromdir.'"')
5732"     call Decho("filter input: ".getline('$'))
5733
5734     if exists("b:netrw_fname") && b:netrw_fname != ""
5735      keepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
5736"      call Decho("filter input: ".getline('$'))
5737     endif
5738
5739     if exists("g:netrw_ftpextracmd")
5740      keepj put =g:netrw_ftpextracmd
5741"      call Decho("filter input: ".getline('$'))
5742     endif
5743
5744     for fname in a:fname
5745      keepj call setline(line("$")+1,'put "'.fname.'"')
5746"      call Decho("filter input: ".getline('$'))
5747     endfor
5748
5749     " perform ftp:
5750     " -i       : turns off interactive prompting from ftp
5751     " -n  unix : DON'T use <.netrc>, even though it exists
5752     " -n  win32: quit being obnoxious about password
5753     keepj norm! 1Gdd
5754"     call Decho("executing: ".s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n")
5755     exe s:netrw_silentxfer."%!".g:netrw_ftp_cmd." -i -n"
5756     " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
5757     sil keepj g/Local directory now/d
5758     call histdel("/",-1)
5759     if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
5760      let debugkeep= &debug
5761      setlocal debug=msg
5762      call netrw#ErrorMsg(s:ERROR,getline(1),15)
5763      let &debug = debugkeep
5764      let mod    = 1
5765     else
5766      bw!|q
5767     endif
5768    elseif !exists("b:netrw_method") || b:netrw_method < 0
5769"     call Dfunc("netrw#NetrwUpload : unsupported method")
5770     return
5771    endif
5772   else
5773    call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
5774   endif
5775  endif
5776
5777"  call Dret("s:NetrwUpload")
5778endfun
5779
5780" ---------------------------------------------------------------------
5781" s:NetrwPreview: {{{2
5782fun! s:NetrwPreview(path) range
5783"  call Dfunc("NetrwPreview(path<".a:path.">)")
5784  call s:NetrwOptionSave("s:")
5785  call s:NetrwSafeOptions()
5786  if has("quickfix")
5787   if !isdirectory(a:path)
5788    if g:netrw_preview && !g:netrw_alto
5789     let pvhkeep= &pvh
5790     let &pvh   = winwidth(0) - g:netrw_winsize
5791    endif
5792    exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
5793    if exists("pvhkeep")
5794     let &pvh= pvhkeep
5795    endif
5796   elseif !exists("g:netrw_quiet")
5797    call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
5798   endif
5799  elseif !exists("g:netrw_quiet")
5800   call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
5801  endif
5802  call s:NetrwOptionRestore("s:")
5803"  call Dret("NetrwPreview")
5804endfun
5805
5806" ---------------------------------------------------------------------
5807" s:NetrwRefresh: {{{2
5808fun! s:NetrwRefresh(islocal,dirname)
5809"  call Dfunc("NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") hide=".g:netrw_hide." sortdir=".g:netrw_sort_direction)
5810  " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
5811  " NetrwBrowseChgDir() may clear the display; hence a NetrwSavePosn() may not work if its placed here.
5812  " Also, NetrwBrowseChgDir() now does a NetrwSavePosn() itself.
5813  setlocal ma noro
5814"  call Decho("setlocal ma noro")
5815"  call Decho("clear buffer<".expand("%")."> with :%d")
5816  sil! keepj %d
5817  if a:islocal
5818   call netrw#LocalBrowseCheck(a:dirname)
5819  else
5820   call s:NetrwBrowse(a:islocal,a:dirname)
5821  endif
5822  call netrw#NetrwRestorePosn()
5823
5824  " restore file marks
5825  if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
5826"   call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/")
5827   exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
5828  else
5829"   call Decho("2match none")
5830   2match none
5831  endif
5832
5833"  redraw!
5834"  call Dret("NetrwRefresh")
5835endfun
5836
5837" ---------------------------------------------------------------------
5838" s:NetrwRefreshDir: refreshes a directory by name {{{2
5839"                    Called by NetrwMarkFileCopy()
5840"                    Interfaces to s:NetrwRefresh() and s:LocalBrowseShellCmdRefresh()
5841fun! s:NetrwRefreshDir(islocal,dirname)
5842"  call Dfunc("s:NetrwRefreshDir(islocal=".a:islocal." dirname<".a:dirname.">) fastbrowse=".g:netrw_fastbrowse)
5843  if g:netrw_fastbrowse == 0
5844   " slowest mode (keep buffers refreshed, local or remote)
5845"   call Decho("slowest mode: keep buffers refreshed, local or remote")
5846   let tgtwin= bufwinnr(a:dirname)
5847"   call Decho("tgtwin= bufwinnr(".a:dirname.")=".tgtwin)
5848
5849   if tgtwin > 0
5850    " tgtwin is being displayed, so refresh it
5851    let curwin= winnr()
5852"    call Decho("refresh tgtwin#".tgtwin." (curwin#".curwin.")")
5853    exe tgtwin."wincmd w"
5854    call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./')) 
5855    exe curwin."wincmd w"
5856
5857   elseif bufnr(a:dirname) > 0
5858    let bn= bufnr(a:dirname)
5859"    call Decho("bd bufnr(".a:dirname.")=".bn)
5860    exe "silent bd ".bn
5861   endif
5862
5863  elseif g:netrw_fastbrowse <= 1
5864"   call Decho("medium-speed mode: refresh local buffers only")
5865   call s:LocalBrowseShellCmdRefresh()
5866  endif
5867"  call Dret("s:NetrwRefreshDir")
5868endfun
5869
5870" ---------------------------------------------------------------------
5871" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
5872"          What this function does is to compute a priority for the patterns
5873"          in the g:netrw_sort_sequence.  It applies a substitute to any
5874"          "files" that satisfy each pattern, putting the priority / in
5875"          front.  An "*" pattern handles the default priority.
5876fun! s:NetrwSetSort()
5877"  call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
5878  if w:netrw_liststyle == s:LONGLIST
5879   let seqlist  = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
5880  else
5881   let seqlist  = g:netrw_sort_sequence
5882  endif
5883  " sanity check -- insure that * appears somewhere
5884  if seqlist == ""
5885   let seqlist= '*'
5886  elseif seqlist !~ '\*'
5887   let seqlist= seqlist.',*'
5888  endif
5889  let priority = 1
5890  while seqlist != ""
5891   if seqlist =~ ','
5892    let seq     = substitute(seqlist,',.*$','','e')
5893    let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
5894   else
5895    let seq     = seqlist
5896    let seqlist = ""
5897   endif
5898   if priority < 10
5899    let spriority= "00".priority.g:netrw_sepchr
5900   elseif priority < 100
5901    let spriority= "0".priority.g:netrw_sepchr
5902   else
5903    let spriority= priority.g:netrw_sepchr
5904   endif
5905"   call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">")
5906
5907   " sanity check
5908   if w:netrw_bannercnt > line("$")
5909    " apparently no files were left after a Hiding pattern was used
5910"    call Dret("SetSort : no files left after hiding")
5911    return
5912   endif
5913   if seq == '*'
5914    let starpriority= spriority
5915   else
5916    exe 'sil keepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
5917    call histdel("/",-1)
5918    " sometimes multiple sorting patterns will match the same file or directory.
5919    " The following substitute is intended to remove the excess matches.
5920    exe 'sil keepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
5921    call histdel("/",-1)
5922   endif
5923   let priority = priority + 1
5924  endwhile
5925  if exists("starpriority")
5926   exe 'sil keepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/'
5927   call histdel("/",-1)
5928  endif
5929
5930  " Following line associated with priority -- items that satisfy a priority
5931  " pattern get prefixed by ###/ which permits easy sorting by priority.
5932  " Sometimes files can satisfy multiple priority patterns -- only the latest
5933  " priority pattern needs to be retained.  So, at this point, these excess
5934  " priority prefixes need to be removed, but not directories that happen to
5935  " be just digits themselves.
5936  exe 'sil keepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
5937  call histdel("/",-1)
5938
5939"  call Dret("SetSort")
5940endfun
5941
5942" =====================================================================
5943" s:NetrwSortStyle: change sorting style (name - time - size) and refresh display {{{2
5944fun! s:NetrwSortStyle(islocal)
5945"  call Dfunc("s:NetrwSortStyle(islocal=".a:islocal.") netrw_sort_by<".g:netrw_sort_by.">")
5946  call s:NetrwSaveWordPosn()
5947  let svpos= netrw#NetrwSavePosn()
5948
5949  let g:netrw_sort_by= (g:netrw_sort_by =~ 'n')? 'time' : (g:netrw_sort_by =~ 't')? 'size' : 'name'
5950  keepj norm! 0
5951  call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./'))
5952  call netrw#NetrwRestorePosn(svpos)
5953
5954"  call Dret("s:NetrwSortStyle : netrw_sort_by<".g:netrw_sort_by.">")
5955endfun
5956
5957" ---------------------------------------------------------------------
5958" s:NetrwSplit: mode {{{2
5959"           =0 : net   and o
5960"           =1 : net   and t
5961"           =2 : net   and v
5962"           =3 : local and o
5963"           =4 : local and t
5964"           =5 : local and v
5965fun! s:NetrwSplit(mode)
5966"  call Dfunc("s:NetrwSplit(mode=".a:mode.") alto=".g:netrw_alto." altv=".g:netrw_altv)
5967
5968  call s:SaveWinVars()
5969
5970  if a:mode == 0
5971   " remote and o
5972"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s")
5973   exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
5974   let s:didsplit= 1
5975   call s:RestoreWinVars()
5976   call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5977   unlet s:didsplit
5978
5979  elseif a:mode == 1
5980   " remote and t
5981   let newdir  = s:NetrwBrowseChgDir(0,s:NetrwGetWord())
5982"   call Decho("tabnew")
5983   tabnew
5984   let s:didsplit= 1
5985   call s:RestoreWinVars()
5986   call s:NetrwBrowse(0,newdir)
5987   unlet s:didsplit
5988
5989  elseif a:mode == 2
5990   " remote and v
5991"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v")
5992   exe (g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v"
5993   let s:didsplit= 1
5994   call s:RestoreWinVars()
5995   call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord()))
5996   unlet s:didsplit
5997
5998  elseif a:mode == 3
5999   " local and o
6000"   call Decho("exe ".(g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s")
6001   exe (g:netrw_alto? "bel " : "abo ").g:netrw_winsize."wincmd s"
6002   let s:didsplit= 1
6003   call s:RestoreWinVars()
6004   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
6005   unlet s:didsplit
6006
6007  elseif a:mode == 4
6008   " local and t
6009   let cursorword  = s:NetrwGetWord()
6010   let netrw_curdir= s:NetrwTreeDir()
6011"   call Decho("tabnew")
6012   tabnew
6013   let b:netrw_curdir= netrw_curdir
6014   let s:didsplit= 1
6015   call s:RestoreWinVars()
6016   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword))
6017   unlet s:didsplit
6018
6019  elseif a:mode == 5
6020   " local and v
6021"   call Decho("exe ".(g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v")
6022   exe (g:netrw_altv? "rightb " : "lefta ").g:netrw_winsize."wincmd v"
6023   let s:didsplit= 1
6024   call s:RestoreWinVars()
6025   call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord()))
6026   unlet s:didsplit
6027
6028  else
6029   call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
6030  endif
6031
6032"  call Dret("s:NetrwSplit")
6033endfun
6034
6035" ---------------------------------------------------------------------
6036" NetrwStatusLine: {{{2
6037fun! NetrwStatusLine()
6038
6039" vvv NetrwStatusLine() debugging vvv
6040"  let g:stlmsg=""
6041"  if !exists("w:netrw_explore_bufnr")
6042"   let g:stlmsg="!X<explore_bufnr>"
6043"  elseif w:netrw_explore_bufnr != bufnr("%")
6044"   let g:stlmsg="explore_bufnr!=".bufnr("%")
6045"  endif
6046"  if !exists("w:netrw_explore_line")
6047"   let g:stlmsg=" !X<explore_line>"
6048"  elseif w:netrw_explore_line != line(".")
6049"   let g:stlmsg=" explore_line!={line(.)<".line(".").">"
6050"  endif
6051"  if !exists("w:netrw_explore_list")
6052"   let g:stlmsg=" !X<explore_list>"
6053"  endif
6054" ^^^ NetrwStatusLine() debugging ^^^
6055
6056  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")
6057   " restore user's status line
6058   let &stl        = s:netrw_users_stl
6059   let &laststatus = s:netrw_users_ls
6060   if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
6061   if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
6062   return ""
6063  else
6064   return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
6065  endif
6066endfun
6067
6068" ---------------------------------------------------------------------
6069" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
6070" (full path directory with trailing slash returned)
6071fun! s:NetrwTreeDir()
6072"  call Dfunc("NetrwTreeDir() curline#".line(".")."<".getline('.')."> b:netrw_curdir<".b:netrw_curdir."> tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">")
6073
6074  let treedir= b:netrw_curdir
6075"  call Decho("set initial treedir<".treedir.">")
6076  let s:treecurpos= netrw#NetrwSavePosn()
6077
6078  if w:netrw_liststyle == s:TREELIST
6079"   call Decho("w:netrrw_liststyle is TREELIST:")
6080"   call Decho("line#".line(".")." getline(.)<".getline('.')."> treecurpos<".string(s:treecurpos).">")
6081
6082   " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
6083   if getline('.') =~ '/$'
6084    let treedir= substitute(getline('.'),'^\%(| \)*\([^|].\{-}\)$','\1','e')
6085   else
6086    let treedir= ""
6087   endif
6088"   call Decho("treedir<".treedir.">")
6089
6090   " detect user attempting to close treeroot
6091   if getline('.') !~ '|' && getline('.') != '..'
6092"    call Decho("user attempted to close treeroot")
6093    " now force a refresh
6094"    call Decho("clear buffer<".expand("%")."> with :%d")
6095    sil! keepj %d
6096"    call Dret("NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">")
6097    return b:netrw_curdir
6098   endif
6099
6100   " elide all non-depth information
6101   let depth = substitute(getline('.'),'^\(\%(| \)*\)[^|].\{-}$','\1','e')
6102"   call Decho("depth<".depth."> 1st subst (non-depth info removed)")
6103
6104   " elide first depth
6105   let depth = substitute(depth,'^| ','','')
6106"   call Decho("depth<".depth."> 2nd subst (first depth removed)")
6107
6108   " construct treedir by searching backwards at correct depth
6109"   call Decho("constructing treedir<".treedir."> depth<".depth.">")
6110   while depth != "" && search('^'.depth.'[^|].\{-}/$','bW')
6111    let dirname= substitute(getline('.'),'^\(| \)*','','e')
6112    let treedir= dirname.treedir
6113    let depth  = substitute(depth,'^| ','','')
6114"    call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">")
6115   endwhile
6116   if w:netrw_treetop =~ '/$'
6117    let treedir= w:netrw_treetop.treedir
6118   else
6119    let treedir= w:netrw_treetop.'/'.treedir
6120   endif
6121"   call Decho("bufnr(.)=".bufnr("%")." line($)=".line("$")." line(.)=".line("."))
6122  endif
6123  let treedir= substitute(treedir,'//$','/','')
6124
6125"  call Dret("NetrwTreeDir <".treedir."> : (side effect) s:treecurpos<".string(s:treecurpos).">")
6126  return treedir
6127endfun
6128
6129" ---------------------------------------------------------------------
6130" s:NetrwTreeDisplay: recursive tree display {{{2
6131fun! s:NetrwTreeDisplay(dir,depth)
6132"  call Dfunc("NetrwTreeDisplay(dir<".a:dir."> depth<".a:depth.">)")
6133
6134  " insure that there are no folds
6135  setlocal nofen
6136
6137  " install ../ and shortdir
6138  if a:depth == ""
6139   call setline(line("$")+1,'../')
6140"   call Decho("setline#".line("$")." ../ (depth is zero)")
6141  endif
6142  if a:dir =~ '^\a\+://'
6143   if a:dir == w:netrw_treetop
6144    let shortdir= a:dir
6145   else
6146    let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
6147   endif
6148   call setline(line("$")+1,a:depth.shortdir)
6149  else
6150   let shortdir= substitute(a:dir,'^.*/','','e')
6151   call setline(line("$")+1,a:depth.shortdir.'/')
6152  endif
6153"  call Decho("setline#".line("$")." shortdir<".a:depth.shortdir.">")
6154
6155  " append a / to dir if its missing one
6156  let dir= a:dir
6157  if dir !~ '/$'
6158   let dir= dir.'/'
6159  endif
6160
6161  " display subtrees (if any)
6162  let depth= "| ".a:depth
6163
6164"  call Decho("display subtrees with depth<".depth."> and current leaves")
6165  for entry in w:netrw_treedict[a:dir]
6166   let direntry= substitute(dir.entry,'/$','','e')
6167"   call Decho("dir<".dir."> entry<".entry."> direntry<".direntry.">")
6168   if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
6169"    call Decho("<".direntry."> is a key in treedict - display subtree for it")
6170    call s:NetrwTreeDisplay(direntry,depth)
6171   elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
6172"    call Decho("<".direntry."/> is a key in treedict - display subtree for it")
6173    call s:NetrwTreeDisplay(direntry.'/',depth)
6174   else
6175"    call Decho("<".entry."> is not a key in treedict (no subtree)")
6176    sil! keepj call setline(line("$")+1,depth.entry)
6177   endif
6178  endfor
6179"  call Dret("NetrwTreeDisplay")
6180endfun
6181
6182" ---------------------------------------------------------------------
6183" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
6184fun! s:NetrwTreeListing(dirname)
6185  if w:netrw_liststyle == s:TREELIST
6186"   call Dfunc("NetrwTreeListing() bufname<".expand("%").">")
6187"   call Decho("curdir<".a:dirname.">")
6188"   call Decho("win#".winnr().": w:netrw_treetop ".(exists("w:netrw_treetop")? "exists" : "doesn't exit")." w:netrw_treedict ".(exists("w:netrw_treedict")? "exists" : "doesn't exit"))
6189
6190   " update the treetop
6191"   call Decho("update the treetop")
6192   if !exists("w:netrw_treetop")
6193    let w:netrw_treetop= a:dirname
6194"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)")
6195   elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop)
6196    let w:netrw_treetop= a:dirname
6197"    call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)")
6198   endif
6199
6200   " insure that we have at least an empty treedict
6201   if !exists("w:netrw_treedict")
6202    let w:netrw_treedict= {}
6203   endif
6204
6205   " update the directory listing for the current directory
6206"   call Decho("updating dictionary with ".a:dirname.":[..directory listing..]")
6207"   call Decho("bannercnt=".w:netrw_bannercnt." line($)=".line("$"))
6208   exe "sil! keepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d'
6209   let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
6210"   call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]))
6211   exe "sil! keepj ".w:netrw_bannercnt.",$d"
6212
6213   " if past banner, record word
6214   if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
6215    let fname= expand("<cword>")
6216   else
6217    let fname= ""
6218   endif
6219"   call Decho("fname<".fname.">")
6220
6221   " display from treetop on down
6222   call s:NetrwTreeDisplay(w:netrw_treetop,"")
6223
6224"   call Dret("NetrwTreeListing : bufname<".expand("%").">")
6225  endif
6226endfun
6227
6228" ---------------------------------------------------------------------
6229" s:NetrwWideListing: {{{2
6230fun! s:NetrwWideListing()
6231
6232  if w:netrw_liststyle == s:WIDELIST
6233"   call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
6234   " look for longest filename (cpf=characters per filename)
6235   " cpf: characters per filename
6236   " fpl: filenames per line
6237   " fpc: filenames per column
6238   setlocal ma noro
6239"   call Decho("setlocal ma noro")
6240   let b:netrw_cpf= 0
6241   if line("$") >= w:netrw_bannercnt
6242    exe 'sil keepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
6243    call histdel("/",-1)
6244   else
6245"    call Dret("NetrwWideListing")
6246    return
6247   endif
6248   let b:netrw_cpf= b:netrw_cpf + 2
6249"   call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf)
6250
6251   " determine qty files per line (fpl)
6252   let w:netrw_fpl= winwidth(0)/b:netrw_cpf
6253   if w:netrw_fpl <= 0
6254    let w:netrw_fpl= 1
6255   endif
6256"   call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl)
6257
6258   " make wide display
6259   exe 'sil keepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'s",submatch(0)),"\\")/'
6260   call histdel("/",-1)
6261   let fpc         = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
6262   let newcolstart = w:netrw_bannercnt + fpc
6263   let newcolend   = newcolstart + fpc - 1
6264"   call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]")
6265   sil! let keepregstar = @*
6266   while line("$") >= newcolstart
6267    if newcolend > line("$") | let newcolend= line("$") | endif
6268    let newcolqty= newcolend - newcolstart
6269    exe newcolstart
6270    if newcolqty == 0
6271     exe "sil! keepj norm! 0\<c-v>$hx".w:netrw_bannercnt."G$p"
6272    else
6273     exe "sil! keepj norm! 0\<c-v>".newcolqty.'j$hx'.w:netrw_bannercnt.'G$p'
6274    endif
6275    exe "sil! keepj ".newcolstart.','.newcolend.'d'
6276    exe 'sil! keepj '.w:netrw_bannercnt
6277   endwhile
6278   silent! let @*= keepregstar
6279   exe "sil! keepj ".w:netrw_bannercnt.',$s/\s\+$//e'
6280   call histdel("/",-1)
6281   setlocal noma nomod ro
6282"   call Dret("NetrwWideListing")
6283  endif
6284
6285endfun
6286
6287" ---------------------------------------------------------------------
6288" s:PerformListing: {{{2
6289fun! s:PerformListing(islocal)
6290"  call Dfunc("s:PerformListing(islocal=".a:islocal.") bufnr(%)=".bufnr("%")."<".bufname("%").">")
6291
6292  call s:NetrwSafeOptions()
6293  setlocal noro ma
6294"  call Decho("setlocal noro ma")
6295
6296"  if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1	" Decho
6297"   call Decho("(netrw) Processing your browsing request...")
6298"  endif								" Decho
6299
6300"  call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'))
6301  if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6302   " force a refresh for tree listings
6303"   call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d")
6304   sil! keepj %d
6305  endif
6306
6307  " save current directory on directory history list
6308  call s:NetrwBookHistHandler(3,b:netrw_curdir)
6309
6310  " Set up the banner {{{3
6311  if g:netrw_banner
6312"   call Decho("set up banner")
6313   keepj put ='\" ============================================================================'
6314   keepj put ='\" Netrw Directory Listing                                        (netrw '.g:loaded_netrw.')'
6315   keepj put ='\"   '.b:netrw_curdir
6316   keepj 1d
6317   let w:netrw_bannercnt= 3
6318   exe "sil! keepj ".w:netrw_bannercnt
6319  else
6320   keepj 1
6321   let w:netrw_bannercnt= 1
6322  endif
6323
6324  let sortby= g:netrw_sort_by
6325  if g:netrw_sort_direction =~ "^r"
6326   let sortby= sortby." reversed"
6327  endif
6328
6329  " Sorted by... {{{3
6330  if g:netrw_banner
6331"   call Decho("handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">")
6332   if g:netrw_sort_by =~ "^n"
6333"   call Decho("directories will be sorted by name")
6334    " sorted by name
6335    keepj put ='\"   Sorted by      '.sortby
6336    keepj put ='\"   Sort sequence: '.g:netrw_sort_sequence
6337    let w:netrw_bannercnt= w:netrw_bannercnt + 2
6338   else
6339"   call Decho("directories will be sorted by size or time")
6340    " sorted by size or date
6341    keepj put ='\"   Sorted by '.sortby
6342    let w:netrw_bannercnt= w:netrw_bannercnt + 1
6343   endif
6344   exe "sil! keepj ".w:netrw_bannercnt
6345  endif
6346
6347  " show copy/move target, if any
6348  if g:netrw_banner
6349   if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
6350"    call Decho("show copy/move target<".s:netrwmftgt.">")
6351    keepj put =''
6352    if s:netrwmftgt_islocal
6353     sil! keepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (local)')
6354    else
6355     sil! keepj call setline(line("."),'"   Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
6356    endif
6357    let w:netrw_bannercnt= w:netrw_bannercnt + 1
6358   else
6359"    call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt")
6360   endif
6361   exe "sil! keepj ".w:netrw_bannercnt
6362  endif
6363
6364  " Hiding...  -or-  Showing... {{{3
6365  if g:netrw_banner
6366"   call Decho("handle hiding/showing (g:netrw_hide=".g:netrw_list_hide." g:netrw_list_hide<".g:netrw_list_hide.">)")
6367   if g:netrw_list_hide != "" && g:netrw_hide
6368    if g:netrw_hide == 1
6369     keepj put ='\"   Hiding:        '.g:netrw_list_hide
6370    else
6371     keepj put ='\"   Showing:       '.g:netrw_list_hide
6372    endif
6373    let w:netrw_bannercnt= w:netrw_bannercnt + 1
6374   endif
6375   exe "keepjumps ".w:netrw_bannercnt
6376   keepj put ='\"   Quick Help: <F1>:help  -:go up dir  D:delete  R:rename  s:sort-by  x:exec'
6377   keepj put ='\" ============================================================================'
6378   let w:netrw_bannercnt= w:netrw_bannercnt + 2
6379  endif
6380
6381  " bannercnt should index the line just after the banner
6382  if g:netrw_banner
6383   let w:netrw_bannercnt= w:netrw_bannercnt + 1
6384   exe "sil! keepj ".w:netrw_bannercnt
6385"   call Decho("bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"))
6386  endif
6387
6388  " set up syntax highlighting {{{3
6389"  call Decho("set up syntax highlighting")
6390  if has("syntax")
6391   setf netrw
6392   if !exists("g:syntax_on") || !g:syntax_on
6393    setlocal ft=
6394   endif
6395  endif
6396
6397  " get list of files
6398"  call Decho("Get list of files - islocal=".a:islocal)
6399  if a:islocal
6400   call s:LocalListing()
6401  else " remote
6402   call s:NetrwRemoteListing()
6403  endif
6404"  call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)")
6405
6406  " manipulate the directory listing (hide, sort) {{{3
6407  if !g:netrw_banner || line("$") >= w:netrw_bannercnt
6408"   call Decho("manipulate directory listing (hide)")
6409"   call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
6410   if g:netrw_hide && g:netrw_list_hide != ""
6411    call s:NetrwListHide()
6412   endif
6413   if !g:netrw_banner || line("$") >= w:netrw_bannercnt
6414"    call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">")
6415
6416    if g:netrw_sort_by =~ "^n"
6417     " sort by name
6418     call s:NetrwSetSort()
6419
6420     if !g:netrw_banner || w:netrw_bannercnt < line("$")
6421"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")")
6422      if g:netrw_sort_direction =~ 'n'
6423       " normal direction sorting
6424       exe 'sil keepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
6425      else
6426       " reverse direction sorting
6427       exe 'sil keepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
6428      endif
6429     endif
6430     " remove priority pattern prefix
6431"     call Decho("remove priority pattern prefix")
6432     exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
6433     call histdel("/",-1)
6434
6435    elseif a:islocal
6436     if !g:netrw_banner || w:netrw_bannercnt < line("$")
6437"      call Decho("g:netrw_sort_direction=".g:netrw_sort_direction)
6438      if g:netrw_sort_direction =~ 'n'
6439"       call Decho('exe silent keepjumps '.w:netrw_bannercnt.',$sort')
6440       exe 'sil! keepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
6441      else
6442"       call Decho('exe silent keepjumps '.w:netrw_bannercnt.',$sort!')
6443       exe 'sil! keepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
6444      endif
6445     exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
6446     call histdel("/",-1)
6447     endif
6448    endif
6449
6450   elseif g:netrw_sort_direction =~ 'r'
6451"    call Decho('reverse the sorted listing')
6452    if !g:netrw_banner || w:netrw_bannercnt < line('$')
6453     exe 'sil! keepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
6454     call histdel("/",-1)
6455    endif
6456   endif
6457  endif
6458
6459  " convert to wide/tree listing {{{3
6460"  call Decho("modify display if wide/tree listing style")
6461  call s:NetrwWideListing()
6462  call s:NetrwTreeListing(b:netrw_curdir)
6463
6464  if exists("w:netrw_bannercnt") && (line("$") > w:netrw_bannercnt || !g:netrw_banner)
6465   " place cursor on the top-left corner of the file listing
6466"   call Decho("place cursor on top-left corner of file listing")
6467   exe 'sil! keepj '.w:netrw_bannercnt
6468   sil! keepj norm! 0
6469  endif
6470
6471  " record previous current directory
6472  let w:netrw_prvdir= b:netrw_curdir
6473"  call Decho("record netrw_prvdir<".w:netrw_prvdir.">")
6474
6475  " save certain window-oriented variables into buffer-oriented variables {{{3
6476  call s:SetBufWinVars()
6477  call s:NetrwOptionRestore("w:")
6478
6479  " set display to netrw display settings
6480"  call Decho("set display to netrw display settings (noma nomod etc)")
6481  exe "setl ".g:netrw_bufsettings
6482  if exists("s:treecurpos")
6483
6484   call netrw#NetrwRestorePosn(s:treecurpos)
6485   unlet s:treecurpos
6486  endif
6487
6488"  call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
6489endfun
6490
6491" ---------------------------------------------------------------------
6492" s:SetupNetrwStatusLine: {{{2
6493fun! s:SetupNetrwStatusLine(statline)
6494"  call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
6495
6496  if !exists("s:netrw_setup_statline")
6497   let s:netrw_setup_statline= 1
6498"   call Decho("do first-time status line setup")
6499
6500   if !exists("s:netrw_users_stl")
6501    let s:netrw_users_stl= &stl
6502   endif
6503   if !exists("s:netrw_users_ls")
6504    let s:netrw_users_ls= &laststatus
6505   endif
6506
6507   " set up User9 highlighting as needed
6508   let keepa= @a
6509   redir @a
6510   try
6511    hi User9
6512   catch /^Vim\%((\a\+)\)\=:E411/
6513    if &bg == "dark"
6514     hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
6515    else
6516     hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
6517    endif
6518   endtry
6519   redir END
6520   let @a= keepa
6521  endif
6522
6523  " set up status line (may use User9 highlighting)
6524  " insure that windows have a statusline
6525  " make sure statusline is displayed
6526  let &stl=a:statline
6527  setlocal laststatus=2
6528"  call Decho("stl=".&stl)
6529  redraw
6530
6531"  call Dret("SetupNetrwStatusLine : stl=".&stl)
6532endfun
6533
6534" ---------------------------------------------------------------------
6535"  Remote Directory Browsing Support:    {{{1
6536" ===========================================
6537
6538" ---------------------------------------------------------------------
6539" s:NetrwRemoteListing: {{{2
6540fun! s:NetrwRemoteListing()
6541"  call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">)")
6542
6543  call s:RemotePathAnalysis(b:netrw_curdir)
6544
6545  " sanity check:
6546  if exists("b:netrw_method") && b:netrw_method =~ '[235]'
6547"   call Decho("b:netrw_method=".b:netrw_method)
6548   if !executable("ftp")
6549    if !exists("g:netrw_quiet")
6550     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
6551    endif
6552    call s:NetrwOptionRestore("w:")
6553"    call Dret("s:NetrwRemoteListing")
6554    return
6555   endif
6556
6557  elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
6558   if !exists("g:netrw_quiet")
6559    if g:netrw_list_cmd == ""
6560     call netrw#ErrorMsg(s:ERROR,g:netrw_ssh_cmd." is not executable on your system",47)
6561    else
6562     call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
6563    endif
6564   endif
6565
6566   call s:NetrwOptionRestore("w:")
6567"   call Dret("s:NetrwRemoteListing")
6568   return
6569  endif  " (remote handling sanity check)
6570
6571  if exists("b:netrw_method")
6572"   call Decho("setting w:netrw_method<".b:netrw_method.">")
6573   let w:netrw_method= b:netrw_method
6574  endif
6575
6576  if s:method == "ftp"
6577   " use ftp to get remote file listing
6578"   call Decho("use ftp to get remote file listing")
6579   let s:method  = "ftp"
6580   let listcmd = g:netrw_ftp_list_cmd
6581   if g:netrw_sort_by =~ '^t'
6582    let listcmd= g:netrw_ftp_timelist_cmd
6583   elseif g:netrw_sort_by =~ '^s'
6584    let listcmd= g:netrw_ftp_sizelist_cmd
6585   endif
6586"   call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)")
6587   call s:NetrwRemoteFtpCmd(s:path,listcmd)
6588"   exe "sil! keepalt keepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."))'
6589
6590   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST
6591    " shorten the listing
6592"    call Decho("generate short listing")
6593    exe "sil! keepalt keepj ".w:netrw_bannercnt
6594
6595    " cleanup
6596    if g:netrw_ftp_browse_reject != ""
6597     exe "sil! keepalt keepj g/".g:netrw_ftp_browse_reject."/keepj d"
6598     call histdel("/",-1)
6599    endif
6600    sil! keepj %s/\r$//e
6601    call histdel("/",-1)
6602
6603    " if there's no ../ listed, then put ./ and ../ in
6604    let line1= line(".")
6605    exe "sil! keepj ".w:netrw_bannercnt
6606    let line2= search('^\.\.\/\%(\s\|$\)','cnW')
6607    if line2 == 0
6608"     call Decho("netrw is putting ./ and ../ into listing")
6609     sil! keepj put='../'
6610     sil! keepj put='./'
6611    endif
6612    exe "sil! keepj ".line1
6613    sil! keepj norm! 0
6614
6615"    call Decho("line1=".line1." line2=".line2." line(.)=".line("."))
6616    if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
6617"     call Decho("M$ ftp cleanup")
6618     exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
6619     call histdel("/",-1)
6620    else " normal ftp cleanup
6621"     call Decho("normal ftp cleanup")
6622     exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
6623     exe "sil! keepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
6624     exe "sil! keepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
6625     call histdel("/",-1)
6626     call histdel("/",-1)
6627     call histdel("/",-1)
6628    endif
6629   endif
6630
6631  else
6632   " use ssh to get remote file listing {{{3
6633"   call Decho("use ssh to get remote file listing: s:path<".s:path.">")
6634   let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
6635"   call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)")
6636   if g:netrw_scp_cmd =~ '^pscp'
6637"    call Decho("1: exe silent r! ".shellescape(listcmd.s:path, 1))
6638    exe "sil! keepj r! ".listcmd.shellescape(s:path, 1)
6639    " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
6640    sil! keepj g/^Listing directory/keepj d
6641    sil! keepj g/^d[-rwx][-rwx][-rwx]/keepj s+$+/+e
6642    sil! keepj g/^l[-rwx][-rwx][-rwx]/keepj s+$+@+e
6643    call histdel("/",-1)
6644    call histdel("/",-1)
6645    call histdel("/",-1)
6646    if g:netrw_liststyle != s:LONGLIST
6647     sil! keepj g/^[dlsp-][-rwx][-rwx][-rwx]/keepj s/^.*\s\(\S\+\)$/\1/e
6648     call histdel("/",-1)
6649    endif
6650   else
6651    if s:path == ""
6652"     call Decho("2: exe silent r! ".listcmd)
6653     exe "sil! keepalt r! ".listcmd
6654    else
6655"     call Decho("3: exe silent r! ".listcmd.' '.shellescape(s:path,1))
6656     exe "sil! keepalt r! ".listcmd.' '.shellescape(s:path,1)
6657"     call Decho("listcmd<".listcmd."> path<".s:path.">")
6658    endif
6659   endif
6660
6661   " cleanup
6662   if g:netrw_ftp_browse_reject != ""
6663"    call Decho("(cleanup) exe silent! g/".g:netrw_ssh_browse_reject."/keepjumps d")
6664    exe "sil! g/".g:netrw_ssh_browse_reject."/keepj d"
6665    call histdel("/",-1)
6666   endif
6667  endif
6668
6669  if w:netrw_liststyle == s:LONGLIST
6670   " do a long listing; these substitutions need to be done prior to sorting {{{3
6671"   call Decho("fix long listing:")
6672
6673   if s:method == "ftp"
6674    " cleanup
6675    exe "sil! keepj ".w:netrw_bannercnt
6676    while getline('.') =~ g:netrw_ftp_browse_reject
6677     sil! keepj d
6678    endwhile
6679    " if there's no ../ listed, then put ./ and ../ in
6680    let line1= line(".")
6681    sil! keepj 1
6682    sil! keepj call search('^\.\.\/\%(\s\|$\)','W')
6683    let line2= line(".")
6684    if line2 == 0
6685     exe 'sil! keepj '.w:netrw_bannercnt."put='./'"
6686     if b:netrw_curdir != '/'
6687      exe 'sil! keepj '.w:netrw_bannercnt."put='../'"
6688     endif
6689    endif
6690    exe "sil! keepj ".line1
6691    sil! keepj norm! 0
6692   endif
6693
6694   if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
6695"    call Decho("M$ ftp site listing cleanup")
6696    exe 'sil! keepj '.w:netrw_bannercnt.',$s/^\(\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+\)\(\w.*\)$/\2\t\1/'
6697   elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
6698"    call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"))
6699    exe 'sil keepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
6700    exe 'sil keepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2\t\1/e'
6701    exe 'sil keepj '.w:netrw_bannercnt
6702    call histdel("/",-1)
6703    call histdel("/",-1)
6704    call histdel("/",-1)
6705   endif
6706  endif
6707
6708"  if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
6709"   exe "keepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."))'
6710"  endif " Decho
6711"  call Dret("s:NetrwRemoteListing")
6712endfun
6713
6714" ---------------------------------------------------------------------
6715" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
6716fun! s:NetrwRemoteRm(usrhost,path) range
6717"  call Dfunc("s:NetrwRemoteRm(usrhost<".a:usrhost."> path<".a:path.">) virtcol=".virtcol("."))
6718"  call Decho("firstline=".a:firstline." lastline=".a:lastline)
6719  let svpos= netrw#NetrwSavePosn()
6720
6721  let all= 0
6722  if exists("s:netrwmarkfilelist_{bufnr('%')}")
6723   " remove all marked files
6724"   call Decho("remove all marked files with bufnr#".bufnr("%"))
6725   for fname in s:netrwmarkfilelist_{bufnr("%")}
6726    let ok= s:NetrwRemoteRmFile(a:path,fname,all)
6727    if ok =~ 'q\%[uit]'
6728     break
6729    elseif ok =~ 'a\%[ll]'
6730     let all= 1
6731    endif
6732   endfor
6733   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
6734
6735  else
6736   " remove files specified by range
6737"   call Decho("remove files specified by range")
6738
6739   " preparation for removing multiple files/directories
6740   let ctr= a:firstline
6741
6742   " remove multiple files and directories
6743   while ctr <= a:lastline
6744    exe ctr
6745    let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
6746    if ok =~ 'q\%[uit]'
6747     break
6748    elseif ok =~ 'a\%[ll]'
6749     let all= 1
6750    endif
6751    let ctr= ctr + 1
6752   endwhile
6753  endif
6754
6755  " refresh the (remote) directory listing
6756"  call Decho("refresh remote directory listing")
6757  call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
6758  call netrw#NetrwRestorePosn(svpos)
6759
6760"  call Dret("s:NetrwRemoteRm")
6761endfun
6762
6763" ---------------------------------------------------------------------
6764" s:NetrwRemoteRmFile: {{{2
6765fun! s:NetrwRemoteRmFile(path,rmfile,all)
6766"  call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
6767
6768  let all= a:all
6769  let ok = ""
6770
6771  if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
6772   " attempt to remove file
6773"    call Decho("attempt to remove file (all=".all.")")
6774   if !all
6775    echohl Statement
6776"    call Decho("case all=0:")
6777    call inputsave()
6778    let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
6779    call inputrestore()
6780    echohl NONE
6781    if ok == ""
6782     let ok="no"
6783    endif
6784    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
6785    if ok =~ 'a\%[ll]'
6786     let all= 1
6787    endif
6788   endif
6789
6790   if all || ok =~ 'y\%[es]' || ok == ""
6791"    call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""))
6792    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
6793"     call Decho("case ftp:")
6794     let path= a:path
6795     if path =~ '^\a\+://'
6796      let path= substitute(path,'^\a\+://[^/]\+/','','')
6797     endif
6798     sil! keepj .,$d
6799     call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
6800    else
6801"     call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">")
6802     let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
6803"     call Decho("netrw_rm_cmd<".netrw_rm_cmd.">")
6804     if !exists("b:netrw_curdir")
6805      call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
6806      let ok="q"
6807     else
6808      let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
6809"      call Decho("netrw_rm_cmd<".netrw_rm_cmd.">")
6810"      call Decho("remotedir<".remotedir.">")
6811"      call Decho("rmfile<".a:rmfile.">")
6812      if remotedir != ""
6813       let netrw_rm_cmd= netrw_rm_cmd." ".shellescape(fnameescape(remotedir.a:rmfile))
6814      else
6815       let netrw_rm_cmd= netrw_rm_cmd." ".shellescape(fnameescape(a:rmfile))
6816      endif
6817"      call Decho("call system(".netrw_rm_cmd.")")
6818      let ret= system(netrw_rm_cmd)
6819      if ret != 0
6820       call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
6821      endif
6822"      call Decho("returned=".ret." errcode=".v:shell_error)
6823     endif
6824    endif
6825   elseif ok =~ 'q\%[uit]'
6826"    call Decho("ok==".ok)
6827    break
6828   endif
6829
6830  else
6831   " attempt to remove directory
6832"    call Decho("attempt to remove directory")
6833   if !all
6834    call inputsave()
6835    let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
6836    call inputrestore()
6837    if ok == ""
6838     let ok="no"
6839    endif
6840    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
6841    if ok =~ 'a\%[ll]'
6842     let all= 1
6843    endif
6844   endif
6845
6846   if all || ok =~ 'y\%[es]' || ok == ""
6847    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
6848     call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
6849    else
6850     let rmfile          = substitute(a:path.a:rmfile,'/$','','')
6851     let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.shellescape(netrw#WinPath(rmfile))
6852"      call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")")
6853     let ret= system(netrw_rmdir_cmd)
6854"      call Decho("returned=".ret." errcode=".v:shell_error)
6855
6856     if v:shell_error != 0
6857"      call Decho("v:shell_error not 0")
6858      let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.shellescape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
6859"      call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")")
6860      let ret= system(netrw_rmf_cmd)
6861"      call Decho("returned=".ret." errcode=".v:shell_error)
6862
6863      if v:shell_error != 0 && !exists("g:netrw_quiet")
6864      	call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
6865      endif
6866     endif
6867    endif
6868
6869   elseif ok =~ 'q\%[uit]'
6870    break
6871   endif
6872  endif
6873
6874"  call Dret("s:NetrwRemoteRmFile ".ok)
6875  return ok
6876endfun
6877
6878" ---------------------------------------------------------------------
6879" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
6880"  This function assumes that a long listing will be received.  Size, time,
6881"  and reverse sorts will be requested of the server but not otherwise
6882"  enforced here.
6883fun! s:NetrwRemoteFtpCmd(path,listcmd)
6884"  call Dfunc("NetrwRemoteFtpCmd(path<".a:path."> listcmd<".a:listcmd.">) netrw_method=".w:netrw_method)
6885"  call Decho("line($)=".line("$")." bannercnt=".w:netrw_bannercnt)
6886
6887  " because WinXX ftp uses unix style input
6888  let ffkeep= &ff
6889  setlocal ma ff=unix noro
6890"  call Decho("setlocal ma ff=unix noro")
6891
6892  " clear off any older non-banner lines
6893  " note that w:netrw_bannercnt indexes the line after the banner
6894"  call Decho('exe silent! keepjumps '.w:netrw_bannercnt.",$d  (clear off old non-banner lines)")
6895  exe "silent! keepjumps ".w:netrw_bannercnt.",$d"
6896
6897  ".........................................
6898  if w:netrw_method == 2 || w:netrw_method == 5
6899   " ftp + <.netrc>:  Method #2
6900   if a:path != ""
6901    keepj put ='cd \"'.a:path.'\"'
6902   endif
6903   if exists("g:netrw_ftpextracmd")
6904    keepj put =g:netrw_ftpextracmd
6905"    call Decho("filter input: ".getline('.'))
6906   endif
6907   call setline(line("$")+1,a:listcmd)
6908"   exe "keepjumps ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."))'
6909   if exists("g:netrw_port") && g:netrw_port != ""
6910"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1))
6911    exe s:netrw_silentxfer." keepjumps ".w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)." ".shellescape(g:netrw_port,1)
6912   else
6913"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1))
6914    exe s:netrw_silentxfer." keepjumps ".w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i ".shellescape(g:netrw_machine,1)
6915   endif
6916
6917   ".........................................
6918  elseif w:netrw_method == 3
6919   " ftp + machine,id,passwd,filename:  Method #3
6920    setlocal ff=unix
6921    if exists("g:netrw_port") && g:netrw_port != ""
6922     keepj put ='open '.g:netrw_machine.' '.g:netrw_port
6923    else
6924     keepj put ='open '.g:netrw_machine
6925    endif
6926
6927    if exists("g:netrw_ftp") && g:netrw_ftp == 1
6928     keepj put =g:netrw_uid
6929     keepj put ='\"'.s:netrw_passwd.'\"'
6930    else
6931     keepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
6932    endif
6933
6934   if a:path != ""
6935    keepj put ='cd \"'.a:path.'\"'
6936   endif
6937   if exists("g:netrw_ftpextracmd")
6938    keepj put =g:netrw_ftpextracmd
6939"    call Decho("filter input: ".getline('.'))
6940   endif
6941   keepj call setline(line("$")+1,a:listcmd)
6942
6943    " perform ftp:
6944    " -i       : turns off interactive prompting from ftp
6945    " -n  unix : DON'T use <.netrc>, even though it exists
6946    " -n  win32: quit being obnoxious about password
6947"    exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."))'
6948"    call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i -n")
6949    exe s:netrw_silentxfer.w:netrw_bannercnt.",$!".g:netrw_ftp_cmd." -i -n"
6950
6951   ".........................................
6952  else
6953   call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",23)
6954  endif
6955
6956  " cleanup for Windows
6957  if has("win32") || has("win95") || has("win64") || has("win16")
6958   sil! keepj %s/\r$//e
6959   call histdel("/",-1)
6960  endif
6961  if a:listcmd == "dir"
6962   " infer directory/link based on the file permission string
6963   sil! keepj g/d\%([-r][-w][-x]\)\{3}/keepj s@$@/@
6964   sil! keepj g/l\%([-r][-w][-x]\)\{3}/keepj s/$/@/
6965   call histdel("/",-1)
6966   call histdel("/",-1)
6967   if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || w:netrw_liststyle == s:TREELIST
6968    exe "sil! keepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
6969    call histdel("/",-1)
6970   endif
6971  endif
6972
6973  " ftp's listing doesn't seem to include ./ or ../
6974  if !search('^\.\/$\|\s\.\/$','wn')
6975   exe 'keepj '.w:netrw_bannercnt
6976   keepj put ='./'
6977  endif
6978  if !search('^\.\.\/$\|\s\.\.\/$','wn')
6979   exe 'keepj '.w:netrw_bannercnt
6980   keepj put ='../'
6981  endif
6982
6983  " restore settings
6984  let &ff= ffkeep
6985"  call Dret("NetrwRemoteFtpCmd")
6986endfun
6987
6988" ---------------------------------------------------------------------
6989" s:NetrwRemoteRename: rename a remote file or directory {{{2
6990fun! s:NetrwRemoteRename(usrhost,path) range
6991"  call Dfunc("NetrwRemoteRename(usrhost<".a:usrhost."> path<".a:path.">)")
6992
6993  " preparation for removing multiple files/directories
6994  let svpos      = netrw#NetrwSavePosn()
6995  let ctr        = a:firstline
6996  let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
6997
6998  " rename files given by the markfilelist
6999  if exists("s:netrwmarkfilelist_{bufnr('%')}")
7000   for oldname in s:netrwmarkfilelist_{bufnr("%")}
7001"    call Decho("oldname<".oldname.">")
7002    if exists("subfrom")
7003     let newname= substitute(oldname,subfrom,subto,'')
7004"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">")
7005    else
7006     call inputsave()
7007     let newname= input("Moving ".oldname." to : ",oldname)
7008     call inputrestore()
7009     if newname =~ '^s/'
7010      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
7011      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
7012      let newname = substitute(oldname,subfrom,subto,'')
7013"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">")
7014     endif
7015    endif
7016   
7017    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
7018     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
7019    else
7020     let oldname= shellescape(a:path.oldname)
7021     let newname= shellescape(a:path.newname)
7022"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")")
7023     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
7024    endif
7025
7026   endfor
7027   call s:NetrwUnMarkFile(1)
7028
7029  else
7030
7031  " attempt to rename files/directories
7032   while ctr <= a:lastline
7033    exe "keepj ".ctr
7034
7035    let oldname= s:NetrwGetWord()
7036"   call Decho("oldname<".oldname.">")
7037
7038    call inputsave()
7039    let newname= input("Moving ".oldname." to : ",oldname)
7040    call inputrestore()
7041
7042    if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
7043     call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
7044    else
7045     let oldname= shellescape(a:path.oldname)
7046     let newname= shellescape(a:path.newname)
7047"     call Decho("system(netrw#WinPath(".rename_cmd.") ".oldname.' '.newname.")")
7048     let ret    = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
7049    endif
7050
7051    let ctr= ctr + 1
7052   endwhile
7053  endif
7054
7055  " refresh the directory
7056  call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./'))
7057  call netrw#NetrwRestorePosn(svpos)
7058
7059"  call Dret("NetrwRemoteRename")
7060endfun
7061
7062" ---------------------------------------------------------------------
7063"  Local Directory Browsing Support:    {{{1
7064" ==========================================
7065
7066" ---------------------------------------------------------------------
7067" netrw#LocalBrowseCheck: {{{2
7068fun! netrw#LocalBrowseCheck(dirname)
7069  " unfortunate interaction -- split window debugging can't be
7070  " used here, must use D-echoRemOn or D-echoTabOn -- the BufEnter
7071  " event triggers another call to LocalBrowseCheck() when attempts
7072  " to write to the DBG buffer are made.
7073  " The &ft == "netrw" test was installed because the BufEnter event
7074  " would hit when re-entering netrw windows, creating unexpected
7075  " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
7076"  call Decho("netrw#LocalBrowseCheck: isdir<".a:dirname.">=".isdirectory(a:dirname).((exists("s:treeforceredraw")? " treeforceredraw" : "")))
7077  if isdirectory(a:dirname)
7078"   call Decho(" ft<".&ft."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : " doesn't exist")."> dirname<".a:dirname.">"." line($)=".line("$"))
7079   if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname)
7080    silent! call s:NetrwBrowse(1,a:dirname)
7081   elseif &ft == "netrw" && line("$") == 1
7082    silent! call s:NetrwBrowse(1,a:dirname)
7083   elseif exists("s:treeforceredraw")
7084    unlet s:treeforceredraw
7085    silent! call s:NetrwBrowse(1,a:dirname)
7086   endif
7087  endif
7088  " not a directory, ignore it
7089endfun
7090
7091" ---------------------------------------------------------------------
7092"  s:LocalListing: does the job of "ls" for local directories {{{2
7093fun! s:LocalListing()
7094"  call Dfunc("s:LocalListing()")
7095"  call Decho("&ma=".&ma)
7096"  call Decho("&mod=".&mod)
7097"  call Decho("&ro=".&ro)
7098"  call Decho("bufname(%)<".bufname("%").">")
7099
7100"  if exists("b:netrw_curdir") |call Decho('b:netrw_curdir<'.b:netrw_curdir.">")  |else|call Decho("b:netrw_curdir doesn't exist") |endif
7101"  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")|endif
7102
7103  " get the list of files contained in the current directory
7104  let dirname    = escape(b:netrw_curdir,g:netrw_glob_escape)
7105  let dirnamelen = s:Strlen(b:netrw_curdir)
7106  let filelist   = glob(s:ComposePath(dirname,"*"))
7107"  call Decho("glob(dirname<".dirname."/*>)=".filelist)
7108  if filelist != ""
7109   let filelist= filelist."\n"
7110  endif
7111  let filelist= filelist.glob(s:ComposePath(dirname,".*"))
7112"  call Decho("glob(dirname<".dirname."/.*>)=".filelist)
7113
7114  " Coding choice: either   elide   ./ if present
7115  "                or       include ./ if not present
7116  if filelist =~ '[\\/]\.[\\/]\=\(\n\|$\)'
7117   " elide /path/. from glob() entries if present
7118"   call Decho("elide /path/. from glob entries if present")
7119   let filelist = substitute(filelist,'\n','\t','g')
7120   let filelist = substitute(filelist,'^[^\t]\+[/\\]\.\t','','')
7121   let filelist = substitute(filelist,'[^\t]\+[/\\]\.$','','')
7122   let filelist = substitute(filelist,'\t\zs[^\t]\+[/\\]\.\t','','')
7123   let filelist = substitute(filelist,'\t','\n','g')
7124  endif
7125"  call Decho("filelist<".filelist.">")
7126  if filelist !~ '[\\/]\.\.[\\/]\=\(\n\|$\)'
7127    " include ../ in the glob() entry if its missing
7128"   call Decho("forcibly tacking on ..")
7129   let filelist= filelist."\n".s:ComposePath(b:netrw_curdir,"../")
7130"   call Decho("filelist<".filelist.">")
7131  endif
7132  if b:netrw_curdir == '/'
7133   " remove .. from filelist when current directory is root directory
7134"   call Decho("remove .. from filelist")
7135   let filelist= substitute(filelist,'/\.\.\n','','')
7136  endif
7137  " remove multiple contiguous newlines
7138  let filelist= substitute(filelist,'\n\{2,}','\n','ge')
7139  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7140   " change all \s to /s
7141"   call Decho('change all \s to /s')
7142   let filelist= substitute(filelist,'\','/','g')
7143  else
7144   " escape all \s to \\
7145"   call Decho('escape all \s to \\')
7146   let filelist= substitute(filelist,'\','\\','g')
7147  endif
7148
7149"  call Decho("(before while) dirname<".dirname.">")
7150"  call Decho("(before while) dirnamelen<".dirnamelen.">")
7151"  call Decho("(before while) filelist<".filelist.">")
7152
7153  while filelist != ""
7154   if filelist =~ '\n'
7155    let filename = substitute(filelist,'\n.*$','','e')
7156    let filelist = substitute(filelist,'^.\{-}\n\(.*\)$','\1','e')
7157   else
7158    let filename = filelist
7159    let filelist = ""
7160   endif
7161"   call Decho(" ")
7162"   call Decho("(while) filelist<".filelist.">")
7163"   call Decho("(while) filename<".filename.">")
7164
7165   if getftype(filename) == "link"
7166    " indicate a symbolic link
7167"    call Decho("indicate <".filename."> is a symbolic link with trailing @")
7168    let pfile= filename."@"
7169
7170   elseif getftype(filename) == "socket"
7171    " indicate a socket
7172"    call Decho("indicate <".filename."> is a socket with trailing =")
7173    let pfile= filename."="
7174
7175   elseif getftype(filename) == "fifo"
7176    " indicate a fifo
7177"    call Decho("indicate <".filename."> is a fifo with trailing |")
7178    let pfile= filename."|"
7179
7180   elseif isdirectory(filename)
7181    " indicate a directory
7182"    call Decho("indicate <".filename."> is a directory with trailing /")
7183    let pfile= filename."/"
7184
7185   elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(filename)
7186    if (has("win32") || has("win95") || has("win64") || has("win16"))
7187     if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
7188      " indicate an executable
7189"      call Decho("indicate <".filename."> is executable with trailing *")
7190      let pfile= filename."*"
7191     else
7192      " normal file
7193      let pfile= filename
7194     endif
7195    elseif executable(filename)
7196     " indicate an executable
7197"     call Decho("indicate <".filename."> is executable with trailing *")
7198     let pfile= filename."*"
7199    else
7200     " normal file
7201     let pfile= filename
7202    endif
7203
7204   else
7205    " normal file
7206    let pfile= filename
7207   endif
7208"   call Decho("pfile<".pfile."> (after *@/ appending)")
7209
7210   if pfile =~ '//$'
7211    let pfile= substitute(pfile,'//$','/','e')
7212"    call Decho("change // to /: pfile<".pfile.">")
7213   endif
7214   let pfile= strpart(pfile,dirnamelen)
7215   let pfile= substitute(pfile,'^[/\\]','','e')
7216"   call Decho("filename<".filename.">")
7217"   call Decho("pfile   <".pfile.">")
7218
7219   if w:netrw_liststyle == s:LONGLIST
7220    let sz   = getfsize(filename)
7221    let fsz  = strpart("               ",1,15-strlen(sz)).sz
7222    let pfile= pfile."\t".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
7223"    call Decho("sz=".sz." fsz=".fsz)
7224   endif
7225
7226   if     g:netrw_sort_by =~ "^t"
7227    " sort by time (handles time up to 1 quintillion seconds, US)
7228"    call Decho("getftime(".filename.")=".getftime(filename))
7229    let t  = getftime(filename)
7230    let ft = strpart("000000000000000000",1,18-strlen(t)).t
7231"    call Decho("exe keepjumps put ='".ft.'/'.filename."'")
7232    let ftpfile= ft.'/'.pfile
7233    sil! keepj put=ftpfile
7234
7235   elseif g:netrw_sort_by =~ "^s"
7236    " sort by size (handles file sizes up to 1 quintillion bytes, US)
7237"    call Decho("getfsize(".filename.")=".getfsize(filename))
7238    let sz   = getfsize(filename)
7239    let fsz  = strpart("000000000000000000",1,18-strlen(sz)).sz
7240"    call Decho("exe keepjumps put ='".fsz.'/'.filename."'")
7241    let fszpfile= fsz.'/'.pfile
7242    sil! keepj put =fszpfile
7243
7244   else
7245    " sort by name
7246"    call Decho("exe keepjumps put ='".pfile."'")
7247    sil! keepj put=pfile
7248   endif
7249  endwhile
7250
7251  " cleanup any windows mess at end-of-line
7252  sil! keepj g/^$/d
7253  sil! keepj %s/\r$//e
7254  call histdel("/",-1)
7255  exe "setlocal ts=".g:netrw_maxfilenamelen
7256"  call Decho("setlocal ts=".g:netrw_maxfilenamelen)
7257
7258"  call Dret("s:LocalListing")
7259endfun
7260
7261" ---------------------------------------------------------------------
7262" s:LocalBrowseShellCmdRefresh: this function is called after a user has {{{2
7263" performed any shell command.  The idea is to cause all local-browsing
7264" buffers to be refreshed after a user has executed some shell command,
7265" on the chance that s/he removed/created a file/directory with it.
7266fun! s:LocalBrowseShellCmdRefresh()
7267"  call Dfunc("LocalBrowseShellCmdRefresh() browselist=".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "empty")." ".tabpagenr("$")." tabs")
7268  " determine which buffers currently reside in a tab
7269  if !exists("s:netrw_browselist")
7270"   call Dret("LocalBrowseShellCmdRefresh : browselist is empty")
7271   return
7272  endif
7273  if !exists("w:netrw_bannercnt")
7274"   call Dret("LocalBrowseShellCmdRefresh : don't refresh when focus not on netrw window")
7275   return
7276  endif
7277  if exists("s:locbrowseshellcmd")
7278   if s:locbrowseshellcmd
7279    let s:locbrowseshellcmd= 0
7280"    call Dret("LocalBrowseShellCmdRefresh : NetrwBrowse itself caused the refresh")
7281    return
7282   endif
7283   let s:locbrowseshellcmd= 0
7284  endif
7285  let itab       = 1
7286  let buftablist = []
7287  while itab <= tabpagenr("$")
7288   let buftablist = buftablist + tabpagebuflist()
7289   let itab       = itab + 1
7290   tabn
7291  endwhile
7292"  call Decho("buftablist".string(buftablist))
7293"  call Decho("s:netrw_browselist<".(exists("s:netrw_browselist")? string(s:netrw_browselist) : "").">")
7294  "  GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
7295  "   | refresh any netrw window
7296  "   | wipe out any non-displaying netrw buffer
7297  let curwin = winnr()
7298  let ibl    = 0
7299  for ibuf in s:netrw_browselist
7300"   call Decho("bufwinnr(".ibuf.") index(buftablist,".ibuf.")=".index(buftablist,ibuf))
7301   if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
7302    " wipe out any non-displaying netrw buffer
7303"    call Decho("wiping  buf#".ibuf,"<".bufname(ibuf).">")
7304    exe "sil! bd ".fnameescape(ibuf)
7305    call remove(s:netrw_browselist,ibl)
7306"    call Decho("browselist=".string(s:netrw_browselist))
7307    continue
7308   elseif index(tabpagebuflist(),ibuf) != -1
7309    " refresh any netrw buffer
7310"    call Decho("refresh buf#".ibuf.'-> win#'.bufwinnr(ibuf))
7311    exe bufwinnr(ibuf)."wincmd w"
7312    call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
7313   endif
7314   let ibl= ibl + 1
7315  endfor
7316  exe curwin."wincmd w"
7317
7318"  call Dret("LocalBrowseShellCmdRefresh")
7319endfun
7320
7321" ---------------------------------------------------------------------
7322" s:NetrwLocalRm: {{{2
7323fun! s:NetrwLocalRm(path) range
7324"  call Dfunc("s:NetrwLocalRm(path<".a:path.">)")
7325"  call Decho("firstline=".a:firstline." lastline=".a:lastline)
7326
7327  " preparation for removing multiple files/directories
7328  let ret   = 0
7329  let all   = 0
7330  let svpos = netrw#NetrwSavePosn()
7331
7332  if exists("s:netrwmarkfilelist_{bufnr('%')}")
7333   " remove all marked files
7334"   call Decho("remove all marked files")
7335   for fname in s:netrwmarkfilelist_{bufnr("%")}
7336    let ok= s:NetrwLocalRmFile(a:path,fname,all)
7337    if ok =~ 'q\%[uit]' || ok == "no"
7338     break
7339    elseif ok =~ 'a\%[ll]'
7340     let all= 1
7341    endif
7342   endfor
7343   call s:NetrwUnMarkFile(1)
7344
7345  else
7346  " remove (multiple) files and directories
7347"   call Decho("remove files in range [".a:firstline.",".a:lastline."]")
7348
7349   let ctr = a:firstline
7350   while ctr <= a:lastline
7351    exe "keepj ".ctr
7352
7353    " sanity checks
7354    if line(".") < w:netrw_bannercnt
7355     let ctr= ctr + 1
7356     continue
7357    endif
7358    let curword= s:NetrwGetWord()
7359    if curword == "./" || curword == "../"
7360     let ctr= ctr + 1
7361     continue
7362    endif
7363    let ok= s:NetrwLocalRmFile(a:path,curword,all)
7364    if ok =~ 'q\%[uit]' || ok == "no"
7365     break
7366    elseif ok =~ 'a\%[ll]'
7367     let all= 1
7368    endif
7369    let ctr= ctr + 1
7370   endwhile
7371  endif
7372
7373  " refresh the directory
7374"  call Decho("bufname<".bufname("%").">")
7375  if bufname("%") != "NetrwMessage"
7376   call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
7377   call netrw#NetrwRestorePosn(svpos)
7378  endif
7379
7380"  call Dret("s:NetrwLocalRm")
7381endfun
7382
7383" ---------------------------------------------------------------------
7384" s:NetrwLocalRmFile: remove file fname given the path {{{2
7385"                     Give confirmation prompt unless all==1
7386fun! s:NetrwLocalRmFile(path,fname,all)
7387"  call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
7388  
7389  let all= a:all
7390  let ok = ""
7391  keepj norm! 0
7392  let rmfile= s:ComposePath(a:path,a:fname)
7393"  call Decho("rmfile<".rmfile.">")
7394
7395  if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
7396   " attempt to remove file
7397"   call Decho("attempt to remove file<".rmfile.">")
7398   if !all
7399    echohl Statement
7400    call inputsave()
7401    let ok= input("Confirm deletion of file<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
7402    call inputrestore()
7403    echohl NONE
7404    if ok == ""
7405     let ok="no"
7406    endif
7407"    call Decho("response: ok<".ok.">")
7408    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
7409"    call Decho("response: ok<".ok."> (after sub)")
7410    if ok =~ 'a\%[ll]'
7411     let all= 1
7412    endif
7413   endif
7414
7415   if all || ok =~ 'y\%[es]' || ok == ""
7416    let ret= s:NetrwDelete(rmfile)
7417"    call Decho("errcode=".v:shell_error." ret=".ret)
7418   endif
7419
7420  else
7421   " attempt to remove directory
7422   if !all
7423    echohl Statement
7424    call inputsave()
7425    let ok= input("Confirm deletion of directory<".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
7426    call inputrestore()
7427    let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
7428    if ok == ""
7429     let ok="no"
7430    endif
7431    if ok =~ 'a\%[ll]'
7432     let all= 1
7433    endif
7434   endif
7435   let rmfile= substitute(rmfile,'[\/]$','','e')
7436
7437   if all || ok =~ 'y\%[es]' || ok == ""
7438"    call Decho("1st attempt: system(netrw#WinPath(".g:netrw_local_rmdir.') '.shellescape(rmfile).')')
7439    call system(netrw#WinPath(g:netrw_local_rmdir).' '.shellescape(rmfile))
7440"    call Decho("v:shell_error=".v:shell_error)
7441
7442    if v:shell_error != 0
7443"     call Decho("2nd attempt to remove directory<".rmfile.">")
7444     let errcode= s:NetrwDelete(rmfile)
7445"     call Decho("errcode=".errcode)
7446
7447     if errcode != 0
7448      if has("unix")
7449"       call Decho("3rd attempt to remove directory<".rmfile.">")
7450       call system("rm ".shellescape(rmfile))
7451       if v:shell_error != 0 && !exists("g:netrw_quiet")
7452        call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",34)
7453	let ok="no"
7454       endif
7455      elseif !exists("g:netrw_quiet")
7456       call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",35)
7457       let ok="no"
7458      endif
7459     endif
7460    endif
7461   endif
7462  endif
7463
7464"  call Dret("s:NetrwLocalRmFile ".ok)
7465  return ok
7466endfun
7467
7468" ---------------------------------------------------------------------
7469" s:NetrwLocalRename: rename a remote file or directory {{{2
7470fun! s:NetrwLocalRename(path) range
7471"  call Dfunc("NetrwLocalRename(path<".a:path.">)")
7472
7473  " preparation for removing multiple files/directories
7474  let ctr  = a:firstline
7475  let svpos= netrw#NetrwSavePosn()
7476
7477  " rename files given by the markfilelist
7478  if exists("s:netrwmarkfilelist_{bufnr('%')}")
7479   for oldname in s:netrwmarkfilelist_{bufnr("%")}
7480"    call Decho("oldname<".oldname.">")
7481    if exists("subfrom")
7482     let newname= substitute(oldname,subfrom,subto,'')
7483"     call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">")
7484    else
7485     call inputsave()
7486     let newname= input("Moving ".oldname." to : ",oldname)
7487     call inputrestore()
7488     if newname =~ '^s/'
7489      let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
7490      let subto   = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
7491"      call Decho("subfrom<".subfrom."> subto<".subto."> newname<".newname.">")
7492      let newname = substitute(oldname,subfrom,subto,'')
7493     endif
7494    endif
7495    call rename(oldname,newname)
7496   endfor
7497   call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
7498  
7499  else
7500
7501   " attempt to rename files/directories
7502   while ctr <= a:lastline
7503    exe "keepj ".ctr
7504
7505    " sanity checks
7506    if line(".") < w:netrw_bannercnt
7507     let ctr= ctr + 1
7508     continue
7509    endif
7510    let curword= s:NetrwGetWord()
7511    if curword == "./" || curword == "../"
7512     let ctr= ctr + 1
7513     continue
7514    endif
7515
7516    keepj norm! 0
7517    let oldname= s:ComposePath(a:path,curword)
7518"   call Decho("oldname<".oldname.">")
7519
7520    call inputsave()
7521    let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
7522    call inputrestore()
7523
7524    call rename(oldname,newname)
7525"   call Decho("renaming <".oldname."> to <".newname.">")
7526
7527    let ctr= ctr + 1
7528   endwhile
7529  endif
7530
7531  " refresh the directory
7532"  call Decho("refresh the directory listing")
7533  call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./'))
7534  call netrw#NetrwRestorePosn(svpos)
7535
7536"  call Dret("NetrwLocalRename")
7537endfun
7538
7539" ---------------------------------------------------------------------
7540" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
7541"
7542"     g:netrw_    Directory Is
7543"     fastbrowse  Local  Remote   
7544"  slow   0         D      D      D=Deleting a buffer implies it will not be re-used (slow)
7545"  med    1         D      H      H=Hiding a buffer implies it may be re-used        (fast)
7546"  fast   2         H      H      
7547"
7548"  Deleting a buffer means that it will be re-loaded when examined, hence "slow".
7549"  Hiding   a buffer means that it will be re-used   when examined, hence "fast".
7550"           (re-using a buffer may not be as accurate)
7551fun! s:LocalFastBrowser()
7552"  call Dfunc("LocalFastBrowser() g:netrw_fastbrowse=".g:netrw_fastbrowse)
7553
7554  " initialize browselist, a list of buffer numbers that the local browser has used
7555  if !exists("s:netrw_browselist")
7556"   call Decho("initialize s:netrw_browselist")
7557   let s:netrw_browselist= []
7558  endif
7559
7560  " append current buffer to fastbrowse list
7561  if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
7562"   call Decho("appendng current buffer to browselist")
7563   call add(s:netrw_browselist,bufnr("%"))
7564"   call Decho("browselist=".string(s:netrw_browselist))
7565  endif
7566
7567  " enable autocmd events to handle refreshing/removing local browser buffers
7568  "    If local browse buffer is currently showing: refresh it
7569  "    If local browse buffer is currently hidden : wipe it
7570  if !exists("s:netrw_browser_shellcmd") && g:netrw_fastbrowse <= 1
7571"   call Decho("setting up local-browser shell command refresh")
7572   let s:netrw_browser_shellcmd= 1
7573   augroup AuNetrwShellCmd
7574    au!
7575    if (has("win32") || has("win95") || has("win64") || has("win16"))
7576"     call Decho("autocmd: ShellCmdPost * call s:LocalBrowseShellCmdRefresh()")
7577     au ShellCmdPost			*	call s:LocalBrowseShellCmdRefresh()
7578    else
7579     au ShellCmdPost,FocusGained	*	call s:LocalBrowseShellCmdRefresh()
7580"     call Decho("autocmd: ShellCmdPost,FocusGained * call s:LocalBrowseShellCmdRefresh()")
7581    endif
7582   augroup END
7583  endif
7584
7585  " user must have changed fastbrowse to its fast setting, so remove
7586  " the associated autocmd events
7587  if g:netrw_fastbrowse > 1 && exists("s:netrw_browser_shellcmd")
7588"   call Decho("remove AuNetrwShellCmd autcmd group")
7589   unlet s:netrw_browser_shellcmd
7590   augroup AuNetrwShellCmd
7591    au!
7592   augroup END
7593   augroup! AuNetrwShellCmd
7594  endif
7595
7596"  call Dret("LocalFastBrowser : browselist<".string(s:netrw_browselist).">")
7597endfun
7598
7599" ---------------------------------------------------------------------
7600" Support Functions: {{{1
7601
7602" ---------------------------------------------------------------------
7603" netrw#ErrorMsg: {{{2
7604"   0=note     = s:NOTE
7605"   1=warning  = s:WARNING
7606"   2=error    = s:ERROR
7607"  Dec 03, 2009 : max errnum currently is 76
7608fun! netrw#ErrorMsg(level,msg,errnum)
7609"  call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
7610
7611  if a:level == 1
7612   let level= "**warning** (netrw) "
7613  elseif a:level == 2
7614   let level= "**error** (netrw) "
7615  else
7616   let level= "**note** (netrw) "
7617  endif
7618"  call Decho("level=".level)
7619
7620  if g:netrw_use_errorwindow
7621   " (default) netrw creates a one-line window to show error/warning
7622   " messages (reliably displayed)
7623
7624   " record current window number for NetrwRestorePosn()'s benefit
7625   let s:winBeforeErr= winnr()
7626"   call Decho("s:winBeforeErr=".s:winBeforeErr)
7627
7628   " getting messages out reliably is just plain difficult!
7629   " This attempt splits the current window, creating a one line window.
7630   if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
7631"    call Decho("write to NetrwMessage buffer")
7632    exe bufwinnr("NetrwMessage")."wincmd w"
7633"    call Decho("setlocal ma noro")
7634    setlocal ma noro
7635    call setline(line("$")+1,level.a:msg)
7636    keepj $
7637   else
7638"    call Decho("create a NetrwMessage buffer window")
7639    bo 1split
7640    call s:NetrwEnew()
7641    call s:NetrwSafeOptions()
7642    setlocal bt=nofile
7643    file NetrwMessage
7644"    call Decho("setlocal ma noro")
7645    setlocal ma noro
7646    call setline(line("$"),level.a:msg)
7647   endif
7648"   call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr())
7649   if &fo !~ '[ta]'
7650    syn clear
7651    syn match netrwMesgNote	"^\*\*note\*\*"
7652    syn match netrwMesgWarning	"^\*\*warning\*\*"
7653    syn match netrwMesgError	"^\*\*error\*\*"
7654    hi link netrwMesgWarning WarningMsg
7655    hi link netrwMesgError   Error
7656   endif
7657   setlocal noma ro bh=wipe
7658
7659  else
7660   " (optional) netrw will show messages using echomsg.  Even if the
7661   " message doesn't appear, at least it'll be recallable via :messages
7662"   redraw!
7663   if a:level == s:WARNING
7664    echohl WarningMsg
7665   elseif a:level == s:ERROR
7666    echohl Error
7667   endif
7668   echomsg level.a:msg
7669"   call Decho("echomsg ***netrw*** ".a:msg)
7670   echohl None
7671  endif
7672
7673"  call Dret("netrw#ErrorMsg")
7674endfun
7675
7676" ---------------------------------------------------------------------
7677" netrw#NetrwRestorePosn: restores the cursor and file position as saved by NetrwSavePosn() {{{2
7678fun! netrw#NetrwRestorePosn(...)
7679"  call Dfunc("netrw#NetrwRestorePosn() a:0=".a:0." winnr=".(exists("w:netrw_winnr")? w:netrw_winnr : -1)." line=".(exists("w:netrw_line")? w:netrw_line : -1)." col=".(exists("w:netrw_col")? w:netrw_col : -1)." hline=".(exists("w:netrw_hline")? w:netrw_hline : -1))
7680  let eikeep= &ei
7681  set ei=all
7682  if expand("%") == "NetrwMessage"
7683   exe s:winBeforeErr."wincmd w"
7684  endif
7685
7686  if a:0 > 0
7687   exe a:1
7688  endif
7689
7690  " restore window
7691  if exists("w:netrw_winnr")
7692"   call Decho("restore window: exe silent! ".w:netrw_winnr."wincmd w")
7693   exe "sil! ".w:netrw_winnr."wincmd w"
7694  endif
7695  if v:shell_error == 0
7696   " as suggested by Bram M: redraw on no error
7697   " allows protocol error messages to remain visible
7698"   redraw!
7699  endif
7700
7701  " restore top-of-screen line
7702  if exists("w:netrw_hline")
7703"   call Decho("restore topofscreen: exe norm! ".w:netrw_hline."G0z")
7704   exe "keepj norm! ".w:netrw_hline."G0z\<CR>"
7705  endif
7706
7707  " restore position
7708  if exists("w:netrw_line") && exists("w:netrw_col")
7709"   call Decho("restore posn: exe norm! ".w:netrw_line."G0".w:netrw_col."|")
7710   exe "keepj norm! ".w:netrw_line."G0".w:netrw_col."\<bar>"
7711  endif
7712
7713  let &ei= eikeep
7714"  call Dret("netrw#NetrwRestorePosn")
7715endfun
7716
7717" ---------------------------------------------------------------------
7718" netrw#NetrwSavePosn: saves position of cursor on screen {{{2
7719fun! netrw#NetrwSavePosn()
7720"  call Dfunc("netrw#NetrwSavePosn()")
7721  " Save current line and column
7722  let w:netrw_winnr= winnr()
7723  let w:netrw_line = line(".")
7724  let w:netrw_col  = virtcol(".")
7725"  call Decho("currently, win#".w:netrw_winnr." line#".w:netrw_line." col#".w:netrw_col)
7726
7727  " Save top-of-screen line
7728  keepj norm! H0
7729  let w:netrw_hline= line(".")
7730
7731  " set up string holding position parameters
7732  let ret          = "let w:netrw_winnr=".w:netrw_winnr."|let w:netrw_line=".w:netrw_line."|let w:netrw_col=".w:netrw_col."|let w:netrw_hline=".w:netrw_hline
7733
7734  call netrw#NetrwRestorePosn()
7735"  call Dret("netrw#NetrwSavePosn : winnr=".w:netrw_winnr." line=".w:netrw_line." col=".w:netrw_col." hline=".w:netrw_hline)
7736  return ret
7737endfun
7738
7739" ------------------------------------------------------------------------
7740"  netrw#RFC2396: converts %xx into characters {{{2
7741fun! netrw#RFC2396(fname)
7742"  call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
7743  let fname = escape(substitute(a:fname,'%\(\x\x\)','\=nr2char("0x".submatch(1))','ge')," \t")
7744"  call Dret("netrw#RFC2396 ".fname)
7745  return fname
7746endfun
7747
7748" ---------------------------------------------------------------------
7749"  s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
7750fun! s:ComposePath(base,subdir)
7751"  call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
7752
7753  if(has("amiga"))
7754"   call Decho("amiga")
7755   let ec = a:base[s:Strlen(a:base)-1]
7756   if ec != '/' && ec != ':'
7757    let ret = a:base . "/" . a:subdir
7758   else
7759    let ret = a:base . a:subdir
7760   endif
7761
7762  elseif a:subdir =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
7763"   call Decho("windows")
7764   let ret= a:subdir
7765
7766  elseif a:base =~ '^\a:[/\\][^/\\]' && (has("win32") || has("win95") || has("win64") || has("win16"))
7767"   call Decho("windows")
7768   if a:base =~ '[/\\]$'
7769    let ret= a:base.a:subdir
7770   else
7771    let ret= a:base."/".a:subdir
7772   endif
7773
7774  elseif a:base =~ '^\a\+://'
7775"   call Decho("remote linux/macos")
7776   let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
7777   let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
7778   if a:subdir == '../'
7779    if curpath =~ '[^/]/[^/]\+/$'
7780     let curpath= substitute(curpath,'[^/]\+/$','','')
7781    else
7782     let curpath=""
7783    endif
7784    let ret= urlbase.curpath
7785   else
7786    let ret= urlbase.curpath.a:subdir
7787   endif
7788"   call Decho("urlbase<".urlbase.">")
7789"   call Decho("curpath<".curpath.">")
7790"   call Decho("ret<".ret.">")
7791
7792  else
7793"   call Decho("local linux/macos")
7794   let ret = substitute(a:base."/".a:subdir,"//","/","g")
7795   if a:base =~ '^//'
7796    " keeping initial '//' for the benefit of network share listing support
7797    let ret= '/'.ret
7798   endif
7799   let ret= simplify(ret)
7800  endif
7801
7802"  call Dret("s:ComposePath ".ret)
7803  return ret
7804endfun
7805
7806" ---------------------------------------------------------------------
7807" s:FileReadable: o/s independent filereadable {{{2
7808fun! s:FileReadable(fname)
7809"  call Dfunc("s:FileReadable(fname<".a:fname.">)")
7810
7811  if g:netrw_cygwin
7812   let ret= filereadable(substitute(a:fname,'/cygdrive/\(.\)','\1:/',''))
7813  else
7814   let ret= filereadable(a:fname)
7815  endif
7816
7817"  call Dret("s:FileReadable ".ret)
7818  return ret
7819endfun
7820
7821" ---------------------------------------------------------------------
7822"  s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
7823"                 Places correct suffix on end of temporary filename,
7824"                 using the suffix provided with fname
7825fun! s:GetTempfile(fname)
7826"  call Dfunc("s:GetTempfile(fname<".a:fname.">)")
7827
7828  if !exists("b:netrw_tmpfile")
7829   " get a brand new temporary filename
7830   let tmpfile= tempname()
7831"   call Decho("tmpfile<".tmpfile."> : from tempname()")
7832
7833   let tmpfile= substitute(tmpfile,'\','/','ge')
7834"   call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /")
7835
7836   " sanity check -- does the temporary file's directory exist?
7837   if !isdirectory(substitute(tmpfile,'[^/]\+$','','e'))
7838"    call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
7839    call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
7840"    call Dret("s:GetTempfile getcwd<".getcwd().">")
7841    return ""
7842   endif
7843
7844   " let netrw#NetSource() know about the tmpfile
7845   let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#NetrwBrowseX()
7846"   call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">")
7847
7848   " o/s dependencies
7849   if g:netrw_cygwin != 0
7850    let tmpfile = substitute(tmpfile,'^\(\a\):','/cygdrive/\1','e')
7851   elseif has("win32") || has("win95") || has("win64") || has("win16")
7852    if !exists("+shellslash") || !&ssl
7853     let tmpfile = substitute(tmpfile,'/','\','g')
7854    endif
7855   else
7856    let tmpfile = tmpfile
7857   endif
7858   let b:netrw_tmpfile= tmpfile
7859"   call Decho("o/s dependent fixed tempname<".tmpfile.">")
7860  else
7861   " re-use temporary filename
7862   let tmpfile= b:netrw_tmpfile
7863"   call Decho("tmpfile<".tmpfile."> re-using")
7864  endif
7865
7866  " use fname's suffix for the temporary file
7867  if a:fname != ""
7868   if a:fname =~ '\.[^./]\+$'
7869"    call Decho("using fname<".a:fname.">'s suffix")
7870    if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
7871     let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
7872    elseif a:fname =~ '.txz$'
7873     let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
7874    else
7875     let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
7876    endif
7877"    call Decho("suffix<".suffix.">")
7878    let tmpfile= substitute(tmpfile,'\.tmp$','','e')
7879"    call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)")
7880    let tmpfile .= suffix
7881"    call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">")
7882    let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
7883   endif
7884  endif
7885
7886"  call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap)
7887"  call Dret("s:GetTempfile <".tmpfile.">")
7888  return tmpfile
7889endfun
7890
7891" ---------------------------------------------------------------------
7892" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
7893"               a correct command for use with a system() call
7894fun! s:MakeSshCmd(sshcmd)
7895"  call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
7896  let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user.s:machine,'')
7897  if exists("g:netrw_port") && g:netrw_port != ""
7898   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
7899  elseif exists("s:port") && s:port != ""
7900   let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
7901  else
7902   let sshcmd= substitute(sshcmd,"USEPORT ",'','')
7903  endif
7904"  call Dret("s:MakeSshCmd <".sshcmd.">")
7905  return sshcmd
7906endfun
7907
7908" ---------------------------------------------------------------------
7909" s:NetrwBMShow: {{{2
7910fun! s:NetrwBMShow()
7911"  call Dfunc("s:NetrwBMShow()")
7912  redir => bmshowraw
7913   menu
7914  redir END
7915  let bmshowlist = split(bmshowraw,'\n')
7916  if bmshowlist != []
7917   let bmshowfuncs= filter(bmshowlist,'v:val =~ "<SNR>\\d\\+_BMShow()"')
7918   if bmshowfuncs != []
7919    let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
7920    if bmshowfunc =~ '^call.*BMShow()'
7921     exe "sil! ".bmshowfunc
7922    endif
7923   endif
7924  endif
7925"  call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
7926endfun
7927
7928" ---------------------------------------------------------------------
7929" s:NetrwCursorline: {{{2
7930fun! s:NetrwCursorline()
7931  if !exists("w:netrw_liststyle")
7932   let w:netrw_liststyle= g:netrw_liststyle
7933  endif
7934"  call Dfunc("s:NetrwCursorline() liststyle=".w:netrw_liststyle." g:netrw_cursorline=".g:netrw_cursorline." s:netrw_usercuc=".s:netrw_usercuc." s:netrw_usercul=".s:netrw_usercul)
7935  "
7936  if w:netrw_liststyle != s:WIDELIST
7937   " thin-long-tree listings
7938   if g:netrw_cursorline == 2
7939    setlocal cursorline
7940    let &l:cursorcolumn= s:netrw_usercuc
7941"    call Decho("setlocal cursorline  (cursorcolumn is ".((s:netrw_usercuc)? "on" : "off").")")
7942   elseif g:netrw_cursorline
7943    setlocal cursorline
7944"    call Decho("setlocal cursorline")
7945   endif
7946
7947  else
7948   " wide listings
7949   if g:netrw_cursorline == 2
7950    setlocal cursorline cursorcolumn
7951"    call Decho("setlocal cursorline cursorcolumn")
7952   elseif g:netrw_cursorline
7953    let &l:cursorline= s:netrw_usercul
7954"    call Decho("cursorline is ".((s:netrw_usercul)? "on" : "off").")")
7955   endif
7956  endif
7957"  call Dret("s:NetrwCursorline : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
7958endfun
7959
7960" ---------------------------------------------------------------------
7961" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
7962fun! s:RestoreCursorline()
7963"  call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
7964  let &l:cursorline   = s:netrw_usercul
7965  let &l:cursorcolumn = s:netrw_usercuc
7966"  call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
7967endfun
7968
7969" ---------------------------------------------------------------------
7970" s:NetrwDelete: Deletes a file. {{{2
7971"           Uses Steve Hall's idea to insure that Windows paths stay
7972"           acceptable.  No effect on Unix paths.
7973"  Examples of use:  let result= s:NetrwDelete(path)
7974fun! s:NetrwDelete(path)
7975"  call Dfunc("s:NetrwDelete(path<".a:path.">)")
7976
7977  let path = netrw#WinPath(a:path)
7978  if !g:netrw_cygwin && (has("win32") || has("win95") || has("win64") || has("win16"))
7979   if exists("+shellslash")
7980    let sskeep= &shellslash
7981    setlocal noshellslash
7982    let result      = delete(path)
7983    let &shellslash = sskeep
7984   else
7985"    call Decho("exe let result= ".a:cmd."('".path."')")
7986    let result= delete(path)
7987   endif
7988  else
7989"   call Decho("let result= delete(".path.")")
7990   let result= delete(path)
7991  endif
7992  if result < 0
7993   call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
7994  endif
7995
7996"  call Dret("s:NetrwDelete ".result)
7997  return result
7998endfun
7999
8000" ---------------------------------------------------------------------
8001" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
8002fun! s:NetrwEnew(...)
8003"  call Dfunc("s:NetrwEnew() a:0=".a:0." bufnr($)=".bufnr("$"))
8004"  call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">")
8005
8006  " grab a function-local-variable copy of buffer variables
8007"  call Decho("make function-local copy of netrw variables")
8008  if exists("b:netrw_bannercnt")      |let netrw_bannercnt       = b:netrw_bannercnt      |endif
8009  if exists("b:netrw_browser_active") |let netrw_browser_active  = b:netrw_browser_active |endif
8010  if exists("b:netrw_cpf")            |let netrw_cpf             = b:netrw_cpf            |endif
8011  if exists("b:netrw_curdir")         |let netrw_curdir          = b:netrw_curdir         |endif
8012  if exists("b:netrw_explore_bufnr")  |let netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
8013  if exists("b:netrw_explore_indx")   |let netrw_explore_indx    = b:netrw_explore_indx   |endif
8014  if exists("b:netrw_explore_line")   |let netrw_explore_line    = b:netrw_explore_line   |endif
8015  if exists("b:netrw_explore_list")   |let netrw_explore_list    = b:netrw_explore_list   |endif
8016  if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
8017  if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
8018  if exists("b:netrw_fname")          |let netrw_fname           = b:netrw_fname          |endif
8019  if exists("b:netrw_lastfile")       |let netrw_lastfile        = b:netrw_lastfile       |endif
8020  if exists("b:netrw_liststyle")      |let netrw_liststyle       = b:netrw_liststyle      |endif
8021  if exists("b:netrw_method")         |let netrw_method          = b:netrw_method         |endif
8022  if exists("b:netrw_option")         |let netrw_option          = b:netrw_option         |endif
8023  if exists("b:netrw_prvdir")         |let netrw_prvdir          = b:netrw_prvdir         |endif
8024
8025  call s:NetrwOptionRestore("w:")
8026"  call Decho("generate a buffer with keepjumps keepalt enew!")
8027  let netrw_keepdiff= &l:diff
8028  keepj keepalt enew!
8029  let &l:diff= netrw_keepdiff
8030"  call Decho("bufnr($)=".bufnr("$"))
8031  call s:NetrwOptionSave("w:")
8032
8033  " copy function-local-variables to buffer variable equivalents
8034"  call Decho("copy function-local variables back to buffer netrw variables")
8035  if exists("netrw_bannercnt")      |let b:netrw_bannercnt       = netrw_bannercnt      |endif
8036  if exists("netrw_browser_active") |let b:netrw_browser_active  = netrw_browser_active |endif
8037  if exists("netrw_cpf")            |let b:netrw_cpf             = netrw_cpf            |endif
8038  if exists("netrw_curdir")         |let b:netrw_curdir          = netrw_curdir         |endif
8039  if exists("netrw_explore_bufnr")  |let b:netrw_explore_bufnr   = netrw_explore_bufnr  |endif
8040  if exists("netrw_explore_indx")   |let b:netrw_explore_indx    = netrw_explore_indx   |endif
8041  if exists("netrw_explore_line")   |let b:netrw_explore_line    = netrw_explore_line   |endif
8042  if exists("netrw_explore_list")   |let b:netrw_explore_list    = netrw_explore_list   |endif
8043  if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
8044  if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
8045  if exists("netrw_fname")          |let b:netrw_fname           = netrw_fname          |endif
8046  if exists("netrw_lastfile")       |let b:netrw_lastfile        = netrw_lastfile       |endif
8047  if exists("netrw_liststyle")      |let b:netrw_liststyle       = netrw_liststyle      |endif
8048  if exists("netrw_method")         |let b:netrw_method          = netrw_method         |endif
8049  if exists("netrw_option")         |let b:netrw_option          = netrw_option         |endif
8050  if exists("netrw_prvdir")         |let b:netrw_prvdir          = netrw_prvdir         |endif
8051
8052  if a:0 > 0
8053   let b:netrw_curdir= a:1
8054   if b:netrw_curdir =~ '/$'
8055    if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
8056     file NetrwTreeListing
8057     set bt=nowrite noswf
8058     nno <silent> <buffer> [	:silent call <SID>TreeListMove('[')<cr>
8059     nno <silent> <buffer> ]	:silent call <SID>TreeListMove(']')<cr>
8060    else
8061     exe "sil! keepalt file ".fnameescape(b:netrw_curdir)
8062    endif
8063   endif
8064  endif
8065
8066"  call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#").">")
8067endfun
8068
8069" ------------------------------------------------------------------------
8070" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
8071" changed sorting, etc.  Also see s:NetrwRestoreWordPosn().
8072fun! s:NetrwSaveWordPosn()
8073"  call Dfunc("NetrwSaveWordPosn()")
8074  let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
8075"  call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
8076endfun
8077
8078" ---------------------------------------------------------------------
8079" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
8080"  changed sorting, etc.  Also see s:NetrwSaveWordPosn().
8081fun! s:NetrwRestoreWordPosn()
8082"  call Dfunc("NetrwRestoreWordPosn()")
8083  silent! call search(s:netrw_saveword,'w')
8084"  call Dret("NetrwRestoreWordPosn")
8085endfun
8086
8087" ---------------------------------------------------------------------
8088" s:RestoreBufVars: {{{2
8089fun! s:RestoreBufVars()
8090"  call Dfunc("s:RestoreBufVars()")
8091
8092  if exists("s:netrw_curdir")        |let b:netrw_curdir         = s:netrw_curdir        |endif
8093  if exists("s:netrw_lastfile")      |let b:netrw_lastfile       = s:netrw_lastfile      |endif
8094  if exists("s:netrw_method")        |let b:netrw_method         = s:netrw_method        |endif
8095  if exists("s:netrw_fname")         |let b:netrw_fname          = s:netrw_fname         |endif
8096  if exists("s:netrw_machine")       |let b:netrw_machine        = s:netrw_machine       |endif
8097  if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
8098
8099"  call Dret("s:RestoreBufVars")
8100endfun
8101
8102" ---------------------------------------------------------------------
8103" s:RemotePathAnalysis: {{{2
8104fun! s:RemotePathAnalysis(dirname)
8105"  call Dfunc("s:RemotePathAnalysis()")
8106
8107  let dirpat  = '^\(\w\{-}\)://\(\w\+@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
8108  let s:method  = substitute(a:dirname,dirpat,'\1','')
8109  let s:user    = substitute(a:dirname,dirpat,'\2','')
8110  let s:machine = substitute(a:dirname,dirpat,'\3','')
8111  let s:port    = substitute(a:dirname,dirpat,'\4','')
8112  let s:path    = substitute(a:dirname,dirpat,'\5','')
8113  let s:fname   = substitute(a:dirname,'^.*/\ze.','','')
8114
8115"  call Decho("set up s:method <".s:method .">")
8116"  call Decho("set up s:user   <".s:user   .">")
8117"  call Decho("set up s:machine<".s:machine.">")
8118"  call Decho("set up s:port   <".s:port.">")
8119"  call Decho("set up s:path   <".s:path   .">")
8120"  call Decho("set up s:fname  <".s:fname  .">")
8121
8122"  call Dret("s:RemotePathAnalysis")
8123endfun
8124
8125" ---------------------------------------------------------------------
8126" s:RemoteSystem: runs a command on a remote host using ssh {{{2
8127"                 Returns status
8128" Runs system() on
8129"    [cd REMOTEDIRPATH;] a:cmd
8130" Note that it doesn't do shellescape(a:cmd)!
8131fun! s:RemoteSystem(cmd)
8132"  call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
8133  if !executable(g:netrw_ssh_cmd)
8134   call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
8135  elseif !exists("b:netrw_curdir")
8136   call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
8137  else
8138   let cmd      = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
8139   let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
8140   if remotedir != ""
8141    let cmd= cmd.' cd '.shellescape(remotedir).";"
8142   else
8143    let cmd= cmd.' '
8144   endif
8145   let cmd= cmd.a:cmd
8146"   call Decho("call system(".cmd.")")
8147   let ret= system(cmd)
8148  endif
8149"  call Dret("s:RemoteSystem ".ret)
8150  return ret
8151endfun
8152
8153" ---------------------------------------------------------------------
8154" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
8155fun! s:RestoreWinVars()
8156"  call Dfunc("s:RestoreWinVars()")
8157  if exists("s:bannercnt")      |let w:netrw_bannercnt       = s:bannercnt      |unlet s:bannercnt      |endif
8158  if exists("s:col")            |let w:netrw_col             = s:col            |unlet s:col            |endif
8159  if exists("s:curdir")         |let w:netrw_curdir          = s:curdir         |unlet s:curdir         |endif
8160  if exists("s:explore_bufnr")  |let w:netrw_explore_bufnr   = s:explore_bufnr  |unlet s:explore_bufnr  |endif
8161  if exists("s:explore_indx")   |let w:netrw_explore_indx    = s:explore_indx   |unlet s:explore_indx   |endif
8162  if exists("s:explore_line")   |let w:netrw_explore_line    = s:explore_line   |unlet s:explore_line   |endif
8163  if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
8164  if exists("s:explore_list")   |let w:netrw_explore_list    = s:explore_list   |unlet s:explore_list   |endif
8165  if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
8166  if exists("s:fpl")            |let w:netrw_fpl             = s:fpl            |unlet s:fpl            |endif
8167  if exists("s:hline")          |let w:netrw_hline           = s:hline          |unlet s:hline          |endif
8168  if exists("s:line")           |let w:netrw_line            = s:line           |unlet s:line           |endif
8169  if exists("s:liststyle")      |let w:netrw_liststyle       = s:liststyle      |unlet s:liststyle      |endif
8170  if exists("s:method")         |let w:netrw_method          = s:method         |unlet s:method         |endif
8171  if exists("s:prvdir")         |let w:netrw_prvdir          = s:prvdir         |unlet s:prvdir         |endif
8172  if exists("s:treedict")       |let w:netrw_treedict        = s:treedict       |unlet s:treedict       |endif
8173  if exists("s:treetop")        |let w:netrw_treetop         = s:treetop        |unlet s:treetop        |endif
8174  if exists("s:winnr")          |let w:netrw_winnr           = s:winnr          |unlet s:winnr          |endif
8175"  call Dret("s:RestoreWinVars")
8176endfun
8177
8178" ---------------------------------------------------------------------
8179" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
8180"
8181"             s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
8182"             is true) and a command, :Rexplore, which call this function.
8183"
8184"             s:nbcd_curpos_{bufnr('%')} is set up by s:NetrwBrowseChgDir()
8185fun! s:NetrwRexplore(islocal,dirname)
8186"  call Dfunc("s:NetrwRexplore(islocal=".a:islocal." dirname<".a:dirname.">)")
8187  if a:islocal
8188   call netrw#LocalBrowseCheck(a:dirname)
8189  else
8190   call s:NetrwBrowse(0,a:dirname)
8191  endif
8192  if exists("s:nbcd_curpos_{bufnr('%')}")
8193   call netrw#NetrwRestorePosn(s:nbcd_curpos_{bufnr('%')})
8194   unlet s:nbcd_curpos_{bufnr('%')}
8195  endif
8196  if exists("s:explore_match")
8197   exe "2match netrwMarkFile /".s:explore_match."/"
8198  endif
8199"  call Dret("s:NetrwRexplore")
8200endfun
8201
8202" ---------------------------------------------------------------------
8203" s:SaveBufVars: {{{2
8204fun! s:SaveBufVars()
8205"  call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
8206
8207  if exists("b:netrw_curdir")        |let s:netrw_curdir         = b:netrw_curdir        |endif
8208  if exists("b:netrw_lastfile")      |let s:netrw_lastfile       = b:netrw_lastfile      |endif
8209  if exists("b:netrw_method")        |let s:netrw_method         = b:netrw_method        |endif
8210  if exists("b:netrw_fname")         |let s:netrw_fname          = b:netrw_fname         |endif
8211  if exists("b:netrw_machine")       |let s:netrw_machine        = b:netrw_machine       |endif
8212  if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
8213
8214"  call Dret("s:SaveBufVars")
8215endfun
8216
8217" ---------------------------------------------------------------------
8218" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
8219fun! s:SaveWinVars()
8220"  call Dfunc("s:SaveWinVars() win#".winnr())
8221  if exists("w:netrw_bannercnt")      |let s:bannercnt       = w:netrw_bannercnt      |endif
8222  if exists("w:netrw_col")            |let s:col             = w:netrw_col            |endif
8223  if exists("w:netrw_curdir")         |let s:curdir          = w:netrw_curdir         |endif
8224  if exists("w:netrw_explore_bufnr")  |let s:explore_bufnr   = w:netrw_explore_bufnr  |endif
8225  if exists("w:netrw_explore_indx")   |let s:explore_indx    = w:netrw_explore_indx   |endif
8226  if exists("w:netrw_explore_line")   |let s:explore_line    = w:netrw_explore_line   |endif
8227  if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
8228  if exists("w:netrw_explore_list")   |let s:explore_list    = w:netrw_explore_list   |endif
8229  if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
8230  if exists("w:netrw_fpl")            |let s:fpl             = w:netrw_fpl            |endif
8231  if exists("w:netrw_hline")          |let s:hline           = w:netrw_hline          |endif
8232  if exists("w:netrw_line")           |let s:line            = w:netrw_line           |endif
8233  if exists("w:netrw_liststyle")      |let s:liststyle       = w:netrw_liststyle      |endif
8234  if exists("w:netrw_method")         |let s:method          = w:netrw_method         |endif
8235  if exists("w:netrw_prvdir")         |let s:prvdir          = w:netrw_prvdir         |endif
8236  if exists("w:netrw_treedict")       |let s:treedict        = w:netrw_treedict       |endif
8237  if exists("w:netrw_treetop")        |let s:treetop         = w:netrw_treetop        |endif
8238  if exists("w:netrw_winnr")          |let s:winnr           = w:netrw_winnr          |endif
8239"  call Dret("s:SaveWinVars")
8240endfun
8241
8242" ---------------------------------------------------------------------
8243" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
8244"   To allow separate windows to have their own activities, such as
8245"   Explore **/pattern, several variables have been made window-oriented.
8246"   However, when the user splits a browser window (ex: ctrl-w s), these
8247"   variables are not inherited by the new window.  SetBufWinVars() and
8248"   UseBufWinVars() get around that.
8249fun! s:SetBufWinVars()
8250"  call Dfunc("s:SetBufWinVars() win#".winnr())
8251  if exists("w:netrw_liststyle")      |let b:netrw_liststyle      = w:netrw_liststyle      |endif
8252  if exists("w:netrw_bannercnt")      |let b:netrw_bannercnt      = w:netrw_bannercnt      |endif
8253  if exists("w:netrw_method")         |let b:netrw_method         = w:netrw_method         |endif
8254  if exists("w:netrw_prvdir")         |let b:netrw_prvdir         = w:netrw_prvdir         |endif
8255  if exists("w:netrw_explore_indx")   |let b:netrw_explore_indx   = w:netrw_explore_indx   |endif
8256  if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
8257  if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
8258  if exists("w:netrw_explore_bufnr")  |let b:netrw_explore_bufnr  = w:netrw_explore_bufnr  |endif
8259  if exists("w:netrw_explore_line")   |let b:netrw_explore_line   = w:netrw_explore_line   |endif
8260  if exists("w:netrw_explore_list")   |let b:netrw_explore_list   = w:netrw_explore_list   |endif
8261"  call Dret("s:SetBufWinVars")
8262endfun
8263
8264" ---------------------------------------------------------------------
8265" s:SetRexDir: set directory for :Rexplore {{{2
8266fun! s:SetRexDir(islocal,dirname)
8267"  call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">)")
8268  " set up Rex and leftmouse-double-click
8269  if a:islocal
8270   exe 'com! Rexplore call s:NetrwRexplore(1,"'.escape(a:dirname,'"\').'")'
8271   if g:netrw_retmap
8272    if !hasmapto("<Plug>NetrwReturn") && maparg("<2-leftmouse>","n") == ""
8273     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
8274    endif
8275    let dir = escape(a:dirname, s:netrw_map_escape)
8276    exe 'nnoremap <silent> <Plug>NetrwReturn :call <SID>NetrwRexplore(1,"'.dir.'")<cr>'
8277   endif
8278  else
8279   exe 'com! Rexplore call s:NetrwRexplore(0,"'.escape(a:dirname,'"\').'")'
8280   if g:netrw_retmap
8281    if !hasmapto("<Plug>NetrwReturn") && maparg("<2-leftmouse>","n") == ""
8282     nmap <unique> <silent> <2-leftmouse>	<Plug>NetrwReturn
8283    endif
8284    let dir = escape(a:dirname, s:netrw_map_escape)
8285    exe 'nnoremap <silent> <Plug>NetrwReturn :call <SID>NetrwRexplore(0,"'.dir.'")<cr>'
8286   endif
8287  endif
8288"  call Dret("s:SetRexDir")
8289endfun
8290
8291" ---------------------------------------------------------------------
8292" s:Strlen: this function returns the length of a string, even if its {{{2
8293"           using two-byte etc characters.
8294"           Solution from Nicolai Weibull, vim docs (:help strlen()), Tony Mechelynck,
8295"           and a bit from me.
8296"           if g:netrw_xstrlen is zero (default), then the builtin strlen() function is used.
8297fun! s:Strlen(x)
8298"  call Dfunc("s:Strlen(x<".a:x.">")
8299  if g:netrw_xstrlen == 1
8300   " number of codepoints (Latin a + combining circumflex is two codepoints)
8301   " (comment from TM, solution from NW)
8302   let ret= strlen(substitute(a:x,'.','c','g'))
8303
8304  elseif g:netrw_xstrlen == 2
8305   " number of spacing codepoints (Latin a + combining circumflex is one spacing 
8306   " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
8307   " (comment from TM, solution from TM)
8308   let ret=strlen(substitute(a:x, '.\Z', 'x', 'g')) 
8309
8310  elseif g:netrw_xstrlen == 3
8311   " virtual length (counting, for instance, tabs as anything between 1 and 
8312   " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately 
8313   " preceded by lam, one otherwise, etc.)
8314   " (comment from TM, solution from me)
8315   let modkeep= &mod
8316   exe "keepj norm! o\<esc>"
8317   call setline(line("."),a:x)
8318   let ret= virtcol("$") - 1
8319   keepj d
8320   let &mod= modkeep
8321
8322  else
8323   " at least give a decent default
8324   let ret= strlen(a:x)
8325  endif
8326"  call Dret("s:Strlen ".ret)
8327  return ret
8328endfun
8329
8330" ---------------------------------------------------------------------
8331" s:TreeListMove: {{{2
8332fun! s:TreeListMove(dir)
8333"  call Dfunc("s:TreeListMove(dir<".a:dir.">)")
8334  let curline  = getline('.')
8335  let prvline  = (line(".") > 1)?         getline(line(".")-1) : ''
8336  let nxtline  = (line(".") < line("$"))? getline(line(".")+1) : ''
8337  let curindent= substitute(curline,'^\([| ]*\).\{-}$','\1','')
8338  let indentm1 = substitute(curindent,'^| ','','')
8339"  call Decho("prvline  <".prvline."> #".line(".")-1)
8340"  call Decho("curline  <".curline."> #".line("."))
8341"  call Decho("nxtline  <".nxtline."> #".line(".")+1)
8342"  call Decho("curindent<".curindent.">")
8343"  call Decho("indentm1 <".indentm1.">")
8344
8345  if curline !~ '/$'
8346"   call Decho('regfile')
8347   if     a:dir == '[' && prvline != ''
8348    keepj norm! 0
8349    let nl = search('^'.indentm1.'[^|]','bWe')    " search backwards from regular file
8350"    call Decho("regfile srch back: ".nl)
8351   elseif a:dir == ']' && nxtline != ''
8352    keepj norm! $
8353    let nl = search('^'.indentm1.'[^|]','We')     " search forwards from regular file
8354"    call Decho("regfile srch fwd: ".nl)
8355   endif
8356
8357  elseif a:dir == '[' && prvline != ''
8358   keepj norm! 0
8359   let curline= line(".")
8360   let nl     = search('^'.curindent.'[^|]','bWe') " search backwards From directory, same indentation
8361"   call Decho("dir srch back ind: ".nl)
8362   if nl != 0
8363    if line(".") == curline-1
8364     let nl= search('^'.indentm1.'[^|]','bWe')     " search backwards from directory, indentation - 1
8365"     call Decho("dir srch back ind-1: ".nl)
8366    endif
8367   endif
8368
8369  elseif a:dir == ']' && nxtline != ''
8370   keepj norm! $
8371   let curline = line(".")
8372   let nl      = search('^'.curindent.'[^|]','We') " search forwards from directory, same indentation
8373"   call Decho("dir srch fwd ind: ".nl)
8374   if nl != 0
8375    if line(".") == curline+1
8376     let nl= search('^'.indentm1.'[^|]','We')         " search forwards from directory, indentation - 1
8377"     call Decho("dir srch fwd ind-1: ".nl)
8378    endif
8379   endif
8380
8381  endif
8382
8383"  call Dret("s:TreeListMove")
8384endfun
8385
8386" ---------------------------------------------------------------------
8387" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
8388"                      The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
8389"                      can't be called except via emenu.  But due to locale, that menu line may not be called
8390"                      Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
8391fun! s:UpdateBuffersMenu()
8392"  call Dfunc("s:UpdateBuffersMenu()")
8393  if has("gui") && has("menu") && has("gui_running") && &go =~ 'm' && g:netrw_menu
8394   try
8395    silent emenu Buffers.Refresh\ menu
8396   catch /^Vim\%((\a\+)\)\=:E/
8397    let v:errmsg= ""
8398    silent call s:NetrwBMShow()
8399   endtry
8400  endif
8401"  call Dret("s:UpdateBuffersMenu")
8402endfun
8403
8404" ---------------------------------------------------------------------
8405" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
8406"              Matching function to BufferWinVars()
8407fun! s:UseBufWinVars()
8408"  call Dfunc("s:UseBufWinVars()")
8409  if exists("b:netrw_liststyle")       && !exists("w:netrw_liststyle")      |let w:netrw_liststyle       = b:netrw_liststyle      |endif
8410  if exists("b:netrw_bannercnt")       && !exists("w:netrw_bannercnt")      |let w:netrw_bannercnt       = b:netrw_bannercnt      |endif
8411  if exists("b:netrw_method")          && !exists("w:netrw_method")         |let w:netrw_method          = b:netrw_method         |endif
8412  if exists("b:netrw_prvdir")          && !exists("w:netrw_prvdir")         |let w:netrw_prvdir          = b:netrw_prvdir         |endif
8413  if exists("b:netrw_explore_indx")    && !exists("w:netrw_explore_indx")   |let w:netrw_explore_indx    = b:netrw_explore_indx   |endif
8414  if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
8415  if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
8416  if exists("b:netrw_explore_bufnr")   && !exists("w:netrw_explore_bufnr")  |let w:netrw_explore_bufnr   = b:netrw_explore_bufnr  |endif
8417  if exists("b:netrw_explore_line")    && !exists("w:netrw_explore_line")   |let w:netrw_explore_line    = b:netrw_explore_line   |endif
8418  if exists("b:netrw_explore_list")    && !exists("w:netrw_explore_list")   |let w:netrw_explore_list    = b:netrw_explore_list   |endif
8419"  call Dret("s:UseBufWinVars")
8420endfun
8421
8422" ---------------------------------------------------------------------
8423" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
8424fun! netrw#WinPath(path)
8425"  call Dfunc("netrw#WinPath(path<".a:path.">)")
8426  if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && (has("win32") || has("win95") || has("win64") || has("win16"))
8427   " remove cygdrive prefix, if present
8428   let path = substitute(a:path,'/cygdrive/\(.\)','\1:','')
8429   " remove trailing slash (Win95)
8430   let path = substitute(path, '\(\\\|/\)$', '', 'g')
8431   " remove escaped spaces
8432   let path = substitute(path, '\ ', ' ', 'g')
8433   " convert slashes to backslashes
8434   let path = substitute(path, '/', '\', 'g')
8435  else
8436   let path= a:path
8437  endif
8438"  call Dret("netrw#WinPath <".path.">")
8439  return path
8440endfun
8441
8442" ---------------------------------------------------------------------
8443" Settings Restoration: {{{2
8444let &cpo= s:keepcpo
8445unlet s:keepcpo
8446
8447" ------------------------------------------------------------------------
8448" Modelines: {{{1
8449" vim:ts=8 fdm=marker
8450