blob: 044b2da17b066658bdd62ff3744f921f0412651b [file] [log] [blame]
Bram Moolenaar9964e462007-05-05 17:54:07 +00001" netrw.vim: Handles file transfer and remote directory listing across
2" AUTOLOAD SECTION
Christian Brabandtf9ca1392024-02-19 20:37:11 +01003" Maintainer: This runtime file is looking for a new maintainer.
Luca Saccarolac363ca12024-12-19 20:16:18 +01004" Date: May 03, 2023
5" Version: 173a
Travis Sheltone34d0e32024-07-30 21:08:56 +02006" Last Change: {{{1
Luca Saccarolac363ca12024-12-19 20:16:18 +01007" 2023 Nov 21 by Vim Project: ignore wildignore when expanding $COMSPEC (v173a)
8" 2023 Nov 22 by Vim Project: fix handling of very long filename on longlist style (v173a)
Christian Brabandt8fad5d52024-02-29 18:12:30 +01009" 2024 Feb 19 by Vim Project: (announce adoption)
10" 2024 Feb 29 by Vim Project: handle symlinks in tree mode correctly
Christian Brabandt08d24012024-04-03 22:44:27 +020011" 2024 Apr 03 by Vim Project: detect filetypes for remote edited files
Nir Lichtman1e34b952024-05-08 19:19:34 +020012" 2024 May 08 by Vim Project: cleanup legacy Win9X checks
Nir Lichtmance2ad9f2024-05-09 20:20:36 +020013" 2024 May 09 by Vim Project: remove hard-coded private.ppk
Nir Lichtmanc16c4a22024-05-10 23:43:29 +020014" 2024 May 10 by Vim Project: recursively delete directories by default
Christian Brabandt43f2edc2024-05-13 20:56:43 +020015" 2024 May 13 by Vim Project: prefer scp over pscp
Christian Brabandt98b73eb2024-06-04 18:15:57 +020016" 2024 Jun 04 by Vim Project: set bufhidden if buffer changed, nohidden is set and buffer shall be switched (#14915)
Christian Brabandt14879472024-06-13 21:25:35 +020017" 2024 Jun 13 by Vim Project: glob() on Windows fails when a directory name contains [] (#14952)
Enno3146d632024-07-04 19:44:42 +020018" 2024 Jun 23 by Vim Project: save ad restore registers when liststyle = WIDELIST (#15077, #15114)
Damien9d57ea52024-07-22 20:23:48 +020019" 2024 Jul 22 by Vim Project: avoid endless recursion (#15318)
Christian Brabandt581d4a72024-07-23 21:14:06 +020020" 2024 Jul 23 by Vim Project: escape filename before trying to delete it (#15330)
Travis Sheltone34d0e32024-07-30 21:08:56 +020021" 2024 Jul 30 by Vim Project: handle mark-copy to same target directory (#12112)
Ivan Shapovalovc527d902024-08-02 19:43:12 +020022" 2024 Aug 02 by Vim Project: honor g:netrw_alt{o,v} for :{S,H,V}explore (#15417)
Damien7c754112024-08-15 21:58:57 +020023" 2024 Aug 15 by Vim Project: style changes, prevent E121 (#15501)
yasuda38cfa2b2024-08-22 20:54:47 +020024" 2024 Aug 22 by Vim Project: fix mf-selection highlight (#15551)
yasudac75dad02024-08-22 21:06:32 +020025" 2024 Aug 22 by Vim Project: adjust echo output of mx command (#15550)
Christian Brabandt0f5effb2024-09-15 19:17:23 +020026" 2024 Sep 15 by Vim Project: more strict confirmation dialog (#15680)
yasudac18a9d52024-09-19 18:09:51 +020027" 2024 Sep 19 by Vim Project: mf-selection highlight uses wrong pattern (#15700)
Peter Aronoffbe551da2024-09-22 11:29:40 +020028" 2024 Sep 21 by Vim Project: remove extraneous closing bracket (#15718)
Luca Saccarolaa7d45612024-10-21 21:27:03 +020029" 2024 Oct 21 by Vim Project: remove netrwFileHandlers (#15895)
Konfekt3d7e5672024-10-27 22:16:49 +010030" 2024 Oct 27 by Vim Project: clean up gx mapping (#15721)
Christian Brabandtaa2ce6f2024-10-30 18:27:03 +010031" 2024 Oct 30 by Vim Project: fix filetype detection for remote files (#15961)
Christian Brabandt9f320692024-10-30 18:36:20 +010032" 2024 Oct 30 by Vim Project: fix x mapping on cygwin (#13687)
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +010033" 2024 Oct 31 by Vim Project: add netrw#Launch() and netrw#Open() (#15962)
Tom Benham4d618002024-10-31 10:47:23 +010034" 2024 Oct 31 by Vim Project: fix E874 when browsing remote dir (#15964)
Christian Brabandta063b222024-11-07 14:30:30 +010035" 2024 Nov 07 by Vim Project: use keeppatterns to prevent polluting the search history
Tom Benham64a536d2024-11-07 21:15:03 +010036" 2024 Nov 07 by Vim Project: fix a few issues with netrw tree listing (#15996)
Christian Brabandt5b63b232024-11-10 20:22:34 +010037" 2024 Nov 10 by Vim Project: directory symlink not resolved in tree view (#16020)
Konfekt460799d2024-11-14 21:42:27 +010038" 2024 Nov 14 by Vim Project: small fixes to netrw#BrowseX (#16056)
Christian Brabandtcacfccf2024-11-23 13:28:01 +010039" 2024 Nov 23 by Vim Project: update decompress defaults (#16104)
GuyBrushd7745ac2024-11-23 14:13:10 +010040" 2024 Nov 23 by Vim Project: fix powershell escaping issues (#16094)
Konfekteda923e2024-12-04 20:12:44 +010041" 2024 Dec 04 by Vim Project: do not detach for gvim (#16168)
Christian Brabandt92b36662024-12-08 09:52:37 +010042" 2024 Dec 08 by Vim Project: check the first arg of netrw_browsex_viewer for being executable (#16185)
Christian Brabandt5c42c772024-12-12 19:13:08 +010043" 2024 Dec 12 by Vim Project: do not pollute the search history (#16206)
Luca Saccarolac363ca12024-12-19 20:16:18 +010044" 2024 Dec 19 by Vim Project: change style (#16248)
Travis Sheltone34d0e32024-07-30 21:08:56 +020045" }}}
Luca Saccarolac363ca12024-12-19 20:16:18 +010046" Former Maintainer: Charles E Campbell
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +000047" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
Bram Moolenaare0fa3742016-02-20 15:47:01 +010048" Copyright: Copyright (C) 2016 Charles E. Campbell {{{1
Bram Moolenaar572cb562005-08-05 21:35:02 +000049" Permission is hereby granted to use and distribute this code,
50" with or without modifications, provided that this copyright
51" notice is copied with it. Like anything else that's free,
Bram Moolenaar1afcace2005-11-25 19:54:28 +000052" netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
Bram Moolenaar446cb832008-06-24 21:56:24 +000053" *as is* and come with no warranty of any kind, either
Bram Moolenaar1afcace2005-11-25 19:54:28 +000054" expressed or implied. By using this plugin, you agree that
55" in no event will the copyright holder be liable for any damages
56" resulting from the use of this software.
Bram Moolenaar91359012019-11-30 17:57:03 +010057"
58" Note: the code here was started in 1999 under a much earlier version of vim. The directory browsing
59" code was written using vim v6, which did not have Lists (Lists were first offered with vim-v7).
60"
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020061"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar071d4272004-06-13 20:20:40 +000062"
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +000063" But be doers of the Word, and not only hearers, deluding your own selves {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000064" (James 1:22 RSV)
65" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Bram Moolenaar9964e462007-05-05 17:54:07 +000066" Load Once: {{{1
Bram Moolenaar1afcace2005-11-25 19:54:28 +000067if &cp || exists("g:loaded_netrw")
68 finish
69endif
Bram Moolenaar85850f32019-07-19 22:05:51 +020070
71" Check that vim has patches that netrw requires.
72" Patches needed for v7.4: 1557, and 213.
73" (netrw will benefit from vim's having patch#656, too)
74let s:needspatches=[1557,213]
75if exists("s:needspatches")
Luca Saccarolac363ca12024-12-19 20:16:18 +010076 for ptch in s:needspatches
77 if v:version < 704 || (v:version == 704 && !has("patch".ptch))
78 if !exists("s:needpatch{ptch}")
79 unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch#".ptch
80 endif
81 let s:needpatch{ptch}= 1
82 finish
83 endif
84 endfor
Bram Moolenaar13600302014-05-22 18:26:40 +020085endif
Bram Moolenaar85850f32019-07-19 22:05:51 +020086
Bram Moolenaarb7398fe2023-05-14 18:50:25 +010087let g:loaded_netrw = "v173"
Bram Moolenaar446cb832008-06-24 21:56:24 +000088
Bram Moolenaar1afcace2005-11-25 19:54:28 +000089let s:keepcpo= &cpo
Bram Moolenaara6878372014-03-22 21:02:50 +010090setl cpo&vim
Bram Moolenaar85850f32019-07-19 22:05:51 +020091"DechoFuncName 1
Bram Moolenaar8d043172014-01-23 14:24:41 +010092"DechoRemOn
Bram Moolenaara0f849e2015-10-30 14:37:44 +010093"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw,'~'.expand("<slnum>"))
Bram Moolenaar071d4272004-06-13 20:20:40 +000094
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +000095" ======================
96" Netrw Variables: {{{1
97" ======================
98
Bram Moolenaar071d4272004-06-13 20:20:40 +000099" ---------------------------------------------------------------------
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200100" netrw#ErrorMsg: {{{2
101" 0=note = s:NOTE
102" 1=warning = s:WARNING
103" 2=error = s:ERROR
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100104" Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number)
105" netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number)
106" (this function can optionally take a list of messages)
Bram Moolenaar29634562020-01-09 21:46:04 +0100107" Dec 2, 2019 : max errnum currently is 106
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200108fun! netrw#ErrorMsg(level,msg,errnum)
Luca Saccarolac363ca12024-12-19 20:16:18 +0100109 " call Dfunc("netrw#ErrorMsg(level=".a:level." msg<".a:msg."> errnum=".a:errnum.") g:netrw_use_errorwindow=".g:netrw_use_errorwindow)
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200110
111 if a:level < g:netrw_errorlvl
Luca Saccarolac363ca12024-12-19 20:16:18 +0100112 " call Dret("netrw#ErrorMsg : suppressing level=".a:level." since g:netrw_errorlvl=".g:netrw_errorlvl)
113 return
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200114 endif
115
116 if a:level == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +0100117 let level= "**warning** (netrw) "
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200118 elseif a:level == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +0100119 let level= "**error** (netrw) "
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200120 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100121 let level= "**note** (netrw) "
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200122 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100123 " call Decho("level=".level,'~'.expand("<slnum>"))
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200124
Damienb4d11642024-08-15 22:00:45 +0200125 if g:netrw_use_errorwindow == 2 && exists("*popup_atcursor")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100126 " use popup window
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100127 if type(a:msg) == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +0100128 let msg = [level]+a:msg
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100129 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100130 let msg= level.a:msg
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100131 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100132 let s:popuperr_id = popup_atcursor(msg,{})
133 let s:popuperr_text= ""
134 elseif g:netrw_use_errorwindow
135 " (default) netrw creates a one-line window to show error/warning
136 " messages (reliably displayed)
137
138 " record current window number
139 let s:winBeforeErr= winnr()
140 " call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>"))
141
142 " getting messages out reliably is just plain difficult!
143 " This attempt splits the current window, creating a one line window.
144 if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
145 " call Decho("write to NetrwMessage buffer",'~'.expand("<slnum>"))
146 exe bufwinnr("NetrwMessage")."wincmd w"
147 " call Decho("setl ma noro",'~'.expand("<slnum>"))
148 setl ma noro
149 if type(a:msg) == 3
150 for msg in a:msg
151 NetrwKeepj call setline(line("$")+1,level.msg)
152 endfor
153 else
154 NetrwKeepj call setline(line("$")+1,level.a:msg)
155 endif
156 NetrwKeepj $
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100157 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100158 " call Decho("create a NetrwMessage buffer window",'~'.expand("<slnum>"))
159 bo 1split
160 sil! call s:NetrwEnew()
161 sil! NetrwKeepj call s:NetrwOptionsSafe(1)
162 setl bt=nofile
163 NetrwKeepj file NetrwMessage
164 " call Decho("setl ma noro",'~'.expand("<slnum>"))
165 setl ma noro
166 if type(a:msg) == 3
167 for msg in a:msg
168 NetrwKeepj call setline(line("$")+1,level.msg)
169 endfor
170 else
171 NetrwKeepj call setline(line("$"),level.a:msg)
172 endif
173 NetrwKeepj $
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100174 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100175 " call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr(),'~'.expand("<slnum>"))
176 if &fo !~ '[ta]'
177 syn clear
178 syn match netrwMesgNote "^\*\*note\*\*"
179 syn match netrwMesgWarning "^\*\*warning\*\*"
180 syn match netrwMesgError "^\*\*error\*\*"
181 hi link netrwMesgWarning WarningMsg
182 hi link netrwMesgError Error
183 endif
184 " call Decho("setl noma ro bh=wipe",'~'.expand("<slnum>"))
185 setl ro nomod noma bh=wipe
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200186
187 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100188 " (optional) netrw will show messages using echomsg. Even if the
189 " message doesn't appear, at least it'll be recallable via :messages
190 " redraw!
191 if a:level == s:WARNING
192 echohl WarningMsg
193 elseif a:level == s:ERROR
194 echohl Error
195 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100196
Luca Saccarolac363ca12024-12-19 20:16:18 +0100197 if type(a:msg) == 3
198 for msg in a:msg
199 unsilent echomsg level.msg
200 endfor
201 else
202 unsilent echomsg level.a:msg
203 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100204
Luca Saccarolac363ca12024-12-19 20:16:18 +0100205 " call Decho("echomsg ***netrw*** ".a:msg,'~'.expand("<slnum>"))
206 echohl None
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200207 endif
208
Luca Saccarolac363ca12024-12-19 20:16:18 +0100209 " call Dret("netrw#ErrorMsg")
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200210endfun
211
212" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100213" s:NetrwInit: initializes variables if they haven't been defined {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +0100214" Loosely, varname = value.
215fun s:NetrwInit(varname,value)
Luca Saccarolac363ca12024-12-19 20:16:18 +0100216 " call Decho("varname<".a:varname."> value=".a:value,'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +0100217 if !exists(a:varname)
Luca Saccarolac363ca12024-12-19 20:16:18 +0100218 if type(a:value) == 0
219 exe "let ".a:varname."=".a:value
220 elseif type(a:value) == 1 && a:value =~ '^[{[]'
221 exe "let ".a:varname."=".a:value
222 elseif type(a:value) == 1
223 exe "let ".a:varname."="."'".a:value."'"
224 else
225 exe "let ".a:varname."=".a:value
226 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100227 endif
228endfun
229
230" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +0000231" Netrw Constants: {{{2
Bram Moolenaar85850f32019-07-19 22:05:51 +0200232call s:NetrwInit("g:netrw_dirhistcnt",0)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000233if !exists("s:LONGLIST")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100234 call s:NetrwInit("s:THINLIST",0)
235 call s:NetrwInit("s:LONGLIST",1)
236 call s:NetrwInit("s:WIDELIST",2)
237 call s:NetrwInit("s:TREELIST",3)
238 call s:NetrwInit("s:MAXLIST" ,4)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000239endif
240
Damien7c754112024-08-15 21:58:57 +0200241let s:NOTE = 0
242let s:WARNING = 1
243let s:ERROR = 2
244call s:NetrwInit("g:netrw_errorlvl", s:NOTE)
245
Bram Moolenaar9964e462007-05-05 17:54:07 +0000246" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +0200247" Default option values: {{{2
248let g:netrw_localcopycmdopt = ""
249let g:netrw_localcopydircmdopt = ""
250let g:netrw_localmkdiropt = ""
251let g:netrw_localmovecmdopt = ""
Bram Moolenaar85850f32019-07-19 22:05:51 +0200252
253" ---------------------------------------------------------------------
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000254" Default values for netrw's global protocol variables {{{2
Damienb4d11642024-08-15 22:00:45 +0200255if exists("*popup_atcursor")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100256 \ && has("syntax")
257 \ && exists("g:syntax_on")
258 \ && has("mouse")
Bram Moolenaar1d59aa12020-09-19 18:50:13 +0200259 call s:NetrwInit("g:netrw_use_errorwindow",2)
260else
261 call s:NetrwInit("g:netrw_use_errorwindow",1)
262endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200263
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000264if !exists("g:netrw_dav_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100265 if executable("cadaver")
266 let g:netrw_dav_cmd = "cadaver"
267 elseif executable("curl")
268 let g:netrw_dav_cmd = "curl"
269 else
270 let g:netrw_dav_cmd = ""
271 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000272endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000273if !exists("g:netrw_fetch_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100274 if executable("fetch")
275 let g:netrw_fetch_cmd = "fetch -o"
276 else
277 let g:netrw_fetch_cmd = ""
278 endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000279endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100280if !exists("g:netrw_file_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100281 if executable("elinks")
282 call s:NetrwInit("g:netrw_file_cmd","elinks")
283 elseif executable("links")
284 call s:NetrwInit("g:netrw_file_cmd","links")
285 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100286endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000287if !exists("g:netrw_ftp_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100288 let g:netrw_ftp_cmd = "ftp"
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000289endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200290let s:netrw_ftp_cmd= g:netrw_ftp_cmd
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200291if !exists("g:netrw_ftp_options")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100292 let g:netrw_ftp_options= "-i -n"
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200293endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000294if !exists("g:netrw_http_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100295 if executable("wget")
296 let g:netrw_http_cmd = "wget"
297 call s:NetrwInit("g:netrw_http_xcmd","-q -O")
298 elseif executable("curl")
299 let g:netrw_http_cmd = "curl"
300 call s:NetrwInit("g:netrw_http_xcmd","-L -o")
301 elseif executable("elinks")
302 let g:netrw_http_cmd = "elinks"
303 call s:NetrwInit("g:netrw_http_xcmd","-source >")
304 elseif executable("fetch")
305 let g:netrw_http_cmd = "fetch"
306 call s:NetrwInit("g:netrw_http_xcmd","-o")
307 elseif executable("links")
308 let g:netrw_http_cmd = "links"
309 call s:NetrwInit("g:netrw_http_xcmd","-http.extra-header ".shellescape("Accept-Encoding: identity", 1)." -source >")
310 else
311 let g:netrw_http_cmd = ""
312 endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000313endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100314call s:NetrwInit("g:netrw_http_put_cmd","curl -T")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100315call s:NetrwInit("g:netrw_keepj","keepj")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100316call s:NetrwInit("g:netrw_rcp_cmd" , "rcp")
317call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
Bram Moolenaar85850f32019-07-19 22:05:51 +0200318call s:NetrwInit("g:netrw_rsync_sep", "/")
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200319if !exists("g:netrw_scp_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100320 if executable("scp")
321 call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
322 elseif executable("pscp")
323 call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
324 else
325 call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
326 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200327endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100328call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
329call s:NetrwInit("g:netrw_ssh_cmd" , "ssh")
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000330
Nir Lichtman1e34b952024-05-08 19:19:34 +0200331if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100332 \ && exists("g:netrw_use_nt_rcp")
333 \ && g:netrw_use_nt_rcp
334 \ && executable( $SystemRoot .'/system32/rcp.exe')
335 let s:netrw_has_nt_rcp = 1
336 let s:netrw_rcpmode = '-b'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000337else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100338 let s:netrw_has_nt_rcp = 0
339 let s:netrw_rcpmode = ''
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000340endif
341
342" ---------------------------------------------------------------------
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000343" Default values for netrw's global variables {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +0000344" Cygwin Detection ------- {{{3
345if !exists("g:netrw_cygwin")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100346 if has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
347 let g:netrw_cygwin= 1
348 else
349 let g:netrw_cygwin= 0
350 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000351endif
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000352" Default values - a-c ---------- {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +0100353call s:NetrwInit("g:netrw_alto" , &sb)
354call s:NetrwInit("g:netrw_altv" , &spr)
355call s:NetrwInit("g:netrw_banner" , 1)
356call s:NetrwInit("g:netrw_browse_split", 0)
Bram Moolenaar13600302014-05-22 18:26:40 +0200357call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro nornu")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100358call s:NetrwInit("g:netrw_chgwin" , -1)
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200359call s:NetrwInit("g:netrw_clipboard" , 1)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100360call s:NetrwInit("g:netrw_compress" , "gzip")
361call s:NetrwInit("g:netrw_ctags" , "ctags")
Bram Moolenaaradc21822011-04-01 18:03:16 +0200362if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100363 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
364 let g:netrw_cursor= g:netrw_cursorline
Bram Moolenaar446cb832008-06-24 21:56:24 +0000365endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200366call s:NetrwInit("g:netrw_cursor" , 2)
367let s:netrw_usercul = &cursorline
368let s:netrw_usercuc = &cursorcolumn
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200369"call Decho("(netrw) COMBAK: cuc=".&l:cuc." cul=".&l:cul." initialization of s:netrw_cu[cl]")
Bram Moolenaar8d043172014-01-23 14:24:41 +0100370call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
Bram Moolenaar446cb832008-06-24 21:56:24 +0000371" Default values - d-g ---------- {{{3
Bram Moolenaarff034192013-04-24 18:51:19 +0200372call s:NetrwInit("s:didstarstar",0)
Bram Moolenaar85850f32019-07-19 22:05:51 +0200373call s:NetrwInit("g:netrw_dirhistcnt" , 0)
Christian Brabandtcacfccf2024-11-23 13:28:01 +0100374let s:xz_opt = has('unix') ? "XZ_OPT=-T0" :
Luca Saccarolac363ca12024-12-19 20:16:18 +0100375 \ (has("win32") && &shell =~? '\vcmd(\.exe)?$' ?
376 \ "setx XZ_OPT=-T0 &&" : "")
Christian Brabandtcacfccf2024-11-23 13:28:01 +0100377call s:NetrwInit("g:netrw_decompress ", "{"
Luca Saccarolac363ca12024-12-19 20:16:18 +0100378 \ .."'.lz4': 'lz4 -d',"
379 \ .."'.lzo': 'lzop -d',"
380 \ .."'.lz': 'lzip -dk',"
381 \ .."'.7z': '7za x',"
382 \ .."'.001': '7za x',"
383 \ .."'.zip': 'unzip',"
384 \ .."'.bz': 'bunzip2 -k',"
385 \ .."'.bz2': 'bunzip2 -k',"
386 \ .."'.gz': 'gunzip -k',"
387 \ .."'.lzma': 'unlzma -T0 -k',"
388 \ .."'.xz': 'unxz -T0 -k',"
389 \ .."'.zst': 'zstd -T0 -d',"
390 \ .."'.Z': 'uncompress -k',"
391 \ .."'.tar': 'tar -xvf',"
392 \ .."'.tar.bz': 'tar -xvjf',"
393 \ .."'.tar.bz2': 'tar -xvjf',"
394 \ .."'.tbz': 'tar -xvjf',"
395 \ .."'.tbz2': 'tar -xvjf',"
396 \ .."'.tar.gz': 'tar -xvzf',"
397 \ .."'.tgz': 'tar -xvzf',"
398 \ .."'.tar.lzma': '"..s:xz_opt.." tar -xvf --lzma',"
399 \ .."'.tlz': '"..s:xz_opt.." tar -xvf --lzma',"
400 \ .."'.tar.xz': '"..s:xz_opt.." tar -xvfJ',"
401 \ .."'.txz': '"..s:xz_opt.." tar -xvfJ',"
402 \ .."'.tar.zst': '"..s:xz_opt.." tar -xvf --use-compress-program=unzstd',"
403 \ .."'.tzst': '"..s:xz_opt.." tar -xvf --use-compress-program=unzstd',"
404 \ .."'.rar': '"..(executable("unrar")?"unrar x -ad":"rar x -ad").."'"
405 \ .."}")
Christian Brabandtcacfccf2024-11-23 13:28:01 +0100406unlet s:xz_opt
Bram Moolenaar5c736222010-01-06 20:54:52 +0100407call s:NetrwInit("g:netrw_dirhistmax" , 10)
408call s:NetrwInit("g:netrw_fastbrowse" , 1)
409call 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$')
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000410if !exists("g:netrw_ftp_list_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100411 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
412 let g:netrw_ftp_list_cmd = "ls -lF"
413 let g:netrw_ftp_timelist_cmd = "ls -tlF"
414 let g:netrw_ftp_sizelist_cmd = "ls -slF"
415 else
416 let g:netrw_ftp_list_cmd = "dir"
417 let g:netrw_ftp_timelist_cmd = "dir"
418 let g:netrw_ftp_sizelist_cmd = "dir"
419 endif
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000420endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100421call s:NetrwInit("g:netrw_ftpmode",'binary')
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000422" Default values - h-lh ---------- {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +0100423call s:NetrwInit("g:netrw_hide",1)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000424if !exists("g:netrw_ignorenetrc")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100425 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
426 let g:netrw_ignorenetrc= 1
427 else
428 let g:netrw_ignorenetrc= 0
429 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000430endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100431call s:NetrwInit("g:netrw_keepdir",1)
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000432if !exists("g:netrw_list_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100433 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
434 if exists("g:netrw_list_cmd_options")
435 let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
436 else
437 let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
438 endif
439 elseif executable(g:netrw_ssh_cmd)
440 " provide a scp-based default listing command
441 if exists("g:netrw_list_cmd_options")
442 let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
443 else
444 let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
445 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100446 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100447 " call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
448 let g:netrw_list_cmd= ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100449 endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000450endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100451call s:NetrwInit("g:netrw_list_hide","")
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000452" Default values - lh-lz ---------- {{{3
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200453if exists("g:netrw_local_copycmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100454 let g:netrw_localcopycmd= g:netrw_local_copycmd
455 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_copycmd is deprecated in favor of g:netrw_localcopycmd",84)
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200456endif
Bram Moolenaar97d62492012-11-15 21:28:22 +0100457if !exists("g:netrw_localcmdshell")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100458 let g:netrw_localcmdshell= ""
Bram Moolenaar97d62492012-11-15 21:28:22 +0100459endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000460if !exists("g:netrw_localcopycmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100461 if has("win32")
462 if g:netrw_cygwin
463 let g:netrw_localcopycmd= "cp"
464 else
465 let g:netrw_localcopycmd = expand("$COMSPEC", v:true)
466 let g:netrw_localcopycmdopt= " /c copy"
467 endif
468 elseif has("unix") || has("macunix")
469 let g:netrw_localcopycmd= "cp"
Bram Moolenaar446cb832008-06-24 21:56:24 +0000470 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100471 let g:netrw_localcopycmd= ""
Bram Moolenaar446cb832008-06-24 21:56:24 +0000472 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000473endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100474if !exists("g:netrw_localcopydircmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100475 if has("win32")
476 if g:netrw_cygwin
477 let g:netrw_localcopydircmd = "cp"
478 let g:netrw_localcopydircmdopt= " -R"
479 else
480 let g:netrw_localcopydircmd = expand("$COMSPEC", v:true)
481 let g:netrw_localcopydircmdopt= " /c xcopy /e /c /h /i /k"
482 endif
483 elseif has("unix")
484 let g:netrw_localcopydircmd = "cp"
485 let g:netrw_localcopydircmdopt= " -R"
486 elseif has("macunix")
487 let g:netrw_localcopydircmd = "cp"
488 let g:netrw_localcopydircmdopt= " -R"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100489 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100490 let g:netrw_localcopydircmd= ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100491 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100492endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200493if exists("g:netrw_local_mkdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100494 let g:netrw_localmkdir= g:netrw_local_mkdir
495 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_mkdir is deprecated in favor of g:netrw_localmkdir",87)
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200496endif
Nir Lichtman1e34b952024-05-08 19:19:34 +0200497if has("win32")
Bram Moolenaar13600302014-05-22 18:26:40 +0200498 if g:netrw_cygwin
Luca Saccarolac363ca12024-12-19 20:16:18 +0100499 call s:NetrwInit("g:netrw_localmkdir","mkdir")
Bram Moolenaar13600302014-05-22 18:26:40 +0200500 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100501 let g:netrw_localmkdir = expand("$COMSPEC", v:true)
502 let g:netrw_localmkdiropt= " /c mkdir"
Bram Moolenaar13600302014-05-22 18:26:40 +0200503 endif
504else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100505 call s:NetrwInit("g:netrw_localmkdir","mkdir")
Bram Moolenaar13600302014-05-22 18:26:40 +0200506endif
Bram Moolenaar15146672011-10-20 22:22:38 +0200507call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200508if exists("g:netrw_local_movecmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100509 let g:netrw_localmovecmd= g:netrw_local_movecmd
510 call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200511endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000512if !exists("g:netrw_localmovecmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100513 if has("win32")
514 if g:netrw_cygwin
515 let g:netrw_localmovecmd= "mv"
516 else
517 let g:netrw_localmovecmd = expand("$COMSPEC", v:true)
518 let g:netrw_localmovecmdopt= " /c move"
519 endif
520 elseif has("unix") || has("macunix")
521 let g:netrw_localmovecmd= "mv"
Bram Moolenaar446cb832008-06-24 21:56:24 +0000522 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100523 let g:netrw_localmovecmd= ""
Bram Moolenaar446cb832008-06-24 21:56:24 +0000524 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000525endif
Bram Moolenaar29634562020-01-09 21:46:04 +0100526" following serves as an example for how to insert a version&patch specific test
527"if v:version < 704 || (v:version == 704 && !has("patch1107"))
528"endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100529call s:NetrwInit("g:netrw_liststyle" , s:THINLIST)
530" sanity checks
Bram Moolenaar9964e462007-05-05 17:54:07 +0000531if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +0100532 let g:netrw_liststyle= s:THINLIST
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000533endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000534if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100535 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000536endif
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000537" Default values - m-r ---------- {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +0100538call s:NetrwInit("g:netrw_markfileesc" , '*./[\~')
539call s:NetrwInit("g:netrw_maxfilenamelen", 32)
540call s:NetrwInit("g:netrw_menu" , 1)
541call s:NetrwInit("g:netrw_mkdir_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +0200542call s:NetrwInit("g:netrw_mousemaps" , (exists("+mouse") && &mouse =~# '[anh]'))
Bram Moolenaar5c736222010-01-06 20:54:52 +0100543call s:NetrwInit("g:netrw_retmap" , 0)
544if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
Luca Saccarolac363ca12024-12-19 20:16:18 +0100545 call s:NetrwInit("g:netrw_chgperm" , "chmod PERM FILENAME")
Nir Lichtman1e34b952024-05-08 19:19:34 +0200546elseif has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100547 call s:NetrwInit("g:netrw_chgperm" , "cacls FILENAME /e /p PERM")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100548else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100549 call s:NetrwInit("g:netrw_chgperm" , "chmod PERM FILENAME")
Bram Moolenaar446cb832008-06-24 21:56:24 +0000550endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100551call s:NetrwInit("g:netrw_preview" , 0)
552call s:NetrwInit("g:netrw_scpport" , "-P")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100553call s:NetrwInit("g:netrw_servername" , "NETRWSERVER")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100554call s:NetrwInit("g:netrw_sshport" , "-p")
555call s:NetrwInit("g:netrw_rename_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
556call s:NetrwInit("g:netrw_rm_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
557call s:NetrwInit("g:netrw_rmdir_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
Bram Moolenaara6878372014-03-22 21:02:50 +0100558call s:NetrwInit("g:netrw_rmf_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
559" Default values - q-s ---------- {{{3
560call s:NetrwInit("g:netrw_quickhelp",0)
561let s:QuickHelp= ["-:go up dir D:delete R:rename s:sort-by x:special",
Luca Saccarolac363ca12024-12-19 20:16:18 +0100562 \ "(create new) %:file d:directory",
563 \ "(windows split&open) o:horz v:vert p:preview",
564 \ "i:style qf:file info O:obtain r:reverse",
565 \ "(marks) mf:mark file mt:set target mm:move mc:copy",
566 \ "(bookmarks) mb:make mB:delete qb:list gb:go to",
567 \ "(history) qb:list u:go up U:go down",
568 \ "(targets) mt:target Tb:use bookmark Th:use history"]
Bram Moolenaar5c736222010-01-06 20:54:52 +0100569" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
570call s:NetrwInit("g:netrw_sepchr" , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100571if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
Luca Saccarolac363ca12024-12-19 20:16:18 +0100572 call s:NetrwInit("s:netrw_silentxfer" , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100573else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100574 call s:NetrwInit("s:netrw_silentxfer" , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100575endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100576call s:NetrwInit("g:netrw_sort_by" , "name") " alternatives: date , size
577call s:NetrwInit("g:netrw_sort_options" , "")
578call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse (z y x ...)
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000579if !exists("g:netrw_sort_sequence")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100580 if has("unix")
581 let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
582 else
583 let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
584 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000585endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100586call s:NetrwInit("g:netrw_special_syntax" , 0)
587call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
Bram Moolenaara6878372014-03-22 21:02:50 +0100588call s:NetrwInit("g:netrw_use_noswf" , 1)
Bram Moolenaare0fa3742016-02-20 15:47:01 +0100589call s:NetrwInit("g:netrw_sizestyle" ,"b")
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000590" Default values - t-w ---------- {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +0100591call s:NetrwInit("g:netrw_timefmt","%c")
Bram Moolenaarff034192013-04-24 18:51:19 +0200592if !exists("g:netrw_xstrlen")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100593 if exists("g:Align_xstrlen")
594 let g:netrw_xstrlen= g:Align_xstrlen
595 elseif exists("g:drawit_xstrlen")
596 let g:netrw_xstrlen= g:drawit_xstrlen
597 elseif &enc == "latin1" || !has("multi_byte")
598 let g:netrw_xstrlen= 0
599 else
600 let g:netrw_xstrlen= 1
601 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200602endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100603call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
Bram Moolenaar251e1912011-06-19 05:09:16 +0200604call s:NetrwInit("g:netrw_winsize",50)
Bram Moolenaara0f849e2015-10-30 14:37:44 +0100605call s:NetrwInit("g:netrw_wiw",1)
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200606if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000607" ---------------------------------------------------------------------
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000608" Default values for netrw's script variables: {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +0100609call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
Nir Lichtman1e34b952024-05-08 19:19:34 +0200610if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100611 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200612else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100613 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200614endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200615call s:NetrwInit("g:netrw_menu_escape",'.&? \')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100616call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
617call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
Bram Moolenaara6878372014-03-22 21:02:50 +0100618if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
Luca Saccarolac363ca12024-12-19 20:16:18 +0100619 let s:treedepthstring= "│ "
Bram Moolenaar8d043172014-01-23 14:24:41 +0100620else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100621 let s:treedepthstring= "| "
Bram Moolenaar8d043172014-01-23 14:24:41 +0100622endif
Bram Moolenaar85850f32019-07-19 22:05:51 +0200623call s:NetrwInit("s:netrw_posn",'{}')
Bram Moolenaar8299df92004-07-10 09:47:34 +0000624
625" BufEnter event ignored by decho when following variable is true
626" Has a side effect that doau BufReadPost doesn't work, so
627" files read by network transfer aren't appropriately highlighted.
Luca Saccarolac363ca12024-12-19 20:16:18 +0100628"let g:decho_bufenter = 1 "Decho
Bram Moolenaar071d4272004-06-13 20:20:40 +0000629
Bram Moolenaaradc21822011-04-01 18:03:16 +0200630" ======================
631" Netrw Initialization: {{{1
632" ======================
Bram Moolenaar15146672011-10-20 22:22:38 +0200633if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100634 " call Decho("installed beval events",'~'.expand("<slnum>"))
635 let &l:bexpr = "netrw#BalloonHelp()"
636 " call Decho("&l:bexpr<".&l:bexpr."> buf#".bufnr())
637 au FileType netrw setl beval
638 au WinLeave * if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
639 au VimEnter * let s:initbeval= &beval
640 "else " Decho
641 " if v:version < 700 | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>")) | endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +0100642" if !has("balloon_eval") | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>")) | endif
643" if exists("s:initbeval") | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>")) | endif
644" if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>")) | endif
645" if !has("syntax") | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
646" if exists("g:syntax_on") | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>")) | endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200647endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100648au WinEnter * if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200649
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +0200650if g:netrw_keepj =~# "keepj"
Luca Saccarolac363ca12024-12-19 20:16:18 +0100651 com! -nargs=* NetrwKeepj keepj <args>
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100652else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100653 let g:netrw_keepj= ""
654 com! -nargs=* NetrwKeepj <args>
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100655endif
656
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000657" ==============================
658" Netrw Utility Functions: {{{1
659" ==============================
660
Bram Moolenaaradc21822011-04-01 18:03:16 +0200661" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +0100662" netrw#BalloonHelp: {{{2
Bram Moolenaar8d043172014-01-23 14:24:41 +0100663if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100664 " call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
665 fun! netrw#BalloonHelp()
666 if &ft != "netrw"
667 return ""
Bram Moolenaar1d59aa12020-09-19 18:50:13 +0200668 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100669 if exists("s:popuperr_id") && popup_getpos(s:popuperr_id) != {}
670 " popup error window is still showing
671 " s:pouperr_id and s:popuperr_text are set up in netrw#ErrorMsg()
672 if exists("s:popuperr_text") && s:popuperr_text != "" && v:beval_text != s:popuperr_text
673 " text under mouse hasn't changed; only close window when it changes
674 call popup_close(s:popuperr_id)
675 unlet s:popuperr_text
676 else
677 let s:popuperr_text= v:beval_text
678 endif
679 let mesg= ""
680 elseif !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
681 let mesg= ""
682 elseif v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
683 let mesg = "i: thin-long-wide-tree gh: quick hide/unhide of dot-files qf: quick file info %:open new file"
684 elseif getline(v:beval_lnum) =~ '^"\s*/'
685 let mesg = "<cr>: edit/enter o: edit/enter in horiz window t: edit/enter in new tab v:edit/enter in vert window"
686 elseif v:beval_text == "Sorted" || v:beval_text == "by"
687 let mesg = 's: sort by name, time, file size, extension r: reverse sorting order mt: mark target'
688 elseif v:beval_text == "Sort" || v:beval_text == "sequence"
689 let mesg = "S: edit sorting sequence"
690 elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
691 let mesg = "a: hiding-showing-all ctrl-h: editing hiding list mh: hide/show by suffix"
692 elseif v:beval_text == "Quick" || v:beval_text == "Help"
693 let mesg = "Help: press <F1>"
694 elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
695 let mesg = "mt: mark target mc: copy marked file to target mm: move marked file to target"
696 else
697 let mesg= ""
698 endif
699 return mesg
700 endfun
701 "else " Decho
702 " if v:version < 700 |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +0100703" if !has("balloon_eval") |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>")) |endif
704" if !has("syntax") |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>")) |endif
705" if !exists("g:syntax_on") |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>")) |endif
706" if exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>")) |endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200707endif
708
Bram Moolenaar071d4272004-06-13 20:20:40 +0000709" ------------------------------------------------------------------------
Bram Moolenaarff034192013-04-24 18:51:19 +0200710" netrw#Explore: launch the local browser in the directory of the current file {{{2
711" indx: == -1: Nexplore
712" == -2: Pexplore
713" == +: this is overloaded:
714" * If Nexplore/Pexplore is in use, then this refers to the
715" indx'th item in the w:netrw_explore_list[] of items which
716" matched the */pattern **/pattern *//pattern **//pattern
717" * If Hexplore or Vexplore, then this will override
718" g:netrw_winsize to specify the qty of rows or columns the
719" newly split window should have.
Bram Moolenaar8d043172014-01-23 14:24:41 +0100720" dosplit==0: the window will be split iff the current file has been modified and hidden not set
Bram Moolenaarff034192013-04-24 18:51:19 +0200721" dosplit==1: the window will be split before running the local browser
722" style == 0: Explore style == 1: Explore!
723" == 2: Hexplore style == 3: Hexplore!
724" == 4: Vexplore style == 5: Vexplore!
725" == 6: Texplore
726fun! netrw#Explore(indx,dosplit,style,...)
Bram Moolenaarff034192013-04-24 18:51:19 +0200727 if !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100728 let b:netrw_curdir= getcwd()
Bram Moolenaarff034192013-04-24 18:51:19 +0200729 endif
Bram Moolenaara6878372014-03-22 21:02:50 +0100730
731 " record current file for Rexplore's benefit
732 if &ft != "netrw"
Luca Saccarolac363ca12024-12-19 20:16:18 +0100733 let w:netrw_rexfile= expand("%:p")
Bram Moolenaara6878372014-03-22 21:02:50 +0100734 endif
735
736 " record current directory
Bram Moolenaarff034192013-04-24 18:51:19 +0200737 let curdir = simplify(b:netrw_curdir)
738 let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
Nir Lichtman1e34b952024-05-08 19:19:34 +0200739 if !exists("g:netrw_cygwin") && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100740 let curdir= substitute(curdir,'\','/','g')
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200741 endif
Bram Moolenaara6878372014-03-22 21:02:50 +0100742
743 " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
744 " will end up with backslashes here. Solution: strip off backslashes that precede white space and
745 " try Explore again.
746 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +0100747 if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
748 let a1 = substitute(a:1, '\\\(\s\)', '\1', 'g')
749 if a1 != a:1
750 call netrw#Explore(a:indx, a:dosplit, a:style, a1)
751 return
752 endif
Damien9d57ea52024-07-22 20:23:48 +0200753 endif
Bram Moolenaara6878372014-03-22 21:02:50 +0100754 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200755
756 " save registers
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200757 if has("clipboard") && g:netrw_clipboard
Luca Saccarolac363ca12024-12-19 20:16:18 +0100758 " call Decho("(netrw#Explore) save @* and @+",'~'.expand("<slnum>"))
759 sil! let keepregstar = @*
760 sil! let keepregplus = @+
Bram Moolenaara6878372014-03-22 21:02:50 +0100761 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200762 sil! let keepregslash= @/
763
Bram Moolenaar8d043172014-01-23 14:24:41 +0100764 " if dosplit
765 " -or- file has been modified AND file not hidden when abandoned
766 " -or- Texplore used
767 if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
Luca Saccarolac363ca12024-12-19 20:16:18 +0100768 call s:SaveWinVars()
769 let winsz= g:netrw_winsize
770 if a:indx > 0
771 let winsz= a:indx
772 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200773
Luca Saccarolac363ca12024-12-19 20:16:18 +0100774 if a:style == 0 " Explore, Sexplore
775 let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
776 if winsz == 0|let winsz= ""|endif
777 exe "noswapfile ".(g:netrw_alto ? "below " : "above ").winsz."wincmd s"
Bram Moolenaarff034192013-04-24 18:51:19 +0200778
Luca Saccarolac363ca12024-12-19 20:16:18 +0100779 elseif a:style == 1 " Explore!, Sexplore!
780 let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
781 if winsz == 0|let winsz= ""|endif
782 exe "keepalt noswapfile ".(g:netrw_altv ? "rightbelow " : "leftabove ").winsz."wincmd v"
Bram Moolenaarff034192013-04-24 18:51:19 +0200783
Luca Saccarolac363ca12024-12-19 20:16:18 +0100784 elseif a:style == 2 " Hexplore
785 let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
786 if winsz == 0|let winsz= ""|endif
787 exe "keepalt noswapfile ".(g:netrw_alto ? "below " : "above ").winsz."wincmd s"
Bram Moolenaarff034192013-04-24 18:51:19 +0200788
Luca Saccarolac363ca12024-12-19 20:16:18 +0100789 elseif a:style == 3 " Hexplore!
790 let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
791 if winsz == 0|let winsz= ""|endif
792 exe "keepalt noswapfile ".(!g:netrw_alto ? "below " : "above ").winsz."wincmd s"
Bram Moolenaarff034192013-04-24 18:51:19 +0200793
Luca Saccarolac363ca12024-12-19 20:16:18 +0100794 elseif a:style == 4 " Vexplore
795 let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
796 if winsz == 0|let winsz= ""|endif
797 exe "keepalt noswapfile ".(g:netrw_altv ? "rightbelow " : "leftabove ").winsz."wincmd v"
Bram Moolenaarff034192013-04-24 18:51:19 +0200798
Luca Saccarolac363ca12024-12-19 20:16:18 +0100799 elseif a:style == 5 " Vexplore!
800 let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
801 if winsz == 0|let winsz= ""|endif
802 exe "keepalt noswapfile ".(!g:netrw_altv ? "rightbelow " : "leftabove ").winsz."wincmd v"
Bram Moolenaarff034192013-04-24 18:51:19 +0200803
Luca Saccarolac363ca12024-12-19 20:16:18 +0100804 elseif a:style == 6 " Texplore
805 call s:SaveBufVars()
806 exe "keepalt tabnew ".fnameescape(curdir)
807 call s:RestoreBufVars()
808 endif
809 call s:RestoreWinVars()
Bram Moolenaarff034192013-04-24 18:51:19 +0200810 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100811 NetrwKeepj norm! 0
Bram Moolenaarff034192013-04-24 18:51:19 +0200812
813 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +0100814 if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
815 let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
816 elseif a:1 == '.'
817 let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
818 if dirname !~ '/$'
819 let dirname= dirname."/"
820 endif
821 elseif a:1 =~ '\$'
822 let dirname= simplify(expand(a:1))
823 elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
824 let dirname= simplify(a:1)
825 else
826 let dirname= a:1
Bram Moolenaarff034192013-04-24 18:51:19 +0200827 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200828 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100829 " clear explore
830 call s:NetrwClearExplore()
831 return
Bram Moolenaarff034192013-04-24 18:51:19 +0200832 endif
833
Bram Moolenaarff034192013-04-24 18:51:19 +0200834 if dirname =~ '\.\./\=$'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100835 let dirname= simplify(fnamemodify(dirname,':p:h'))
Bram Moolenaarff034192013-04-24 18:51:19 +0200836 elseif dirname =~ '\.\.' || dirname == '.'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100837 let dirname= simplify(fnamemodify(dirname,':p'))
Bram Moolenaarff034192013-04-24 18:51:19 +0200838 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200839
840 if dirname =~ '^\*//'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100841 " starpat=1: Explore *//pattern (current directory only search for files containing pattern)
842 let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
843 let starpat= 1
844 if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200845
846 elseif dirname =~ '^\*\*//'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100847 " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
848 let pattern= substitute(dirname,'^\*\*//','','')
849 let starpat= 2
Bram Moolenaarff034192013-04-24 18:51:19 +0200850
851 elseif dirname =~ '/\*\*/'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100852 " handle .../**/.../filepat
853 let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
854 if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && has("win32"))
855 let b:netrw_curdir = prefixdir
856 else
857 let b:netrw_curdir= getcwd().'/'.prefixdir
858 endif
859 let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
860 let starpat= 4
Bram Moolenaarff034192013-04-24 18:51:19 +0200861
862 elseif dirname =~ '^\*/'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100863 " case starpat=3: Explore */filepat (search in current directory for filenames matching filepat)
864 let starpat= 3
Bram Moolenaarff034192013-04-24 18:51:19 +0200865
866 elseif dirname=~ '^\*\*/'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100867 " starpat=4: Explore **/filepat (recursive descent search for filenames matching filepat)
868 let starpat= 4
Bram Moolenaarff034192013-04-24 18:51:19 +0200869
870 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100871 let starpat= 0
Bram Moolenaarff034192013-04-24 18:51:19 +0200872 endif
873
874 if starpat == 0 && a:indx >= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +0100875 " [Explore Hexplore Vexplore Sexplore] [dirname]
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200876 if dirname == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +0100877 let dirname= curfiledir
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200878 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100879 if dirname =~# '^scp://' || dirname =~ '^ftp://'
880 call netrw#Nread(2,dirname)
881 else
882 if dirname == ""
883 let dirname= getcwd()
884 elseif has("win32") && !g:netrw_cygwin
885 " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
886 " depending on whether backslashes have been converted to forward slashes by earlier code).
887 if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
888 let dirname= b:netrw_curdir."/".dirname
889 endif
890 elseif dirname !~ '^/'
891 let dirname= b:netrw_curdir."/".dirname
892 endif
893 call netrw#LocalBrowseCheck(dirname)
894 endif
895 if exists("w:netrw_bannercnt")
896 " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
897 " If one wants to return the same place in the netrw window, use :Rex instead.
898 exe w:netrw_bannercnt
899 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200900
Bram Moolenaarff034192013-04-24 18:51:19 +0200901
Luca Saccarolac363ca12024-12-19 20:16:18 +0100902 " starpat=1: Explore *//pattern (current directory only search for files containing pattern)
903 " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
904 " starpat=3: Explore */filepat (search in current directory for filenames matching filepat)
905 " starpat=4: Explore **/filepat (recursive descent search for filenames matching filepat)
Bram Moolenaarff034192013-04-24 18:51:19 +0200906 elseif a:indx <= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +0100907 " Nexplore, Pexplore, Explore: handle starpat
908 if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
909 let s:didstarstar= 1
910 nnoremap <buffer> <silent> <s-up> :Pexplore<cr>
911 nnoremap <buffer> <silent> <s-down> :Nexplore<cr>
Bram Moolenaarff034192013-04-24 18:51:19 +0200912 endif
913
Luca Saccarolac363ca12024-12-19 20:16:18 +0100914 if has("path_extra")
915 if !exists("w:netrw_explore_indx")
916 let w:netrw_explore_indx= 0
Bram Moolenaara6878372014-03-22 21:02:50 +0100917 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200918
Luca Saccarolac363ca12024-12-19 20:16:18 +0100919 let indx = a:indx
920
921 if indx == -1
922 " Nexplore
923 if !exists("w:netrw_explore_list") " sanity check
924 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
925 if has("clipboard") && g:netrw_clipboard
926 if @* != keepregstar | sil! let @* = keepregstar | endif
927 if @+ != keepregplus | sil! let @+ = keepregplus | endif
928 endif
929 sil! let @/ = keepregslash
930 return
931 endif
932 let indx= w:netrw_explore_indx
933 if indx < 0 | let indx= 0 | endif
934 if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
935 let curfile= w:netrw_explore_list[indx]
936 while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
937 let indx= indx + 1
938 endwhile
939 if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
940
941 elseif indx == -2
942 " Pexplore
943 if !exists("w:netrw_explore_list") " sanity check
944 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
945 if has("clipboard") && g:netrw_clipboard
946 if @* != keepregstar | sil! let @* = keepregstar | endif
947 if @+ != keepregplus | sil! let @+ = keepregplus | endif
948 endif
949 sil! let @/ = keepregslash
950 return
951 endif
952 let indx= w:netrw_explore_indx
953 if indx < 0 | let indx= 0 | endif
954 if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
955 let curfile= w:netrw_explore_list[indx]
956 while indx >= 0 && curfile == w:netrw_explore_list[indx]
957 let indx= indx - 1
958 endwhile
959 if indx < 0 | let indx= 0 | endif
960
961 else
962 " Explore -- initialize
963 " build list of files to Explore with Nexplore/Pexplore
964 NetrwKeepj keepalt call s:NetrwClearExplore()
965 let w:netrw_explore_indx= 0
966 if !exists("b:netrw_curdir")
967 let b:netrw_curdir= getcwd()
968 endif
969
970 " switch on starpat to build the w:netrw_explore_list of files
971 if starpat == 1
972 " starpat=1: Explore *//pattern (current directory only search for files containing pattern)
973 try
974 exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
975 catch /^Vim\%((\a\+)\)\=:E480/
976 keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
977 return
978 endtry
979 let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
980 if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
981
982 elseif starpat == 2
983 " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
984 try
985 exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
986 catch /^Vim\%((\a\+)\)\=:E480/
987 keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
988 if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
989 if has("clipboard") && g:netrw_clipboard
990 if @* != keepregstar | sil! let @* = keepregstar | endif
991 if @+ != keepregplus | sil! let @+ = keepregplus | endif
992 endif
993 sil! let @/ = keepregslash
994 return
995 endtry
996 let s:netrw_curdir = b:netrw_curdir
997 let w:netrw_explore_list = getqflist()
998 let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
999 if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1000
1001 elseif starpat == 3
1002 " starpat=3: Explore */filepat (search in current directory for filenames matching filepat)
1003 let filepat= substitute(dirname,'^\*/','','')
1004 let filepat= substitute(filepat,'^[%#<]','\\&','')
1005 let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
1006 if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
1007
1008 elseif starpat == 4
1009 " starpat=4: Explore **/filepat (recursive descent search for filenames matching filepat)
1010 let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
1011 if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
1012 endif " switch on starpat to build w:netrw_explore_list
1013
1014 let w:netrw_explore_listlen = len(w:netrw_explore_list)
1015
1016 if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1017 keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1018 if has("clipboard") && g:netrw_clipboard
1019 if @* != keepregstar | sil! let @* = keepregstar | endif
1020 if @+ != keepregplus | sil! let @+ = keepregplus | endif
1021 endif
1022 sil! let @/ = keepregslash
1023 return
1024 endif
1025 endif " if indx ... endif
1026
1027 " NetrwStatusLine support - for exploring support
1028 let w:netrw_explore_indx= indx
1029
1030 " wrap the indx around, but issue a note
1031 if indx >= w:netrw_explore_listlen || indx < 0
1032 let indx = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1033 let w:netrw_explore_indx= indx
1034 keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
Bram Moolenaara6878372014-03-22 21:02:50 +01001035 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001036
1037 exe "let dirfile= w:netrw_explore_list[".indx."]"
1038 let newdir= substitute(dirfile,'/[^/]*$','','e')
1039
1040 call netrw#LocalBrowseCheck(newdir)
1041 if !exists("w:netrw_liststyle")
1042 let w:netrw_liststyle= g:netrw_liststyle
1043 endif
1044 if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1045 keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1046 else
1047 keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1048 endif
1049 let w:netrw_explore_mtchcnt = indx + 1
1050 let w:netrw_explore_bufnr = bufnr("%")
1051 let w:netrw_explore_line = line(".")
1052 keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
Bram Moolenaarff034192013-04-24 18:51:19 +02001053
1054 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001055 if !exists("g:netrw_quiet")
1056 keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1057 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001058 if has("clipboard") && g:netrw_clipboard
Bram Moolenaar0c0734d2019-11-26 21:44:46 +01001059 if @* != keepregstar | sil! let @* = keepregstar | endif
1060 if @+ != keepregplus | sil! let @+ = keepregplus | endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001061 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001062 sil! let @/ = keepregslash
Bram Moolenaarff034192013-04-24 18:51:19 +02001063 return
Bram Moolenaarff034192013-04-24 18:51:19 +02001064 endif
1065
Bram Moolenaarff034192013-04-24 18:51:19 +02001066 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001067 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1068 sil! unlet w:netrw_treedict
1069 sil! unlet w:netrw_treetop
1070 endif
1071 let newdir= dirname
1072 if !exists("b:netrw_curdir")
1073 NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1074 else
1075 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir,0))
1076 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001077 endif
1078
1079 " visual display of **/ **// */ Exploration files
Bram Moolenaarff034192013-04-24 18:51:19 +02001080 if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001081 if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1082 " only update match list when current directory isn't the same as before
1083 let s:explore_prvdir = b:netrw_curdir
1084 let s:explore_match = ""
1085 let dirlen = strlen(b:netrw_curdir)
1086 if b:netrw_curdir !~ '/$'
1087 let dirlen= dirlen + 1
Bram Moolenaarff034192013-04-24 18:51:19 +02001088 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001089 let prvfname= ""
1090 for fname in w:netrw_explore_list
1091 if fname =~ '^'.b:netrw_curdir
1092 if s:explore_match == ""
1093 let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1094 else
1095 let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1096 endif
1097 elseif fname !~ '^/' && fname != prvfname
1098 if s:explore_match == ""
1099 let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1100 else
1101 let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1102 endif
1103 endif
1104 let prvfname= fname
1105 endfor
1106 if has("syntax") && exists("g:syntax_on") && g:syntax_on
1107 exe "2match netrwMarkFile /".s:explore_match."/"
Bram Moolenaarff034192013-04-24 18:51:19 +02001108 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001109 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001110 echo "<s-up>==Pexplore <s-down>==Nexplore"
Bram Moolenaarff034192013-04-24 18:51:19 +02001111 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001112 2match none
1113 if exists("s:explore_match") | unlet s:explore_match | endif
1114 if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001115 endif
1116
Bram Moolenaara6878372014-03-22 21:02:50 +01001117 " since Explore may be used to initialize netrw's browser,
1118 " there's no danger of a late FocusGained event on initialization.
1119 " Consequently, set s:netrw_events to 2.
1120 let s:netrw_events= 2
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001121 if has("clipboard") && g:netrw_clipboard
Luca Saccarolac363ca12024-12-19 20:16:18 +01001122 if @* != keepregstar | sil! let @* = keepregstar | endif
1123 if @+ != keepregplus | sil! let @+ = keepregplus | endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001124 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001125 sil! let @/ = keepregslash
Bram Moolenaarff034192013-04-24 18:51:19 +02001126endfun
1127
1128" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +01001129" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
Bram Moolenaar71badf92023-04-22 22:40:14 +01001130" Uses g:netrw_chgwin : specifies the window where Lexplore files are to be opened
1131" t:netrw_lexposn : winsaveview() output (used on Lexplore window)
1132" t:netrw_lexbufnr: the buffer number of the Lexplore buffer (internal to this function)
1133" s:lexplore_win : window number of Lexplore window (serves to indicate which window is a Lexplore window)
1134" w:lexplore_buf : buffer number of Lexplore window (serves to indicate which window is a Lexplore window)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001135fun! netrw#Lexplore(count,rightside,...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001136 " call Dfunc("netrw#Lexplore(count=".a:count." rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001137 let curwin= winnr()
1138
Bram Moolenaara6878372014-03-22 21:02:50 +01001139 if a:0 > 0 && a:1 != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01001140 " if a netrw window is already on the left-side of the tab
1141 " and a directory has been specified, explore with that
1142 " directory.
1143 let a1 = expand(a:1)
1144 exe "1wincmd w"
1145 if &ft == "netrw"
1146 exe "Explore ".fnameescape(a1)
1147 exe curwin."wincmd w"
1148 let s:lexplore_win= curwin
1149 let w:lexplore_buf= bufnr("%")
1150 if exists("t:netrw_lexposn")
1151 unlet t:netrw_lexposn
1152 endif
1153 return
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001154 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001155 exe curwin."wincmd w"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001156 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001157 let a1= ""
Bram Moolenaara6878372014-03-22 21:02:50 +01001158 endif
1159
Bram Moolenaar8d043172014-01-23 14:24:41 +01001160 if exists("t:netrw_lexbufnr")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001161 " check if t:netrw_lexbufnr refers to a netrw window
1162 let lexwinnr = bufwinnr(t:netrw_lexbufnr)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001163 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001164 let lexwinnr= 0
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001165 endif
1166
1167 if lexwinnr > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01001168 " close down netrw explorer window
1169 exe lexwinnr."wincmd w"
1170 let g:netrw_winsize = -winwidth(0)
1171 let t:netrw_lexposn = winsaveview()
1172 close
1173 if lexwinnr < curwin
1174 let curwin= curwin - 1
1175 endif
1176 if lexwinnr != curwin
1177 exe curwin."wincmd w"
1178 endif
1179 unlet t:netrw_lexbufnr
Bram Moolenaar8d043172014-01-23 14:24:41 +01001180
1181 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001182 " open netrw explorer window
1183 exe "1wincmd w"
1184 let keep_altv = g:netrw_altv
1185 let g:netrw_altv = 0
1186 if a:count != 0
1187 let netrw_winsize = g:netrw_winsize
1188 let g:netrw_winsize = a:count
1189 endif
1190 let curfile= expand("%")
1191 exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1192 if a:0 > 0 && a1 != ""
1193 call netrw#Explore(0,0,0,a1)
1194 exe "Explore ".fnameescape(a1)
1195 elseif curfile =~ '^\a\{3,}://'
1196 call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
1197 else
1198 call netrw#Explore(0,0,0,".")
1199 endif
1200 if a:count != 0
1201 let g:netrw_winsize = netrw_winsize
1202 endif
1203 setlocal winfixwidth
1204 let g:netrw_altv = keep_altv
1205 let t:netrw_lexbufnr = bufnr("%")
1206 " done to prevent build-up of hidden buffers due to quitting and re-invocation of :Lexplore.
1207 " Since the intended use of :Lexplore is to have an always-present explorer window, the extra
1208 " effort to prevent mis-use of :Lex is warranted.
1209 set bh=wipe
1210 if exists("t:netrw_lexposn")
1211 call winrestview(t:netrw_lexposn)
1212 unlet t:netrw_lexposn
1213 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +01001214 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001215
1216 " set up default window for editing via <cr>
Bram Moolenaara6878372014-03-22 21:02:50 +01001217 if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001218 if a:rightside
1219 let g:netrw_chgwin= 1
1220 else
1221 let g:netrw_chgwin= 2
1222 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001223 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001224
Bram Moolenaar8d043172014-01-23 14:24:41 +01001225endfun
1226
1227" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01001228" netrw#Clean: remove netrw {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00001229" supports :NetrwClean -- remove netrw from first directory on runtimepath
1230" :NetrwClean! -- remove netrw from all directories on runtimepath
Bram Moolenaara6878372014-03-22 21:02:50 +01001231fun! netrw#Clean(sys)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001232 " call Dfunc("netrw#Clean(sys=".a:sys.")")
Bram Moolenaar446cb832008-06-24 21:56:24 +00001233
1234 if a:sys
Luca Saccarolac363ca12024-12-19 20:16:18 +01001235 let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
Bram Moolenaar446cb832008-06-24 21:56:24 +00001236 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001237 let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
Bram Moolenaar446cb832008-06-24 21:56:24 +00001238 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001239 " call Decho("choice=".choice,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00001240 let diddel= 0
1241 let diddir= ""
1242
1243 if choice == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001244 for dir in split(&rtp,',')
1245 if filereadable(dir."/plugin/netrwPlugin.vim")
1246 " call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1247 if s:NetrwDelete(dir."/plugin/netrwPlugin.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55) |endif
1248 if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1249 if s:NetrwDelete(dir."/autoload/netrwSettings.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55) |endif
1250 if s:NetrwDelete(dir."/autoload/netrw.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55) |endif
1251 if s:NetrwDelete(dir."/syntax/netrw.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55) |endif
1252 if s:NetrwDelete(dir."/syntax/netrwlist.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55) |endif
1253 let diddir= dir
1254 let diddel= diddel + 1
1255 if !a:sys|break|endif
1256 endif
1257 endfor
Bram Moolenaar446cb832008-06-24 21:56:24 +00001258 endif
1259
Luca Saccarolac363ca12024-12-19 20:16:18 +01001260 echohl WarningMsg
Bram Moolenaar446cb832008-06-24 21:56:24 +00001261 if diddel == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01001262 echomsg "netrw is either not installed or not removable"
Bram Moolenaar446cb832008-06-24 21:56:24 +00001263 elseif diddel == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001264 echomsg "removed one copy of netrw from <".diddir.">"
Bram Moolenaar446cb832008-06-24 21:56:24 +00001265 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001266 echomsg "removed ".diddel." copies of netrw"
Bram Moolenaar446cb832008-06-24 21:56:24 +00001267 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001268 echohl None
Bram Moolenaar446cb832008-06-24 21:56:24 +00001269
Luca Saccarolac363ca12024-12-19 20:16:18 +01001270 " call Dret("netrw#Clean")
Bram Moolenaar446cb832008-06-24 21:56:24 +00001271endfun
1272
Bram Moolenaar5c736222010-01-06 20:54:52 +01001273" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01001274" netrw#MakeTgt: make a target out of the directory name provided {{{2
1275fun! netrw#MakeTgt(dname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001276 " call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1277 " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001278 let svpos = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +01001279 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01001280 let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
Luca Saccarolac363ca12024-12-19 20:16:18 +01001281 " call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01001282 if s:netrwmftgt_islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01001283 let netrwmftgt= simplify(a:dname)
Bram Moolenaara6878372014-03-22 21:02:50 +01001284 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001285 let netrwmftgt= a:dname
Bram Moolenaara6878372014-03-22 21:02:50 +01001286 endif
1287 if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
Luca Saccarolac363ca12024-12-19 20:16:18 +01001288 " re-selected target, so just clear it
1289 unlet s:netrwmftgt s:netrwmftgt_islocal
Bram Moolenaara6878372014-03-22 21:02:50 +01001290 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001291 let s:netrwmftgt= netrwmftgt
Bram Moolenaara6878372014-03-22 21:02:50 +01001292 endif
1293 if g:netrw_fastbrowse <= 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001294 call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
Bram Moolenaara6878372014-03-22 21:02:50 +01001295 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001296 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001297 call winrestview(svpos)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001298 " call Dret("netrw#MakeTgt")
Bram Moolenaar5c736222010-01-06 20:54:52 +01001299endfun
1300
Bram Moolenaara6878372014-03-22 21:02:50 +01001301" ---------------------------------------------------------------------
1302" netrw#Obtain: {{{2
1303" netrw#Obtain(islocal,fname[,tgtdirectory])
Bram Moolenaarff034192013-04-24 18:51:19 +02001304" islocal=0 obtain from remote source
1305" =1 obtain from local source
1306" fname : a filename or a list of filenames
1307" tgtdir : optional place where files are to go (not present, uses getcwd())
Bram Moolenaara6878372014-03-22 21:02:50 +01001308fun! netrw#Obtain(islocal,fname,...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001309 " call Dfunc("netrw#Obtain(islocal=".a:islocal." fname<".((type(a:fname) == 1)? a:fname : string(a:fname)).">) a:0=".a:0)
Bram Moolenaarff034192013-04-24 18:51:19 +02001310 " NetrwStatusLine support - for obtaining support
1311
1312 if type(a:fname) == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001313 let fnamelist= [ a:fname ]
Bram Moolenaarff034192013-04-24 18:51:19 +02001314 elseif type(a:fname) == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01001315 let fnamelist= a:fname
Bram Moolenaarff034192013-04-24 18:51:19 +02001316 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001317 call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1318 " call Dret("netrw#Obtain")
1319 return
Bram Moolenaarff034192013-04-24 18:51:19 +02001320 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001321 " call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
Bram Moolenaarff034192013-04-24 18:51:19 +02001322 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01001323 let tgtdir= a:1
Bram Moolenaarff034192013-04-24 18:51:19 +02001324 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001325 let tgtdir= getcwd()
Bram Moolenaarff034192013-04-24 18:51:19 +02001326 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001327 " call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
Bram Moolenaarff034192013-04-24 18:51:19 +02001328
1329 if exists("b:netrw_islocal") && b:netrw_islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01001330 " obtain a file from local b:netrw_curdir to (local) tgtdir
1331 " call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1332 if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1333 let topath= s:ComposePath(tgtdir,"")
1334 if has("win32")
1335 " transfer files one at time
1336 " call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1337 for fname in fnamelist
1338 " call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1339 call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1340 if v:shell_error != 0
1341 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1342 " call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1343 return
1344 endif
1345 endfor
1346 else
1347 " transfer files with one command
1348 " call Decho("transfer files with one command",'~'.expand("<slnum>"))
1349 let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1350 " call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1351 call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".filelist." ".s:ShellEscape(topath))
1352 if v:shell_error != 0
1353 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1354 " call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1355 return
1356 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001357 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001358 elseif !exists("b:netrw_curdir")
1359 call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
Bram Moolenaarff034192013-04-24 18:51:19 +02001360 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001361 call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
Bram Moolenaarff034192013-04-24 18:51:19 +02001362 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001363
1364 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001365 " obtain files from remote b:netrw_curdir to local tgtdir
1366 " call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1367 if type(a:fname) == 1
1368 call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
Bram Moolenaarff034192013-04-24 18:51:19 +02001369 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001370 call s:NetrwMethod(b:netrw_curdir)
Bram Moolenaarff034192013-04-24 18:51:19 +02001371
Luca Saccarolac363ca12024-12-19 20:16:18 +01001372 if b:netrw_method == 4
1373 " obtain file using scp
1374 " call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1375 if exists("g:netrw_port") && g:netrw_port != ""
1376 let useport= " ".g:netrw_scpport." ".g:netrw_port
1377 else
1378 let useport= ""
Bram Moolenaarff034192013-04-24 18:51:19 +02001379 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001380 if b:netrw_fname =~ '/'
1381 let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1382 else
1383 let path= ""
1384 endif
1385 let filelist= join(map(deepcopy(fnamelist),'escape(s:ShellEscape(g:netrw_machine.":".path.v:val,1)," ")'))
1386 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".filelist." ".s:ShellEscape(tgtdir,1))
Bram Moolenaarff034192013-04-24 18:51:19 +02001387
Luca Saccarolac363ca12024-12-19 20:16:18 +01001388 elseif b:netrw_method == 2
1389 " obtain file using ftp + .netrc
1390 " call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1391 call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1392 let tmpbufnr= bufnr("%")
1393 setl ff=unix
1394 if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1395 NetrwKeepj put =g:netrw_ftpmode
1396 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1397 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001398
Luca Saccarolac363ca12024-12-19 20:16:18 +01001399 if exists("b:netrw_fname") && b:netrw_fname != ""
1400 call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1401 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1402 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001403
Luca Saccarolac363ca12024-12-19 20:16:18 +01001404 if exists("g:netrw_ftpextracmd")
1405 NetrwKeepj put =g:netrw_ftpextracmd
1406 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1407 endif
1408 for fname in fnamelist
1409 call setline(line("$")+1,'get "'.fname.'"')
1410 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1411 endfor
1412 if exists("g:netrw_port") && g:netrw_port != ""
1413 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1414 else
1415 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1416 endif
1417 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1418 if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1419 let debugkeep= &debug
1420 setl debug=msg
1421 call netrw#ErrorMsg(s:ERROR,getline(1),4)
1422 let &debug= debugkeep
1423 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001424
Luca Saccarolac363ca12024-12-19 20:16:18 +01001425 elseif b:netrw_method == 3
1426 " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1427 " call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1428 call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1429 let tmpbufnr= bufnr("%")
1430 setl ff=unix
Bram Moolenaarff034192013-04-24 18:51:19 +02001431
Luca Saccarolac363ca12024-12-19 20:16:18 +01001432 if exists("g:netrw_port") && g:netrw_port != ""
1433 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
1434 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1435 else
1436 NetrwKeepj put ='open '.g:netrw_machine
1437 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1438 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02001439
Luca Saccarolac363ca12024-12-19 20:16:18 +01001440 if exists("g:netrw_uid") && g:netrw_uid != ""
1441 if exists("g:netrw_ftp") && g:netrw_ftp == 1
1442 NetrwKeepj put =g:netrw_uid
1443 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1444 if exists("s:netrw_passwd") && s:netrw_passwd != ""
1445 NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1446 endif
1447 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1448 elseif exists("s:netrw_passwd")
1449 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1450 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1451 endif
1452 endif
1453
1454 if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1455 NetrwKeepj put =g:netrw_ftpmode
1456 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1457 endif
1458
1459 if exists("b:netrw_fname") && b:netrw_fname != ""
1460 NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1461 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1462 endif
1463
1464 if exists("g:netrw_ftpextracmd")
1465 NetrwKeepj put =g:netrw_ftpextracmd
1466 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1467 endif
1468
1469 if exists("g:netrw_ftpextracmd")
1470 NetrwKeepj put =g:netrw_ftpextracmd
1471 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1472 endif
1473 for fname in fnamelist
1474 NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1475 endfor
1476 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1477
1478 " perform ftp:
1479 " -i : turns off interactive prompting from ftp
1480 " -n unix : DON'T use <.netrc>, even though it exists
1481 " -n win32: quit being obnoxious about password
1482 " Note: using "_dd to delete to the black hole register; avoids messing up @@
1483 NetrwKeepj norm! 1G"_dd
1484 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1485 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1486 if getline(1) !~ "^$"
1487 " call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1488 if !exists("g:netrw_quiet")
1489 NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1490 endif
1491 endif
1492
1493 elseif b:netrw_method == 9
1494 " obtain file using sftp
1495 " call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1496 if a:fname =~ '/'
1497 let localfile= substitute(a:fname,'^.*/','','')
1498 else
1499 let localfile= a:fname
1500 endif
1501 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1).s:ShellEscape(localfile)." ".s:ShellEscape(tgtdir))
1502
1503 elseif !exists("b:netrw_method") || b:netrw_method < 0
1504 " probably a badly formed url; protocol not recognized
1505 " call Dret("netrw#Obtain : unsupported method")
1506 return
1507
Bram Moolenaar13600302014-05-22 18:26:40 +02001508 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001509 " protocol recognized but not supported for Obtain (yet?)
1510 if !exists("g:netrw_quiet")
1511 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1512 endif
1513 " call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1514 return
Bram Moolenaar13600302014-05-22 18:26:40 +02001515 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02001516
Luca Saccarolac363ca12024-12-19 20:16:18 +01001517 " restore status line
1518 if type(a:fname) == 1 && exists("s:netrw_users_stl")
1519 NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
Bram Moolenaar13600302014-05-22 18:26:40 +02001520 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001521
1522 endif
1523
1524 " cleanup
1525 if exists("tmpbufnr")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001526 if bufnr("%") != tmpbufnr
1527 exe tmpbufnr."bw!"
1528 else
1529 q!
1530 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001531 endif
1532
Luca Saccarolac363ca12024-12-19 20:16:18 +01001533 " call Dret("netrw#Obtain")
Bram Moolenaara6878372014-03-22 21:02:50 +01001534endfun
1535
1536" ---------------------------------------------------------------------
1537" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1538fun! netrw#Nread(mode,fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001539 " call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001540 let svpos= winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +01001541 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01001542 call netrw#NetRead(a:mode,a:fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001543 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001544 call winrestview(svpos)
Bram Moolenaara6878372014-03-22 21:02:50 +01001545
1546 if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01001547 if exists("w:netrw_bannercnt")
1548 " start with cursor just after the banner
1549 exe w:netrw_bannercnt
1550 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001551 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001552 " call Dret("netrw#Nread")
Bram Moolenaara6878372014-03-22 21:02:50 +01001553endfun
1554
1555" ------------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02001556" s:NetrwOptionsSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1557" Options get restored by s:NetrwOptionsRestore()
1558"
1559" Option handling:
1560" * save user's options (s:NetrwOptionsSave)
1561" * set netrw-safe options (s:NetrwOptionsSafe)
1562" - change an option only when user option != safe option (s:netrwSetSafeSetting)
1563" * restore user's options (s:netrwOPtionsRestore)
1564" - restore a user option when != safe option (s:NetrwRestoreSetting)
1565" vt: (variable type) normally its either "w:" or "s:"
1566fun! s:NetrwOptionsSave(vt)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001567 " call Dfunc("s:NetrwOptionsSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1568 " call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1569 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt." hid=".&hid,'~'.expand("<slnum>"))
1570 " call Decho("(s:NetrwOptionsSave) lines=".&lines)
Bram Moolenaar85850f32019-07-19 22:05:51 +02001571
1572 if !exists("{a:vt}netrw_optionsave")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001573 let {a:vt}netrw_optionsave= 1
Bram Moolenaar85850f32019-07-19 22:05:51 +02001574 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001575 " call Dret("s:NetrwOptionsSave : options already saved")
1576 return
Bram Moolenaar85850f32019-07-19 22:05:51 +02001577 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001578 " call Decho("prior to save: fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." diff=".&l:diff,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001579
1580 " Save current settings and current directory
Luca Saccarolac363ca12024-12-19 20:16:18 +01001581 " call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001582 let s:yykeep = @@
1583 if exists("&l:acd")|let {a:vt}netrw_acdkeep = &l:acd|endif
1584 let {a:vt}netrw_aikeep = &l:ai
1585 let {a:vt}netrw_awkeep = &l:aw
1586 let {a:vt}netrw_bhkeep = &l:bh
1587 let {a:vt}netrw_blkeep = &l:bl
1588 let {a:vt}netrw_btkeep = &l:bt
1589 let {a:vt}netrw_bombkeep = &l:bomb
1590 let {a:vt}netrw_cedit = &cedit
1591 let {a:vt}netrw_cikeep = &l:ci
1592 let {a:vt}netrw_cinkeep = &l:cin
1593 let {a:vt}netrw_cinokeep = &l:cino
1594 let {a:vt}netrw_comkeep = &l:com
1595 let {a:vt}netrw_cpokeep = &l:cpo
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001596 let {a:vt}netrw_cuckeep = &l:cuc
1597 let {a:vt}netrw_culkeep = &l:cul
Luca Saccarolac363ca12024-12-19 20:16:18 +01001598 " call Decho("(s:NetrwOptionsSave) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
Bram Moolenaar85850f32019-07-19 22:05:51 +02001599 let {a:vt}netrw_diffkeep = &l:diff
1600 let {a:vt}netrw_fenkeep = &l:fen
Bram Moolenaar85850f32019-07-19 22:05:51 +02001601 if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01001602 let {a:vt}netrw_ffkeep = &l:ff
Bram Moolenaar85850f32019-07-19 22:05:51 +02001603 endif
1604 let {a:vt}netrw_fokeep = &l:fo " formatoptions
1605 let {a:vt}netrw_gdkeep = &l:gd " gdefault
Bram Moolenaar71badf92023-04-22 22:40:14 +01001606 let {a:vt}netrw_gokeep = &go " guioptions
Bram Moolenaar85850f32019-07-19 22:05:51 +02001607 let {a:vt}netrw_hidkeep = &l:hidden
1608 let {a:vt}netrw_imkeep = &l:im
1609 let {a:vt}netrw_iskkeep = &l:isk
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001610 let {a:vt}netrw_lines = &lines
Bram Moolenaar85850f32019-07-19 22:05:51 +02001611 let {a:vt}netrw_lskeep = &l:ls
1612 let {a:vt}netrw_makeep = &l:ma
1613 let {a:vt}netrw_magickeep = &l:magic
1614 let {a:vt}netrw_modkeep = &l:mod
1615 let {a:vt}netrw_nukeep = &l:nu
1616 let {a:vt}netrw_rnukeep = &l:rnu
1617 let {a:vt}netrw_repkeep = &l:report
1618 let {a:vt}netrw_rokeep = &l:ro
1619 let {a:vt}netrw_selkeep = &l:sel
1620 let {a:vt}netrw_spellkeep = &l:spell
Bram Moolenaar85850f32019-07-19 22:05:51 +02001621 if !g:netrw_use_noswf
Luca Saccarolac363ca12024-12-19 20:16:18 +01001622 let {a:vt}netrw_swfkeep = &l:swf
Bram Moolenaar85850f32019-07-19 22:05:51 +02001623 endif
1624 let {a:vt}netrw_tskeep = &l:ts
1625 let {a:vt}netrw_twkeep = &l:tw " textwidth
1626 let {a:vt}netrw_wigkeep = &l:wig " wildignore
1627 let {a:vt}netrw_wrapkeep = &l:wrap
1628 let {a:vt}netrw_writekeep = &l:write
1629
1630 " save a few selected netrw-related variables
Luca Saccarolac363ca12024-12-19 20:16:18 +01001631 " call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001632 if g:netrw_keepdir
Luca Saccarolac363ca12024-12-19 20:16:18 +01001633 let {a:vt}netrw_dirkeep = getcwd()
1634 " call Decho("saving to ".a:vt."netrw_dirkeep<".{a:vt}netrw_dirkeep.">",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001635 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001636 if has("clipboard") && g:netrw_clipboard
Luca Saccarolac363ca12024-12-19 20:16:18 +01001637 sil! let {a:vt}netrw_starkeep = @*
1638 sil! let {a:vt}netrw_pluskeep = @+
Bram Moolenaar85850f32019-07-19 22:05:51 +02001639 endif
1640 sil! let {a:vt}netrw_slashkeep= @/
1641
Luca Saccarolac363ca12024-12-19 20:16:18 +01001642 " call Decho("(s:NetrwOptionsSave) lines=".&lines)
1643 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." a:vt=".a:vt,'~'.expand("<slnum>"))
1644 " call Dret("s:NetrwOptionsSave : tab#".tabpagenr()." win#".winnr())
Bram Moolenaar85850f32019-07-19 22:05:51 +02001645endfun
1646
1647" ---------------------------------------------------------------------
1648" s:NetrwOptionsSafe: sets options to help netrw do its job {{{2
1649" Use s:NetrwSaveOptions() to save user settings
1650" Use s:NetrwOptionsRestore() to restore user settings
1651fun! s:NetrwOptionsSafe(islocal)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001652 " call Dfunc("s:NetrwOptionsSafe(islocal=".a:islocal.") win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1653 " call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1654 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001655 if exists("+acd") | call s:NetrwSetSafeSetting("&l:acd",0)|endif
1656 call s:NetrwSetSafeSetting("&l:ai",0)
1657 call s:NetrwSetSafeSetting("&l:aw",0)
1658 call s:NetrwSetSafeSetting("&l:bl",0)
1659 call s:NetrwSetSafeSetting("&l:bomb",0)
1660 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01001661 call s:NetrwSetSafeSetting("&l:bt","nofile")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001662 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001663 call s:NetrwSetSafeSetting("&l:bt","acwrite")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001664 endif
1665 call s:NetrwSetSafeSetting("&l:ci",0)
1666 call s:NetrwSetSafeSetting("&l:cin",0)
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001667 if g:netrw_fastbrowse > a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01001668 call s:NetrwSetSafeSetting("&l:bh","hide")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001669 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001670 call s:NetrwSetSafeSetting("&l:bh","delete")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001671 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001672 call s:NetrwSetSafeSetting("&l:cino","")
1673 call s:NetrwSetSafeSetting("&l:com","")
1674 if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif
1675 if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif
1676 setl fo=nroql2
Bram Moolenaar71badf92023-04-22 22:40:14 +01001677 if &go =~ 'a' | set go-=a | endif
1678 if &go =~ 'A' | set go-=A | endif
1679 if &go =~ 'P' | set go-=P | endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001680 call s:NetrwSetSafeSetting("&l:hid",0)
1681 call s:NetrwSetSafeSetting("&l:im",0)
1682 setl isk+=@ isk+=* isk+=/
1683 call s:NetrwSetSafeSetting("&l:magic",1)
1684 if g:netrw_use_noswf
Luca Saccarolac363ca12024-12-19 20:16:18 +01001685 call s:NetrwSetSafeSetting("swf",0)
Bram Moolenaar85850f32019-07-19 22:05:51 +02001686 endif
1687 call s:NetrwSetSafeSetting("&l:report",10000)
1688 call s:NetrwSetSafeSetting("&l:sel","inclusive")
1689 call s:NetrwSetSafeSetting("&l:spell",0)
1690 call s:NetrwSetSafeSetting("&l:tw",0)
1691 call s:NetrwSetSafeSetting("&l:wig","")
1692 setl cedit&
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001693
1694 " set up cuc and cul based on g:netrw_cursor and listing style
1695 " COMBAK -- cuc cul related
1696 call s:NetrwCursor(0)
Bram Moolenaar85850f32019-07-19 22:05:51 +02001697
1698 " allow the user to override safe options
Luca Saccarolac363ca12024-12-19 20:16:18 +01001699 " call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001700 if &ft == "netrw"
Luca Saccarolac363ca12024-12-19 20:16:18 +01001701 " call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1702 keepalt NetrwKeepj doau FileType netrw
Bram Moolenaar85850f32019-07-19 22:05:51 +02001703 endif
1704
Luca Saccarolac363ca12024-12-19 20:16:18 +01001705 " call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1706 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
1707 " call Dret("s:NetrwOptionsSafe")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001708endfun
1709
1710" ---------------------------------------------------------------------
1711" s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2
1712fun! s:NetrwOptionsRestore(vt)
Bram Moolenaara6878372014-03-22 21:02:50 +01001713 if !exists("{a:vt}netrw_optionsave")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001714 " filereadable() returns zero for remote files (e.g. scp://user@localhost//etc/fstab)
1715 " Note: @ may not be in 'isfname', so '^\w\+://\f\+/' may not match
1716 if filereadable(expand("%")) || expand("%") =~# '^\w\+://\f\+'
1717 filetype detect
1718 else
1719 setl ft=netrw
1720 endif
1721 return
Bram Moolenaara6878372014-03-22 21:02:50 +01001722 endif
1723 unlet {a:vt}netrw_optionsave
1724
1725 if exists("+acd")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001726 if exists("{a:vt}netrw_acdkeep")
1727 let curdir = getcwd()
1728 let &l:acd = {a:vt}netrw_acdkeep
1729 unlet {a:vt}netrw_acdkeep
1730 if &l:acd
1731 call s:NetrwLcd(curdir)
1732 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001733 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001734 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001735 call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai")
1736 call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw")
1737 call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl")
1738 call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt")
1739 call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb")
1740 call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit")
1741 call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci")
1742 call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin")
1743 call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino")
1744 call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com")
1745 call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo")
1746 call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff")
1747 call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen")
1748 if exists("g:netrw_ffkeep") && g:netrw_ffkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01001749 call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001750 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001751 call s:NetrwRestoreSetting(a:vt."netrw_fokeep" ,"&l:fo")
1752 call s:NetrwRestoreSetting(a:vt."netrw_gdkeep" ,"&l:gd")
Bram Moolenaar71badf92023-04-22 22:40:14 +01001753 call s:NetrwRestoreSetting(a:vt."netrw_gokeep" ,"&go")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001754 call s:NetrwRestoreSetting(a:vt."netrw_hidkeep" ,"&l:hidden")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001755 call s:NetrwRestoreSetting(a:vt."netrw_imkeep" ,"&l:im")
1756 call s:NetrwRestoreSetting(a:vt."netrw_iskkeep" ,"&l:isk")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001757 call s:NetrwRestoreSetting(a:vt."netrw_lines" ,"&lines")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001758 call s:NetrwRestoreSetting(a:vt."netrw_lskeep" ,"&l:ls")
1759 call s:NetrwRestoreSetting(a:vt."netrw_makeep" ,"&l:ma")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001760 call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001761 call s:NetrwRestoreSetting(a:vt."netrw_modkeep" ,"&l:mod")
1762 call s:NetrwRestoreSetting(a:vt."netrw_nukeep" ,"&l:nu")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001763 call s:NetrwRestoreSetting(a:vt."netrw_rnukeep" ,"&l:rnu")
1764 call s:NetrwRestoreSetting(a:vt."netrw_repkeep" ,"&l:report")
1765 call s:NetrwRestoreSetting(a:vt."netrw_rokeep" ,"&l:ro")
1766 call s:NetrwRestoreSetting(a:vt."netrw_selkeep" ,"&l:sel")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001767 call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001768 call s:NetrwRestoreSetting(a:vt."netrw_twkeep" ,"&l:tw")
1769 call s:NetrwRestoreSetting(a:vt."netrw_wigkeep" ,"&l:wig")
1770 call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep" ,"&l:wrap")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001771 call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write")
1772 call s:NetrwRestoreSetting("s:yykeep","@@")
1773 " former problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1774 " Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces
1775 " rather than by appending a tab which previously was using "&ts" to set the desired spacing. (Sep 28, 2018)
1776 call s:NetrwRestoreSetting(a:vt."netrw_tskeep","&l:ts")
1777
Bram Moolenaara6878372014-03-22 21:02:50 +01001778 if exists("{a:vt}netrw_swfkeep")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001779 if &directory == ""
1780 " user hasn't specified a swapfile directory;
1781 " netrw will temporarily set the swapfile directory
1782 " to the current directory as returned by getcwd().
1783 let &l:directory= getcwd()
1784 sil! let &l:swf = {a:vt}netrw_swfkeep
1785 setl directory=
1786 unlet {a:vt}netrw_swfkeep
1787 elseif &l:swf != {a:vt}netrw_swfkeep
1788 if !g:netrw_use_noswf
1789 " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1790 sil! let &l:swf= {a:vt}netrw_swfkeep
1791 endif
1792 unlet {a:vt}netrw_swfkeep
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001793 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001794 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01001795 if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
Luca Saccarolac363ca12024-12-19 20:16:18 +01001796 let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1797 if exists("{a:vt}netrw_dirkeep")
1798 call s:NetrwLcd(dirkeep)
1799 unlet {a:vt}netrw_dirkeep
1800 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001801 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001802 if has("clipboard") && g:netrw_clipboard
Luca Saccarolac363ca12024-12-19 20:16:18 +01001803 call s:NetrwRestoreSetting(a:vt."netrw_starkeep","@*")
1804 call s:NetrwRestoreSetting(a:vt."netrw_pluskeep","@+")
Bram Moolenaara6878372014-03-22 21:02:50 +01001805 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001806 call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/")
Bram Moolenaara6878372014-03-22 21:02:50 +01001807
Bram Moolenaara6878372014-03-22 21:02:50 +01001808 " Moved the filetype detect here from NetrwGetFile() because remote files
1809 " were having their filetype detect-generated settings overwritten by
1810 " NetrwOptionRestore.
1811 if &ft != "netrw"
Luca Saccarolac363ca12024-12-19 20:16:18 +01001812 filetype detect
Bram Moolenaara6878372014-03-22 21:02:50 +01001813 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001814endfun
1815
1816" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02001817" s:NetrwSetSafeSetting: sets an option to a safe setting {{{2
1818" but only when the options' value and the safe setting differ
1819" Doing this means that netrw will not come up as having changed a
1820" setting last when it really didn't actually change it.
1821"
1822" Called from s:NetrwOptionsSafe
1823" ex. call s:NetrwSetSafeSetting("&l:sel","inclusive")
1824fun! s:NetrwSetSafeSetting(setting,safesetting)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001825 " call Dfunc("s:NetrwSetSafeSetting(setting<".a:setting."> safesetting<".a:safesetting.">)")
Bram Moolenaara6878372014-03-22 21:02:50 +01001826
Bram Moolenaar85850f32019-07-19 22:05:51 +02001827 if a:setting =~ '^&'
Luca Saccarolac363ca12024-12-19 20:16:18 +01001828 " call Decho("fyi: a:setting starts with &")
1829 exe "let settingval= ".a:setting
1830 " call Decho("fyi: settingval<".settingval.">")
Bram Moolenaara6878372014-03-22 21:02:50 +01001831
Luca Saccarolac363ca12024-12-19 20:16:18 +01001832 if settingval != a:safesetting
1833 " call Decho("set setting<".a:setting."> to option value<".a:safesetting.">")
1834 if type(a:safesetting) == 0
1835 exe "let ".a:setting."=".a:safesetting
1836 elseif type(a:safesetting) == 1
1837 exe "let ".a:setting."= '".a:safesetting."'"
1838 else
1839 call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:setting." with a safesetting of type#".type(a:safesetting),105)
1840 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001841 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02001842 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001843
Luca Saccarolac363ca12024-12-19 20:16:18 +01001844 " call Dret("s:NetrwSetSafeSetting")
Bram Moolenaara6878372014-03-22 21:02:50 +01001845endfun
1846
1847" ------------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02001848" s:NetrwRestoreSetting: restores specified setting using associated keepvar, {{{2
1849" but only if the setting value differs from the associated keepvar.
1850" Doing this means that netrw will not come up as having changed a
1851" setting last when it really didn't actually change it.
1852"
Viktor Szépedbf749b2023-10-16 09:53:37 +02001853" Used by s:NetrwOptionsRestore() to restore each netrw-sensitive setting
Bram Moolenaar85850f32019-07-19 22:05:51 +02001854" keepvars are set up by s:NetrwOptionsSave
1855fun! s:NetrwRestoreSetting(keepvar,setting)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001856 """ call Dfunc("s:NetrwRestoreSetting(a:keepvar<".a:keepvar."> a:setting<".a:setting.">)")
Bram Moolenaara6878372014-03-22 21:02:50 +01001857
Bram Moolenaar85850f32019-07-19 22:05:51 +02001858 " typically called from s:NetrwOptionsRestore
1859 " call s:NetrwRestoreSettings(keep-option-variable-name,'associated-option')
1860 " ex. call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001861 " Restores option (but only if different) from a:keepvar
Bram Moolenaar85850f32019-07-19 22:05:51 +02001862 if exists(a:keepvar)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001863 exe "let keepvarval= ".a:keepvar
1864 exe "let setting= ".a:setting
Bram Moolenaar85850f32019-07-19 22:05:51 +02001865
Luca Saccarolac363ca12024-12-19 20:16:18 +01001866 "" call Decho("fyi: a:keepvar<".a:keepvar."> exists")
1867 "" call Decho("fyi: keepvarval=".keepvarval)
1868 "" call Decho("fyi: a:setting<".a:setting."> setting<".setting.">")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001869
Luca Saccarolac363ca12024-12-19 20:16:18 +01001870 if setting != keepvarval
1871 "" call Decho("restore setting<".a:setting."> (currently=".setting.") to keepvarval<".keepvarval.">")
1872 if type(a:setting) == 0
1873 exe "let ".a:setting."= ".keepvarval
1874 elseif type(a:setting) == 1
1875 exe "let ".a:setting."= '".substitute(keepvarval,"'","''","g")."'"
1876 else
1877 call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105)
1878 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001879 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001880
Luca Saccarolac363ca12024-12-19 20:16:18 +01001881 exe "unlet ".a:keepvar
Bram Moolenaara6878372014-03-22 21:02:50 +01001882 endif
1883
Luca Saccarolac363ca12024-12-19 20:16:18 +01001884 "" call Dret("s:NetrwRestoreSetting")
Bram Moolenaarff034192013-04-24 18:51:19 +02001885endfun
1886
1887" ---------------------------------------------------------------------
1888" NetrwStatusLine: {{{2
1889fun! NetrwStatusLine()
1890
Luca Saccarolac363ca12024-12-19 20:16:18 +01001891 " vvv NetrwStatusLine() debugging vvv
1892 " let g:stlmsg=""
1893 " if !exists("w:netrw_explore_bufnr")
1894 " let g:stlmsg="!X<explore_bufnr>"
1895 " elseif w:netrw_explore_bufnr != bufnr("%")
1896 " let g:stlmsg="explore_bufnr!=".bufnr("%")
1897 " endif
1898 " if !exists("w:netrw_explore_line")
1899 " let g:stlmsg=" !X<explore_line>"
1900 " elseif w:netrw_explore_line != line(".")
1901 " let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1902 " endif
1903 " if !exists("w:netrw_explore_list")
1904 " let g:stlmsg=" !X<explore_list>"
1905 " endif
1906 " ^^^ NetrwStatusLine() debugging ^^^
Bram Moolenaarff034192013-04-24 18:51:19 +02001907
1908 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")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001909 " restore user's status line
1910 let &l:stl = s:netrw_users_stl
1911 let &laststatus = s:netrw_users_ls
1912 if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1913 if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1914 return ""
Bram Moolenaarff034192013-04-24 18:51:19 +02001915 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001916 return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
Bram Moolenaarff034192013-04-24 18:51:19 +02001917 endif
1918endfun
1919
Bram Moolenaar85850f32019-07-19 22:05:51 +02001920" ===============================
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +00001921" Netrw Transfer Functions: {{{1
1922" ===============================
1923
Bram Moolenaar071d4272004-06-13 20:20:40 +00001924" ------------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00001925" netrw#NetRead: responsible for reading a file over the net {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +00001926" mode: =0 read remote file and insert before current line
1927" =1 read remote file and insert after current line
1928" =2 replace with remote file
1929" =3 obtain file, but leave in temporary format
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001930fun! netrw#NetRead(mode,...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001931 " call Dfunc("netrw#NetRead(mode=".a:mode.",...) a:0=".a:0." ".g:loaded_netrw.((a:0 > 0)? " a:1<".a:1.">" : ""))
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001932
Bram Moolenaar5c736222010-01-06 20:54:52 +01001933 " NetRead: save options {{{3
Bram Moolenaar85850f32019-07-19 22:05:51 +02001934 call s:NetrwOptionsSave("w:")
1935 call s:NetrwOptionsSafe(0)
Bram Moolenaar00a927d2010-05-14 23:24:24 +02001936 call s:RestoreCursorline()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001937 " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
1938 " However, this setting is not wanted for a remote editing session. The buffer should be "nofile", still.
1939 setl bl
Luca Saccarolac363ca12024-12-19 20:16:18 +01001940 " call Decho("buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001941
Bram Moolenaar5c736222010-01-06 20:54:52 +01001942 " NetRead: interpret mode into a readcmd {{{3
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001943 if a:mode == 0 " read remote file before current line
Luca Saccarolac363ca12024-12-19 20:16:18 +01001944 let readcmd = "0r"
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001945 elseif a:mode == 1 " read file after current line
Luca Saccarolac363ca12024-12-19 20:16:18 +01001946 let readcmd = "r"
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001947 elseif a:mode == 2 " replace with remote file
Luca Saccarolac363ca12024-12-19 20:16:18 +01001948 let readcmd = "%r"
Bram Moolenaar9964e462007-05-05 17:54:07 +00001949 elseif a:mode == 3 " skip read of file (leave as temporary)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001950 let readcmd = "t"
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001951 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001952 exe a:mode
1953 let readcmd = "r"
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00001954 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001955 let ichoice = (a:0 == 0)? 0 : 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001956 " call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001957
Bram Moolenaar5c736222010-01-06 20:54:52 +01001958 " NetRead: get temporary filename {{{3
Bram Moolenaar9964e462007-05-05 17:54:07 +00001959 let tmpfile= s:GetTempfile("")
1960 if tmpfile == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01001961 " call Dret("netrw#NetRead : unable to get a tempfile!")
1962 return
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +00001963 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001964
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00001965 while ichoice <= a:0
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001966
Luca Saccarolac363ca12024-12-19 20:16:18 +01001967 " attempt to repeat with previous host-file-etc
1968 if exists("b:netrw_lastfile") && a:0 == 0
1969 " call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
1970 let choice = b:netrw_lastfile
1971 let ichoice= ichoice + 1
1972
1973 else
1974 exe "let choice= a:" . ichoice
1975 " call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
1976
1977 if match(choice,"?") == 0
1978 " give help
1979 echomsg 'NetRead Usage:'
1980 echomsg ':Nread machine:path uses rcp'
1981 echomsg ':Nread "machine path" uses ftp with <.netrc>'
1982 echomsg ':Nread "machine id password path" uses ftp'
1983 echomsg ':Nread dav://machine[:port]/path uses cadaver'
1984 echomsg ':Nread fetch://machine/path uses fetch'
1985 echomsg ':Nread ftp://[user@]machine[:port]/path uses ftp autodetects <.netrc>'
1986 echomsg ':Nread http://[user@]machine/path uses http wget'
1987 echomsg ':Nread file:///path uses elinks'
1988 echomsg ':Nread https://[user@]machine/path uses http wget'
1989 echomsg ':Nread rcp://[user@]machine/path uses rcp'
1990 echomsg ':Nread rsync://machine[:port]/path uses rsync'
1991 echomsg ':Nread scp://[user@]machine[[:#]port]/path uses scp'
1992 echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
1993 sleep 4
1994 break
1995
1996 elseif match(choice,'^"') != -1
1997 " Reconstruct Choice if choice starts with '"'
1998 " call Decho("reconstructing choice",'~'.expand("<slnum>"))
1999 if match(choice,'"$') != -1
2000 " case "..."
2001 let choice= strpart(choice,1,strlen(choice)-2)
2002 else
2003 " case "... ... ..."
2004 let choice = strpart(choice,1,strlen(choice)-1)
2005 let wholechoice = ""
2006
2007 while match(choice,'"$') == -1
2008 let wholechoice = wholechoice . " " . choice
2009 let ichoice = ichoice + 1
2010 if ichoice > a:0
2011 if !exists("g:netrw_quiet")
2012 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
2013 endif
2014 " call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
2015 return
2016 endif
2017 let choice= a:{ichoice}
2018 endwhile
2019 let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2020 endif
2021 endif
2022 endif
2023
2024 " call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002025 let ichoice= ichoice + 1
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002026
Luca Saccarolac363ca12024-12-19 20:16:18 +01002027 " NetRead: Determine method of read (ftp, rcp, etc) {{{3
2028 call s:NetrwMethod(choice)
2029 if !exists("b:netrw_method") || b:netrw_method < 0
2030 " call Dret("netrw#NetRead : unsupported method")
2031 return
2032 endif
2033 let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002034
Luca Saccarolac363ca12024-12-19 20:16:18 +01002035 " Check whether or not NetrwBrowse() should be handling this request
2036 " call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
2037 if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
2038 " call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
2039 NetrwKeepj call s:NetrwBrowse(0,choice)
2040 " call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
2041 return
2042 endif
Bram Moolenaard4755bb2004-09-02 19:12:26 +00002043
Luca Saccarolac363ca12024-12-19 20:16:18 +01002044 " ============
2045 " NetRead: Perform Protocol-Based Read {{{3
2046 " ===========================
2047 if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2048 echo "(netrw) Processing your read request..."
2049 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002050
Luca Saccarolac363ca12024-12-19 20:16:18 +01002051 ".........................................
2052 " NetRead: (rcp) NetRead Method #1 {{{3
2053 if b:netrw_method == 1 " read with rcp
2054 " call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
2055 " ER: nothing done with g:netrw_uid yet?
2056 " ER: on Win2K" rcp machine[.user]:file tmpfile
2057 " ER: when machine contains '.' adding .user is required (use $USERNAME)
2058 " ER: the tmpfile is full path: rcp sees C:\... as host C
2059 if s:netrw_has_nt_rcp == 1
2060 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2061 let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2062 else
2063 " Any way needed it machine contains a '.'
2064 let uid_machine = g:netrw_machine .'.'. $USERNAME
K.Takata71d0ba02024-01-10 03:21:05 +09002065 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01002066 else
2067 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2068 let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2069 else
2070 let uid_machine = g:netrw_machine
2071 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +02002072 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01002073 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".s:ShellEscape(uid_machine.":".b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2074 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2075 let b:netrw_lastfile = choice
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002076
Luca Saccarolac363ca12024-12-19 20:16:18 +01002077 ".........................................
2078 " NetRead: (ftp + <.netrc>) NetRead Method #2 {{{3
2079 elseif b:netrw_method == 2 " read with ftp + <.netrc>
2080 " call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2081 let netrw_fname= b:netrw_fname
2082 NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2083 let filtbuf= bufnr("%")
2084 setl ff=unix
2085 NetrwKeepj put =g:netrw_ftpmode
2086 " call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2087 if exists("g:netrw_ftpextracmd")
2088 NetrwKeepj put =g:netrw_ftpextracmd
2089 " call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2090 endif
2091 call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2092 " call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2093 if exists("g:netrw_port") && g:netrw_port != ""
2094 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2095 else
2096 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2097 endif
2098 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2099 if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2100 let debugkeep = &debug
2101 setl debug=msg
2102 NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2103 let &debug = debugkeep
2104 endif
2105 call s:SaveBufVars()
2106 keepj bd!
2107 if bufname("%") == "" && getline("$") == "" && line('$') == 1
2108 " needed when one sources a file in a nolbl setting window via ftp
2109 q!
2110 endif
2111 call s:RestoreBufVars()
2112 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2113 let b:netrw_lastfile = choice
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002114
Luca Saccarolac363ca12024-12-19 20:16:18 +01002115 ".........................................
2116 " NetRead: (ftp + machine,id,passwd,filename) NetRead Method #3 {{{3
2117 elseif b:netrw_method == 3 " read with ftp + machine, id, passwd, and fname
2118 " Construct execution string (four lines) which will be passed through filter
2119 " call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2120 let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2121 NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2122 let filtbuf= bufnr("%")
2123 setl ff=unix
2124 if exists("g:netrw_port") && g:netrw_port != ""
2125 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2126 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2127 else
2128 NetrwKeepj put ='open '.g:netrw_machine
2129 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2130 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002131
Luca Saccarolac363ca12024-12-19 20:16:18 +01002132 if exists("g:netrw_uid") && g:netrw_uid != ""
2133 if exists("g:netrw_ftp") && g:netrw_ftp == 1
2134 NetrwKeepj put =g:netrw_uid
2135 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2136 if exists("s:netrw_passwd")
2137 NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2138 endif
2139 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2140 elseif exists("s:netrw_passwd")
2141 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2142 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2143 endif
2144 endif
2145
2146 if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2147 NetrwKeepj put =g:netrw_ftpmode
2148 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2149 endif
2150 if exists("g:netrw_ftpextracmd")
2151 NetrwKeepj put =g:netrw_ftpextracmd
2152 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2153 endif
2154 NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2155 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2156
2157 " perform ftp:
2158 " -i : turns off interactive prompting from ftp
2159 " -n unix : DON'T use <.netrc>, even though it exists
2160 " -n win32: quit being obnoxious about password
2161 NetrwKeepj norm! 1G"_dd
2162 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2163 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2164 if getline(1) !~ "^$"
2165 " call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2166 if !exists("g:netrw_quiet")
2167 call netrw#ErrorMsg(s:ERROR,getline(1),5)
2168 endif
2169 endif
2170 call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2171 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2172 let b:netrw_lastfile = choice
2173
2174 ".........................................
2175 " NetRead: (scp) NetRead Method #4 {{{3
2176 elseif b:netrw_method == 4 " read with scp
2177 " call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2178 if exists("g:netrw_port") && g:netrw_port != ""
2179 let useport= " ".g:netrw_scpport." ".g:netrw_port
2180 else
2181 let useport= ""
2182 endif
2183 " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2184 " This is workaround to avoid mis-handle windows local-path:
2185 if g:netrw_scp_cmd =~ '^scp' && has("win32")
2186 let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2187 else
2188 let tmpfile_get = tmpfile
2189 endif
2190 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".escape(s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1),' ')." ".s:ShellEscape(tmpfile_get,1))
2191 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2192 let b:netrw_lastfile = choice
2193
2194 ".........................................
2195 " NetRead: (http) NetRead Method #5 (wget) {{{3
2196 elseif b:netrw_method == 5
2197 " call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2198 if g:netrw_http_cmd == ""
2199 if !exists("g:netrw_quiet")
2200 call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2201 endif
2202 " call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2203 return
2204 endif
2205
2206 if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2207 " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2208 " call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2209 if exists("g:netrw_http_xcmd")
2210 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_cmd." ".s:ShellEscape(b:netrw_http."://".g:netrw_machine.b:netrw_fname,1)." ".g:netrw_http_xcmd." ".s:ShellEscape(tmpfile,1))
2211 else
2212 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(b:netrw_http."://".g:netrw_machine.b:netrw_fname,1))
2213 endif
2214 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2215
2216 else
2217 " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2218 " call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2219 let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2220 let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2221 " call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2222 " call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2223 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(b:netrw_http."://".g:netrw_machine.netrw_html,1))
2224 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2225 " call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2226 exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2227 endif
2228 let b:netrw_lastfile = choice
2229 " call Decho("setl ro",'~'.expand("<slnum>"))
2230 setl ro nomod
2231
2232 ".........................................
2233 " NetRead: (dav) NetRead Method #6 {{{3
2234 elseif b:netrw_method == 6
2235 " call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2236
2237 if !executable(g:netrw_dav_cmd)
2238 call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2239 " call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2240 return
2241 endif
2242 if g:netrw_dav_cmd =~ "curl"
2243 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2244 else
2245 " Construct execution string (four lines) which will be passed through filter
2246 let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2247 new
2248 setl ff=unix
2249 if exists("g:netrw_port") && g:netrw_port != ""
2250 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2251 else
2252 NetrwKeepj put ='open '.g:netrw_machine
2253 endif
2254 if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2255 NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2256 endif
2257 NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2258 NetrwKeepj put ='quit'
2259
2260 " perform cadaver operation:
2261 NetrwKeepj norm! 1G"_dd
2262 call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2263 keepj bd!
2264 endif
2265 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2266 let b:netrw_lastfile = choice
2267
2268 ".........................................
2269 " NetRead: (rsync) NetRead Method #7 {{{3
2270 elseif b:netrw_method == 7
2271 " call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2272 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(g:netrw_machine.g:netrw_rsync_sep.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2273 let result = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2274 let b:netrw_lastfile = choice
2275
2276 ".........................................
2277 " NetRead: (fetch) NetRead Method #8 {{{3
2278 " fetch://[user@]host[:http]/path
2279 elseif b:netrw_method == 8
2280 " call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2281 if g:netrw_fetch_cmd == ""
2282 if !exists("g:netrw_quiet")
2283 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2284 endif
2285 " call Dret("NetRead")
2286 return
2287 endif
2288 if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2289 let netrw_option= "http"
2290 else
2291 let netrw_option= "ftp"
2292 endif
2293 " call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2294
2295 if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2296 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(netrw_option."://".g:netrw_uid.':'.s:netrw_passwd.'@'.g:netrw_machine."/".b:netrw_fname,1))
2297 else
2298 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_fetch_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(netrw_option."://".g:netrw_machine."/".b:netrw_fname,1))
2299 endif
2300
2301 let result = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2302 let b:netrw_lastfile = choice
2303 " call Decho("setl ro",'~'.expand("<slnum>"))
2304 setl ro nomod
2305
2306 ".........................................
2307 " NetRead: (sftp) NetRead Method #9 {{{3
2308 elseif b:netrw_method == 9
2309 " call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2310 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2311 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2312 let b:netrw_lastfile = choice
2313
2314 ".........................................
2315 " NetRead: (file) NetRead Method #10 {{{3
2316 elseif b:netrw_method == 10 && exists("g:netrw_file_cmd")
2317 " " call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2318 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2319 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2320 let b:netrw_lastfile = choice
2321
2322 ".........................................
2323 " NetRead: Complain {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002324 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002325 call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002326 endif
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002327 endwhile
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002328
Bram Moolenaar5c736222010-01-06 20:54:52 +01002329 " NetRead: cleanup {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002330 if exists("b:netrw_method")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002331 " call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2332 unlet b:netrw_method
2333 unlet b:netrw_fname
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002334 endif
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +02002335 if s:FileReadable(tmpfile) && tmpfile !~ '.tar.bz2$' && tmpfile !~ '.tar.gz$' && tmpfile !~ '.zip' && tmpfile !~ '.tar' && readcmd != 't' && tmpfile !~ '.tar.xz$' && tmpfile !~ '.txz'
Luca Saccarolac363ca12024-12-19 20:16:18 +01002336 " call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2337 NetrwKeepj call s:NetrwDelete(tmpfile)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002338 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02002339 NetrwKeepj call s:NetrwOptionsRestore("w:")
Bram Moolenaar8299df92004-07-10 09:47:34 +00002340
Luca Saccarolac363ca12024-12-19 20:16:18 +01002341 " call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002342endfun
2343
2344" ------------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00002345" netrw#NetWrite: responsible for writing a file over the net {{{2
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +00002346fun! netrw#NetWrite(...) range
Luca Saccarolac363ca12024-12-19 20:16:18 +01002347 " call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002348
Bram Moolenaar5c736222010-01-06 20:54:52 +01002349 " NetWrite: option handling {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002350 let mod= 0
Bram Moolenaar85850f32019-07-19 22:05:51 +02002351 call s:NetrwOptionsSave("w:")
2352 call s:NetrwOptionsSafe(0)
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002353
Bram Moolenaar5c736222010-01-06 20:54:52 +01002354 " NetWrite: Get Temporary Filename {{{3
Bram Moolenaar9964e462007-05-05 17:54:07 +00002355 let tmpfile= s:GetTempfile("")
2356 if tmpfile == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01002357 " call Dret("netrw#NetWrite : unable to get a tempfile!")
2358 return
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +00002359 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002360
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002361 if a:0 == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01002362 let ichoice = 0
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002363 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002364 let ichoice = 1
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002365 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002366
Bram Moolenaar9964e462007-05-05 17:54:07 +00002367 let curbufname= expand("%")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002368 " call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
Bram Moolenaar1afcace2005-11-25 19:54:28 +00002369 if &binary
Luca Saccarolac363ca12024-12-19 20:16:18 +01002370 " For binary writes, always write entire file.
2371 " (line numbers don't really make sense for that).
2372 " Also supports the writing of tar and zip files.
2373 " call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2374 exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002375 elseif g:netrw_cygwin
Luca Saccarolac363ca12024-12-19 20:16:18 +01002376 " write (selected portion of) file to temporary
2377 let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2378 " call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2379 exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
Bram Moolenaar1afcace2005-11-25 19:54:28 +00002380 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002381 " write (selected portion of) file to temporary
2382 " call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2383 exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
Bram Moolenaar1afcace2005-11-25 19:54:28 +00002384 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002385
Bram Moolenaar9964e462007-05-05 17:54:07 +00002386 if curbufname == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01002387 " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2388 " on the temporary file's name. Deletion of the temporary file during
2389 " cleanup then causes an error message.
2390 0file!
Bram Moolenaar9964e462007-05-05 17:54:07 +00002391 endif
2392
Bram Moolenaar5c736222010-01-06 20:54:52 +01002393 " NetWrite: while choice loop: {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002394 while ichoice <= a:0
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002395
Luca Saccarolac363ca12024-12-19 20:16:18 +01002396 " Process arguments: {{{4
2397 " attempt to repeat with previous host-file-etc
2398 if exists("b:netrw_lastfile") && a:0 == 0
2399 " call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2400 let choice = b:netrw_lastfile
2401 let ichoice= ichoice + 1
2402 else
2403 exe "let choice= a:" . ichoice
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002404
Luca Saccarolac363ca12024-12-19 20:16:18 +01002405 " Reconstruct Choice when choice starts with '"'
2406 if match(choice,"?") == 0
2407 echomsg 'NetWrite Usage:"'
2408 echomsg ':Nwrite machine:path uses rcp'
2409 echomsg ':Nwrite "machine path" uses ftp with <.netrc>'
2410 echomsg ':Nwrite "machine id password path" uses ftp'
2411 echomsg ':Nwrite dav://[user@]machine/path uses cadaver'
2412 echomsg ':Nwrite fetch://[user@]machine/path uses fetch'
2413 echomsg ':Nwrite ftp://machine[#port]/path uses ftp (autodetects <.netrc>)'
2414 echomsg ':Nwrite rcp://machine/path uses rcp'
2415 echomsg ':Nwrite rsync://[user@]machine/path uses rsync'
2416 echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2417 echomsg ':Nwrite sftp://[user@]machine/path uses sftp'
2418 sleep 4
2419 break
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002420
Luca Saccarolac363ca12024-12-19 20:16:18 +01002421 elseif match(choice,"^\"") != -1
2422 if match(choice,"\"$") != -1
2423 " case "..."
2424 let choice=strpart(choice,1,strlen(choice)-2)
2425 else
2426 " case "... ... ..."
2427 let choice = strpart(choice,1,strlen(choice)-1)
2428 let wholechoice = ""
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002429
Luca Saccarolac363ca12024-12-19 20:16:18 +01002430 while match(choice,"\"$") == -1
2431 let wholechoice= wholechoice . " " . choice
2432 let ichoice = ichoice + 1
2433 if choice > a:0
2434 if !exists("g:netrw_quiet")
2435 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2436 endif
2437 " call Dret("netrw#NetWrite")
2438 return
2439 endif
2440 let choice= a:{ichoice}
2441 endwhile
2442 let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
K.Takata71d0ba02024-01-10 03:21:05 +09002443 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +02002444 endif
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002445 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01002446 let ichoice= ichoice + 1
2447 " call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002448
Luca Saccarolac363ca12024-12-19 20:16:18 +01002449 " Determine method of write (ftp, rcp, etc) {{{4
2450 NetrwKeepj call s:NetrwMethod(choice)
2451 if !exists("b:netrw_method") || b:netrw_method < 0
2452 " call Dfunc("netrw#NetWrite : unsupported method")
2453 return
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002454 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01002455
Luca Saccarolac363ca12024-12-19 20:16:18 +01002456 " =============
2457 " NetWrite: Perform Protocol-Based Write {{{3
2458 " ============================
2459 if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2460 echo "(netrw) Processing your write request..."
2461 " call Decho("Processing your write request...",'~'.expand("<slnum>"))
2462 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002463
Luca Saccarolac363ca12024-12-19 20:16:18 +01002464 ".........................................
2465 " NetWrite: (rcp) NetWrite Method #1 {{{3
2466 if b:netrw_method == 1
2467 " call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2468 if s:netrw_has_nt_rcp == 1
2469 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2470 let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2471 else
2472 let uid_machine = g:netrw_machine .'.'. $USERNAME
2473 endif
2474 else
2475 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2476 let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2477 else
2478 let uid_machine = g:netrw_machine
2479 endif
2480 endif
2481 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rcp_cmd." ".s:netrw_rcpmode." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(uid_machine.":".b:netrw_fname,1))
2482 let b:netrw_lastfile = choice
2483
2484 ".........................................
2485 " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
2486 elseif b:netrw_method == 2
2487 " call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2488 let netrw_fname = b:netrw_fname
2489
2490 " formerly just a "new...bd!", that changed the window sizes when equalalways. Using enew workaround instead
2491 let bhkeep = &l:bh
2492 let curbuf = bufnr("%")
2493 setl bh=hide
2494 keepj keepalt enew
2495
2496 " call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2497 setl ff=unix
2498 NetrwKeepj put =g:netrw_ftpmode
2499 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2500 if exists("g:netrw_ftpextracmd")
2501 NetrwKeepj put =g:netrw_ftpextracmd
2502 " call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2503 endif
2504 NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2505 " call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2506 if exists("g:netrw_port") && g:netrw_port != ""
2507 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2508 else
2509 " call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2510 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2511 endif
2512 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2513 if getline(1) !~ "^$"
2514 if !exists("g:netrw_quiet")
2515 NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2516 endif
2517 let mod=1
2518 endif
2519
2520 " remove enew buffer (quietly)
2521 let filtbuf= bufnr("%")
2522 exe curbuf."b!"
2523 let &l:bh = bhkeep
2524 exe filtbuf."bw!"
2525
2526 let b:netrw_lastfile = choice
2527
2528 ".........................................
2529 " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
2530 elseif b:netrw_method == 3
2531 " Construct execution string (three or more lines) which will be passed through filter
2532 " call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2533 let netrw_fname = b:netrw_fname
2534 let bhkeep = &l:bh
2535
2536 " formerly just a "new...bd!", that changed the window sizes when equalalways. Using enew workaround instead
2537 let curbuf = bufnr("%")
2538 setl bh=hide
2539 keepj keepalt enew
2540 setl ff=unix
2541
2542 if exists("g:netrw_port") && g:netrw_port != ""
2543 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2544 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2545 else
2546 NetrwKeepj put ='open '.g:netrw_machine
2547 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2548 endif
2549 if exists("g:netrw_uid") && g:netrw_uid != ""
2550 if exists("g:netrw_ftp") && g:netrw_ftp == 1
2551 NetrwKeepj put =g:netrw_uid
2552 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2553 if exists("s:netrw_passwd") && s:netrw_passwd != ""
2554 NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2555 endif
2556 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2557 elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2558 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2559 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2560 endif
2561 endif
2562 NetrwKeepj put =g:netrw_ftpmode
2563 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2564 if exists("g:netrw_ftpextracmd")
2565 NetrwKeepj put =g:netrw_ftpextracmd
2566 " call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2567 endif
2568 NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2569 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2570 " save choice/id/password for future use
2571 let b:netrw_lastfile = choice
2572
2573 " perform ftp:
2574 " -i : turns off interactive prompting from ftp
2575 " -n unix : DON'T use <.netrc>, even though it exists
2576 " -n win32: quit being obnoxious about password
2577 NetrwKeepj norm! 1G"_dd
2578 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2579 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2580 if getline(1) !~ "^$"
2581 if !exists("g:netrw_quiet")
2582 call netrw#ErrorMsg(s:ERROR,getline(1),15)
2583 endif
2584 let mod=1
2585 endif
2586
2587 " remove enew buffer (quietly)
2588 let filtbuf= bufnr("%")
2589 exe curbuf."b!"
2590 let &l:bh= bhkeep
2591 exe filtbuf."bw!"
2592
2593 ".........................................
2594 " NetWrite: (scp) NetWrite Method #4 {{{3
2595 elseif b:netrw_method == 4
2596 " call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2597 if exists("g:netrw_port") && g:netrw_port != ""
2598 let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2599 else
2600 let useport= ""
2601 endif
2602 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2603 let b:netrw_lastfile = choice
2604
2605 ".........................................
2606 " NetWrite: (http) NetWrite Method #5 {{{3
2607 elseif b:netrw_method == 5
2608 " call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2609 let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2610 if executable(curl)
2611 let url= g:netrw_choice
2612 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2613 elseif !exists("g:netrw_quiet")
2614 call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd.">",16)
2615 endif
2616
2617 ".........................................
2618 " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
2619 elseif b:netrw_method == 6
2620 " call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2621
2622 " Construct execution string (four lines) which will be passed through filter
2623 let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2624 let bhkeep = &l:bh
2625
2626 " formerly just a "new...bd!", that changed the window sizes when equalalways. Using enew workaround instead
2627 let curbuf = bufnr("%")
2628 setl bh=hide
2629 keepj keepalt enew
2630
2631 setl ff=unix
2632 if exists("g:netrw_port") && g:netrw_port != ""
2633 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2634 else
2635 NetrwKeepj put ='open '.g:netrw_machine
2636 endif
2637 if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2638 NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2639 endif
2640 NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2641
2642 " perform cadaver operation:
2643 NetrwKeepj norm! 1G"_dd
2644 call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2645
2646 " remove enew buffer (quietly)
2647 let filtbuf= bufnr("%")
2648 exe curbuf."b!"
2649 let &l:bh = bhkeep
2650 exe filtbuf."bw!"
2651
2652 let b:netrw_lastfile = choice
2653
2654 ".........................................
2655 " NetWrite: (rsync) NetWrite Method #7 {{{3
2656 elseif b:netrw_method == 7
2657 " call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2658 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_rsync_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.g:netrw_rsync_sep.b:netrw_fname,1))
2659 let b:netrw_lastfile = choice
2660
2661 ".........................................
2662 " NetWrite: (sftp) NetWrite Method #9 {{{3
2663 elseif b:netrw_method == 9
2664 " call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2665 let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2666 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2667 let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2668 else
2669 let uid_machine = g:netrw_machine
2670 endif
2671
2672 " formerly just a "new...bd!", that changed the window sizes when equalalways. Using enew workaround instead
2673 let bhkeep = &l:bh
2674 let curbuf = bufnr("%")
2675 setl bh=hide
2676 keepj keepalt enew
2677
2678 setl ff=unix
2679 call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2680 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2681 let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2682 call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2683 let filtbuf= bufnr("%")
2684 exe curbuf."b!"
2685 let &l:bh = bhkeep
2686 exe filtbuf."bw!"
2687 let b:netrw_lastfile = choice
2688
2689 ".........................................
2690 " NetWrite: Complain {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002691 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002692 call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2693 let leavemod= 1
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002694 endif
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002695 endwhile
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002696
Bram Moolenaar5c736222010-01-06 20:54:52 +01002697 " NetWrite: Cleanup: {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002698 " call Decho("cleanup",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00002699 if s:FileReadable(tmpfile)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002700 " call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2701 call s:NetrwDelete(tmpfile)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002702 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02002703 call s:NetrwOptionsRestore("w:")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002704
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002705 if a:firstline == 1 && a:lastline == line("$")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002706 " restore modifiability; usually equivalent to set nomod
2707 let &l:mod= mod
2708 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
Bram Moolenaaradc21822011-04-01 18:03:16 +02002709 elseif !exists("leavemod")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002710 " indicate that the buffer has not been modified since last written
2711 " call Decho("set nomod",'~'.expand("<slnum>"))
2712 setl nomod
2713 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002714 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002715
Luca Saccarolac363ca12024-12-19 20:16:18 +01002716 " call Dret("netrw#NetWrite")
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002717endfun
2718
2719" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00002720" netrw#NetSource: source a remotely hosted vim script {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +00002721" uses NetRead to get a copy of the file into a temporarily file,
2722" then sources that file,
2723" then removes that file.
2724fun! netrw#NetSource(...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002725 " call Dfunc("netrw#NetSource() a:0=".a:0)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002726 if a:0 > 0 && a:1 == '?'
Luca Saccarolac363ca12024-12-19 20:16:18 +01002727 " give help
2728 echomsg 'NetSource Usage:'
2729 echomsg ':Nsource dav://machine[:port]/path uses cadaver'
2730 echomsg ':Nsource fetch://machine/path uses fetch'
2731 echomsg ':Nsource ftp://[user@]machine[:port]/path uses ftp autodetects <.netrc>'
2732 echomsg ':Nsource http[s]://[user@]machine/path uses http wget'
2733 echomsg ':Nsource rcp://[user@]machine/path uses rcp'
2734 echomsg ':Nsource rsync://machine[:port]/path uses rsync'
2735 echomsg ':Nsource scp://[user@]machine[[:#]port]/path uses scp'
2736 echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2737 sleep 4
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002738 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002739 let i= 1
2740 while i <= a:0
2741 call netrw#NetRead(3,a:{i})
2742 " call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2743 if s:FileReadable(s:netrw_tmpfile)
2744 " call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2745 exe "so ".fnameescape(s:netrw_tmpfile)
2746 " call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2747 if delete(s:netrw_tmpfile)
2748 call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2749 endif
2750 unlet s:netrw_tmpfile
2751 else
2752 call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2753 endif
2754 let i= i + 1
2755 endwhile
Bram Moolenaar9964e462007-05-05 17:54:07 +00002756 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01002757 " call Dret("netrw#NetSource")
Bram Moolenaar9964e462007-05-05 17:54:07 +00002758endfun
2759
Bram Moolenaar8d043172014-01-23 14:24:41 +01002760" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01002761" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2762" (implements the :Ntree command)
Bram Moolenaar85850f32019-07-19 22:05:51 +02002763fun! netrw#SetTreetop(iscmd,...)
Bram Moolenaara6878372014-03-22 21:02:50 +01002764
Bram Moolenaar85850f32019-07-19 22:05:51 +02002765 " iscmd==0: netrw#SetTreetop called using gn mapping
2766 " iscmd==1: netrw#SetTreetop called using :Ntree from the command line
Bram Moolenaar8d043172014-01-23 14:24:41 +01002767 " clear out the current tree
2768 if exists("w:netrw_treetop")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002769 let inittreetop= w:netrw_treetop
2770 unlet w:netrw_treetop
Bram Moolenaar8d043172014-01-23 14:24:41 +01002771 endif
2772 if exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002773 unlet w:netrw_treedict
Bram Moolenaar8d043172014-01-23 14:24:41 +01002774 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01002775
Bram Moolenaar85850f32019-07-19 22:05:51 +02002776 if (a:iscmd == 0 || a:1 == "") && exists("inittreetop")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002777 let treedir = s:NetrwTreePath(inittreetop)
Bram Moolenaar8d043172014-01-23 14:24:41 +01002778 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002779 if isdirectory(s:NetrwFile(a:1))
2780 let treedir = a:1
2781 let s:netrw_treetop = treedir
2782 elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2783 let treedir = b:netrw_curdir."/".a:1
2784 let s:netrw_treetop = treedir
2785 else
2786 " normally the cursor is left in the message window.
2787 " However, here this results in the directory being listed in the message window, which is not wanted.
2788 let netrwbuf= bufnr("%")
2789 call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2790 exe bufwinnr(netrwbuf)."wincmd w"
2791 let treedir = "."
2792 let s:netrw_treetop = getcwd()
2793 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +01002794 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02002795
2796 " determine if treedir is remote or local
Bram Moolenaara0f849e2015-10-30 14:37:44 +01002797 let islocal= expand("%") !~ '^\a\{3,}://'
Bram Moolenaar85850f32019-07-19 22:05:51 +02002798
2799 " browse the resulting directory
Bram Moolenaara6878372014-03-22 21:02:50 +01002800 if islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01002801 call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir,0))
Bram Moolenaara6878372014-03-22 21:02:50 +01002802 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002803 call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir,0))
Bram Moolenaara6878372014-03-22 21:02:50 +01002804 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02002805
Bram Moolenaar8d043172014-01-23 14:24:41 +01002806endfun
2807
Bram Moolenaar9964e462007-05-05 17:54:07 +00002808" ===========================================
Bram Moolenaar446cb832008-06-24 21:56:24 +00002809" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +00002810" readcmd == %r : replace buffer with newly read file
2811" == 0r : read file at top of buffer
2812" == r : read file after current line
2813" == t : leave file in temporary form (ie. don't read into buffer)
Bram Moolenaar446cb832008-06-24 21:56:24 +00002814fun! s:NetrwGetFile(readcmd, tfile, method)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002815 " call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +00002816
2817 " readcmd=='t': simply do nothing
2818 if a:readcmd == 't'
Luca Saccarolac363ca12024-12-19 20:16:18 +01002819 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2820 " call Dret("NetrwGetFile : skip read of tfile<".a:tfile.">")
2821 return
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002822 endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +00002823
Bram Moolenaar9964e462007-05-05 17:54:07 +00002824 " get name of remote filename (ie. url and all)
2825 let rfile= bufname("%")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002826 " call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
Bram Moolenaar578b49e2005-09-10 19:22:57 +00002827
Bram Moolenaar9964e462007-05-05 17:54:07 +00002828 if exists("*NetReadFixup")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002829 " for the use of NetReadFixup (not otherwise used internally)
2830 let line2= line("$")
Bram Moolenaar578b49e2005-09-10 19:22:57 +00002831 endif
2832
Bram Moolenaar9964e462007-05-05 17:54:07 +00002833 if a:readcmd[0] == '%'
Luca Saccarolac363ca12024-12-19 20:16:18 +01002834 " get file into buffer
2835 " call Decho("get file into buffer",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00002836
Luca Saccarolac363ca12024-12-19 20:16:18 +01002837 " rename the current buffer to the temp file (ie. tfile)
2838 if g:netrw_cygwin
2839 let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2840 else
2841 let tfile= a:tfile
2842 endif
2843 call s:NetrwBufRename(tfile)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002844
Luca Saccarolac363ca12024-12-19 20:16:18 +01002845 " edit temporary file (ie. read the temporary file in)
2846 if rfile =~ '\.zip$'
2847 " call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2848 call zip#Browse(tfile)
2849 elseif rfile =~ '\.tar$'
2850 " call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2851 call tar#Browse(tfile)
2852 elseif rfile =~ '\.tar\.gz$'
2853 " call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2854 call tar#Browse(tfile)
2855 elseif rfile =~ '\.tar\.bz2$'
2856 " call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2857 call tar#Browse(tfile)
2858 elseif rfile =~ '\.tar\.xz$'
2859 " call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2860 call tar#Browse(tfile)
2861 elseif rfile =~ '\.txz$'
2862 " call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2863 call tar#Browse(tfile)
2864 else
2865 " call Decho("edit temporary file",'~'.expand("<slnum>"))
2866 NetrwKeepj e!
2867 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00002868
Luca Saccarolac363ca12024-12-19 20:16:18 +01002869 " rename buffer back to remote filename
2870 call s:NetrwBufRename(rfile)
Bram Moolenaar5b435d62012-04-05 17:33:26 +02002871
Luca Saccarolac363ca12024-12-19 20:16:18 +01002872 " Jan 19, 2022: COMBAK -- bram problem with https://github.com/vim/vim/pull/9554.diff filetype
2873 " Detect filetype of local version of remote file.
2874 " Note that isk must not include a "/" for scripts.vim
2875 " to process this detection correctly.
2876 " call Decho("detect filetype of local version of remote file<".rfile.">",'~'.expand("<slnum>"))
2877 " call Decho("..did_filetype()=".did_filetype())
2878 " setl ft=
2879 " call Decho("..initial filetype<".&ft."> for buf#".bufnr()."<".bufname().">")
2880 let iskkeep= &isk
2881 setl isk-=/
2882 filetype detect
2883 " call Decho("..local filetype<".&ft."> for buf#".bufnr()."<".bufname().">")
2884 let &l:isk= iskkeep
2885 " call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
2886 let line1 = 1
2887 let line2 = line("$")
Bram Moolenaar9964e462007-05-05 17:54:07 +00002888
Bram Moolenaar8d043172014-01-23 14:24:41 +01002889 elseif !&ma
Luca Saccarolac363ca12024-12-19 20:16:18 +01002890 " attempting to read a file after the current line in the file, but the buffer is not modifiable
2891 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2892 " call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2893 return
Bram Moolenaar8d043172014-01-23 14:24:41 +01002894
Bram Moolenaar9964e462007-05-05 17:54:07 +00002895 elseif s:FileReadable(a:tfile)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002896 " read file after current line
2897 " call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2898 let curline = line(".")
2899 let lastline= line("$")
2900 " call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)."> line#".curline,'~'.expand("<slnum>"))
2901 exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2902 let line1= curline + 1
2903 let line2= line("$") - lastline + 1
Bram Moolenaar9964e462007-05-05 17:54:07 +00002904
2905 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002906 " not readable
2907 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2908 " call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2909 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2910 " call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2911 return
Bram Moolenaar9964e462007-05-05 17:54:07 +00002912 endif
2913
2914 " User-provided (ie. optional) fix-it-up command
2915 if exists("*NetReadFixup")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002916 " call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2917 NetrwKeepj call NetReadFixup(a:method, line1, line2)
2918 " else " Decho
2919 " call Decho("NetReadFixup() not called, doesn't exist (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00002920 endif
2921
Bram Moolenaaradc21822011-04-01 18:03:16 +02002922 if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
Luca Saccarolac363ca12024-12-19 20:16:18 +01002923 " update the Buffers menu
2924 NetrwKeepj call s:UpdateBuffersMenu()
Bram Moolenaar9964e462007-05-05 17:54:07 +00002925 endif
2926
Luca Saccarolac363ca12024-12-19 20:16:18 +01002927 " call Decho("readcmd<".a:readcmd."> cmdarg<".v:cmdarg."> tfile<".a:tfile."> readable=".s:FileReadable(a:tfile),'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00002928
Luca Saccarolac363ca12024-12-19 20:16:18 +01002929 " make sure file is being displayed
2930 " redraw!
Bram Moolenaar446cb832008-06-24 21:56:24 +00002931
Luca Saccarolac363ca12024-12-19 20:16:18 +01002932 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2933 " call Dret("NetrwGetFile")
Bram Moolenaar578b49e2005-09-10 19:22:57 +00002934endfun
2935
Bram Moolenaar9964e462007-05-05 17:54:07 +00002936" ------------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00002937" s:NetrwMethod: determine method of transfer {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +01002938" Input:
2939" choice = url [protocol:]//[userid@]hostname[:port]/[path-to-file]
2940" Output:
Bram Moolenaara0f849e2015-10-30 14:37:44 +01002941" b:netrw_method= 1: rcp
2942" 2: ftp + <.netrc>
Luca Saccarolac363ca12024-12-19 20:16:18 +01002943" 3: ftp + machine, id, password, and [path]filename
2944" 4: scp
2945" 5: http[s] (wget)
2946" 6: dav
2947" 7: rsync
2948" 8: fetch
2949" 9: sftp
2950" 10: file
Bram Moolenaar5c736222010-01-06 20:54:52 +01002951" g:netrw_machine= hostname
2952" b:netrw_fname = filename
2953" g:netrw_port = optional port number (for ftp)
2954" g:netrw_choice = copy of input url (choice)
2955fun! s:NetrwMethod(choice)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002956 " call Dfunc("s:NetrwMethod(a:choice<".a:choice.">)")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002957
Luca Saccarolac363ca12024-12-19 20:16:18 +01002958 " sanity check: choice should have at least three slashes in it
2959 if strlen(substitute(a:choice,'[^/]','','g')) < 3
Bram Moolenaar251e1912011-06-19 05:09:16 +02002960 call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
2961 let b:netrw_method = -1
Luca Saccarolac363ca12024-12-19 20:16:18 +01002962 " call Dret("s:NetrwMethod : incorrect url format<".a:choice.">")
Bram Moolenaar251e1912011-06-19 05:09:16 +02002963 return
Luca Saccarolac363ca12024-12-19 20:16:18 +01002964 endif
Bram Moolenaar251e1912011-06-19 05:09:16 +02002965
Luca Saccarolac363ca12024-12-19 20:16:18 +01002966 " record current g:netrw_machine, if any
2967 " curmachine used if protocol == ftp and no .netrc
2968 if exists("g:netrw_machine")
Bram Moolenaar5c736222010-01-06 20:54:52 +01002969 let curmachine= g:netrw_machine
Luca Saccarolac363ca12024-12-19 20:16:18 +01002970 " call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
2971 else
Bram Moolenaar5c736222010-01-06 20:54:52 +01002972 let curmachine= "N O T A HOST"
Luca Saccarolac363ca12024-12-19 20:16:18 +01002973 endif
2974 if exists("g:netrw_port")
Bram Moolenaaradc21822011-04-01 18:03:16 +02002975 let netrw_port= g:netrw_port
Luca Saccarolac363ca12024-12-19 20:16:18 +01002976 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02002977
Luca Saccarolac363ca12024-12-19 20:16:18 +01002978 " insure that netrw_ftp_cmd starts off every method determination
2979 " with the current g:netrw_ftp_cmd
2980 let s:netrw_ftp_cmd= g:netrw_ftp_cmd
Bram Moolenaar5c736222010-01-06 20:54:52 +01002981
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002982 " initialization
2983 let b:netrw_method = 0
2984 let g:netrw_machine = ""
2985 let b:netrw_fname = ""
2986 let g:netrw_port = ""
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002987 let g:netrw_choice = a:choice
2988
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002989 " Patterns:
Luca Saccarolac363ca12024-12-19 20:16:18 +01002990 " mipf : a:machine a:id password filename Use ftp
2991 " mf : a:machine filename Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
Bram Moolenaar446cb832008-06-24 21:56:24 +00002992 " ftpurm : ftp://[user@]host[[#:]port]/filename Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
Luca Saccarolac363ca12024-12-19 20:16:18 +01002993 " rcpurm : rcp://[user@]host/filename Use rcp
2994 " rcphf : [user@]host:filename Use rcp
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002995 " scpurm : scp://[user@]host[[#:]port]/filename Use scp
Luca Saccarolac363ca12024-12-19 20:16:18 +01002996 " httpurm : http[s]://[user@]host/filename Use wget
Bram Moolenaar5c736222010-01-06 20:54:52 +01002997 " davurm : dav[s]://host[:port]/path Use cadaver/curl
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002998 " rsyncurm : rsync://host[:port]/path Use rsync
2999 " fetchurm : fetch://[user@]host[:http]/filename Use fetch (defaults to ftp, override for http)
3000 " sftpurm : sftp://[user@]host/filename Use scp
Luca Saccarolac363ca12024-12-19 20:16:18 +01003001 " fileurm : file://[user@]host/filename Use elinks or links
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003002 let mipf = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
3003 let mf = '^\(\S\+\)\s\+\(\S\+\)$'
Bram Moolenaar15146672011-10-20 22:22:38 +02003004 let ftpurm = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
3005 let rcpurm = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003006 let rcphf = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
Bram Moolenaar1afcace2005-11-25 19:54:28 +00003007 let scpurm = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
Bram Moolenaar15146672011-10-20 22:22:38 +02003008 let httpurm = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
Bram Moolenaar446cb832008-06-24 21:56:24 +00003009 let davurm = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003010 let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
Bram Moolenaar15146672011-10-20 22:22:38 +02003011 let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003012 let sftpurm = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003013 let fileurm = '^file\=://\(.*\)$'
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003014
Luca Saccarolac363ca12024-12-19 20:16:18 +01003015 " call Decho("determine method:",'~'.expand("<slnum>"))
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003016 " Determine Method
Bram Moolenaaradc21822011-04-01 18:03:16 +02003017 " Method#1: rcp://user@hostname/...path-to-file {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003018 if match(a:choice,rcpurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003019 " call Decho("rcp://...",'~'.expand("<slnum>"))
3020 let b:netrw_method = 1
3021 let userid = substitute(a:choice,rcpurm,'\1',"")
3022 let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
3023 let b:netrw_fname = substitute(a:choice,rcpurm,'\3',"")
3024 if userid != ""
3025 let g:netrw_uid= userid
3026 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003027
Luca Saccarolac363ca12024-12-19 20:16:18 +01003028 " Method#4: scp://user@hostname/...path-to-file {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003029 elseif match(a:choice,scpurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003030 " call Decho("scp://...",'~'.expand("<slnum>"))
3031 let b:netrw_method = 4
3032 let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
3033 let g:netrw_port = substitute(a:choice,scpurm,'\2',"")
3034 let b:netrw_fname = substitute(a:choice,scpurm,'\3',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003035
Luca Saccarolac363ca12024-12-19 20:16:18 +01003036 " Method#5: http[s]://user@hostname/...path-to-file {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003037 elseif match(a:choice,httpurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003038 " call Decho("http[s]://...",'~'.expand("<slnum>"))
3039 let b:netrw_method = 5
3040 let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
3041 let b:netrw_fname = substitute(a:choice,httpurm,'\2',"")
3042 let b:netrw_http = (a:choice =~ '^https:')? "https" : "http"
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003043
Luca Saccarolac363ca12024-12-19 20:16:18 +01003044 " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003045 elseif match(a:choice,davurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003046 " call Decho("dav://...",'~'.expand("<slnum>"))
3047 let b:netrw_method= 6
3048 if a:choice =~ 'davs:'
3049 let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003050 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003051 let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003052 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003053 let b:netrw_fname = substitute(a:choice,davurm,'\3',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003054
Luca Saccarolac363ca12024-12-19 20:16:18 +01003055 " Method#7: rsync://user@hostname/...path-to-file {{{3
3056 elseif match(a:choice,rsyncurm) == 0
3057 " call Decho("rsync://...",'~'.expand("<slnum>"))
3058 let b:netrw_method = 7
3059 let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
3060 let b:netrw_fname = substitute(a:choice,rsyncurm,'\2',"")
3061
3062 " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
3063 elseif match(a:choice,ftpurm) == 0
3064 " call Decho("ftp://...",'~'.expand("<slnum>"))
3065 let userid = substitute(a:choice,ftpurm,'\2',"")
3066 let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
3067 let g:netrw_port = substitute(a:choice,ftpurm,'\4',"")
3068 let b:netrw_fname = substitute(a:choice,ftpurm,'\5',"")
3069 " call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3070 if userid != ""
3071 let g:netrw_uid= userid
3072 endif
3073
3074 if curmachine != g:netrw_machine
3075 if exists("s:netrw_hup[".g:netrw_machine."]")
3076 call NetUserPass("ftp:".g:netrw_machine)
3077 elseif exists("s:netrw_passwd")
3078 " if there's a change in hostname, require password re-entry
3079 unlet s:netrw_passwd
3080 endif
3081 if exists("netrw_port")
3082 unlet netrw_port
3083 endif
3084 endif
3085
3086 if exists("g:netrw_uid") && exists("s:netrw_passwd")
3087 let b:netrw_method = 3
3088 else
3089 let host= substitute(g:netrw_machine,'\..*$','','')
3090 if exists("s:netrw_hup[host]")
3091 call NetUserPass("ftp:".host)
3092
3093 elseif has("win32") && s:netrw_ftp_cmd =~# '-[sS]:'
3094 " call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3095 " call Decho(" g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3096 if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
3097 let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3098 " call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3099 endif
3100 let b:netrw_method= 2
3101 elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3102 " call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3103 let b:netrw_method= 2
3104 else
3105 if !exists("g:netrw_uid") || g:netrw_uid == ""
3106 call NetUserPass()
3107 elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3108 call NetUserPass(g:netrw_uid)
3109 " else just use current g:netrw_uid and s:netrw_passwd
3110 endif
3111 let b:netrw_method= 3
3112 endif
3113 endif
3114
3115 " Method#8: fetch {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003116 elseif match(a:choice,fetchurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003117 " call Decho("fetch://...",'~'.expand("<slnum>"))
3118 let b:netrw_method = 8
3119 let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3120 let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3121 let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3122 let b:netrw_fname = substitute(a:choice,fetchurm,'\5',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003123
Luca Saccarolac363ca12024-12-19 20:16:18 +01003124 " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003125 elseif match(a:choice,mipf) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003126 " call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003127 let b:netrw_method = 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01003128 let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3129 let g:netrw_uid = substitute(a:choice,mipf,'\2',"")
3130 let s:netrw_passwd = substitute(a:choice,mipf,'\3',"")
3131 let b:netrw_fname = substitute(a:choice,mipf,'\4',"")
3132 call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003133
Luca Saccarolac363ca12024-12-19 20:16:18 +01003134 " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
3135 elseif match(a:choice,mf) == 0
3136 " call Decho("(ftp) host file",'~'.expand("<slnum>"))
3137 if exists("g:netrw_uid") && exists("s:netrw_passwd")
3138 let b:netrw_method = 3
3139 let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3140 let b:netrw_fname = substitute(a:choice,mf,'\2',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003141
Luca Saccarolac363ca12024-12-19 20:16:18 +01003142 elseif s:FileReadable(expand("$HOME/.netrc"))
3143 let b:netrw_method = 2
3144 let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3145 let b:netrw_fname = substitute(a:choice,mf,'\2',"")
3146 endif
3147
3148 " Method#9: sftp://user@hostname/...path-to-file {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003149 elseif match(a:choice,sftpurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003150 " call Decho("sftp://...",'~'.expand("<slnum>"))
3151 let b:netrw_method = 9
3152 let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3153 let b:netrw_fname = substitute(a:choice,sftpurm,'\2',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003154
Luca Saccarolac363ca12024-12-19 20:16:18 +01003155 " Method#1: Issue an rcp: hostname:filename" (this one should be last) {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003156 elseif match(a:choice,rcphf) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003157 " call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3158 let b:netrw_method = 1
3159 let userid = substitute(a:choice,rcphf,'\2',"")
3160 let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3161 let b:netrw_fname = substitute(a:choice,rcphf,'\4',"")
3162 " call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3163 " call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3164 " call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3165 " call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3166 if userid != ""
3167 let g:netrw_uid= userid
3168 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003169
Luca Saccarolac363ca12024-12-19 20:16:18 +01003170 " Method#10: file://user@hostname/...path-to-file {{{3
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003171 elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003172 " call Decho("http[s]://...",'~'.expand("<slnum>"))
3173 let b:netrw_method = 10
3174 let b:netrw_fname = substitute(a:choice,fileurm,'\1',"")
3175 " call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003176
Luca Saccarolac363ca12024-12-19 20:16:18 +01003177 " Cannot Determine Method {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003178 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003179 if !exists("g:netrw_quiet")
3180 call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3181 endif
3182 let b:netrw_method = -1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003183 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02003184 "}}}3
Bram Moolenaar81695252004-12-29 20:58:21 +00003185
Bram Moolenaar81695252004-12-29 20:58:21 +00003186 if g:netrw_port != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01003187 " remove any leading [:#] from port number
3188 let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
Bram Moolenaaradc21822011-04-01 18:03:16 +02003189 elseif exists("netrw_port")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003190 " retain port number as implicit for subsequent ftp operations
3191 let g:netrw_port= netrw_port
Bram Moolenaar81695252004-12-29 20:58:21 +00003192 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003193
Luca Saccarolac363ca12024-12-19 20:16:18 +01003194 " call Decho("a:choice <".a:choice.">",'~'.expand("<slnum>"))
3195 " call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3196 " call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3197 " call Decho("g:netrw_port <".g:netrw_port.">",'~'.expand("<slnum>"))
3198 " if exists("g:netrw_uid") "Decho
3199 " call Decho("g:netrw_uid <".g:netrw_uid.">",'~'.expand("<slnum>"))
3200 " endif "Decho
3201 " if exists("s:netrw_passwd") "Decho
3202 " call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3203 " endif "Decho
3204 " call Decho("b:netrw_fname <".b:netrw_fname.">",'~'.expand("<slnum>"))
3205 " call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003206endfun
Bram Moolenaar071d4272004-06-13 20:20:40 +00003207
Bram Moolenaar9964e462007-05-05 17:54:07 +00003208" ---------------------------------------------------------------------
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +00003209" NetUserPass: set username and password for subsequent ftp transfer {{{2
Luca Saccarolac363ca12024-12-19 20:16:18 +01003210" Usage: :call NetUserPass() -- will prompt for userid and password
3211" :call NetUserPass("uid") -- will prompt for password
3212" :call NetUserPass("uid","password") -- sets global userid and password
3213" :call NetUserPass("ftp:host") -- looks up userid and password using hup dictionary
3214" :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
Bram Moolenaar071d4272004-06-13 20:20:40 +00003215fun! NetUserPass(...)
3216
Luca Saccarolac363ca12024-12-19 20:16:18 +01003217 " call Dfunc("NetUserPass() a:0=".a:0)
Bram Moolenaar5b435d62012-04-05 17:33:26 +02003218
Luca Saccarolac363ca12024-12-19 20:16:18 +01003219 if !exists('s:netrw_hup')
3220 let s:netrw_hup= {}
Bram Moolenaar97d62492012-11-15 21:28:22 +01003221 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +02003222
Luca Saccarolac363ca12024-12-19 20:16:18 +01003223 if a:0 == 0
3224 " case: no input arguments
Bram Moolenaar5b435d62012-04-05 17:33:26 +02003225
Luca Saccarolac363ca12024-12-19 20:16:18 +01003226 " change host and username if not previously entered; get new password
3227 if !exists("g:netrw_machine")
3228 let g:netrw_machine= input('Enter hostname: ')
Bram Moolenaara6878372014-03-22 21:02:50 +01003229 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003230 if !exists("g:netrw_uid") || g:netrw_uid == ""
3231 " get username (user-id) via prompt
3232 let g:netrw_uid= input('Enter username: ')
3233 endif
3234 " get password via prompting
3235 let s:netrw_passwd= inputsecret("Enter Password: ")
3236
3237 " set up hup database
3238 let host = substitute(g:netrw_machine,'\..*$','','')
3239 if !exists('s:netrw_hup[host]')
3240 let s:netrw_hup[host]= {}
3241 endif
3242 let s:netrw_hup[host].uid = g:netrw_uid
3243 let s:netrw_hup[host].passwd = s:netrw_passwd
3244
3245 elseif a:0 == 1
3246 " case: one input argument
3247
3248 if a:1 =~ '^ftp:'
3249 " get host from ftp:... url
3250 " access userid and password from hup (host-user-passwd) dictionary
3251 " call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3252 let host = substitute(a:1,'^ftp:','','')
3253 let host = substitute(host,'\..*','','')
3254 if exists("s:netrw_hup[host]")
3255 let g:netrw_uid = s:netrw_hup[host].uid
3256 let s:netrw_passwd = s:netrw_hup[host].passwd
3257 " call Decho("get s:netrw_hup[".host."].uid <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3258 " call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
3259 else
3260 let g:netrw_uid = input("Enter UserId: ")
3261 let s:netrw_passwd = inputsecret("Enter Password: ")
3262 endif
3263
3264 else
3265 " case: one input argument, not an url. Using it as a new user-id.
3266 " call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3267 if exists("g:netrw_machine")
3268 if g:netrw_machine =~ '[0-9.]\+'
3269 let host= g:netrw_machine
3270 else
3271 let host= substitute(g:netrw_machine,'\..*$','','')
3272 endif
3273 else
3274 let g:netrw_machine= input('Enter hostname: ')
3275 endif
3276 let g:netrw_uid = a:1
3277 " call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3278 if exists("g:netrw_passwd")
3279 " ask for password if one not previously entered
3280 let s:netrw_passwd= g:netrw_passwd
3281 else
3282 let s:netrw_passwd = inputsecret("Enter Password: ")
3283 endif
3284 endif
3285
3286 " call Decho("host<".host.">",'~'.expand("<slnum>"))
3287 if exists("host")
3288 if !exists('s:netrw_hup[host]')
3289 let s:netrw_hup[host]= {}
3290 endif
3291 let s:netrw_hup[host].uid = g:netrw_uid
3292 let s:netrw_hup[host].passwd = s:netrw_passwd
3293 endif
3294
3295 elseif a:0 == 2
3296 let g:netrw_uid = a:1
3297 let s:netrw_passwd = a:2
3298
3299 elseif a:0 == 3
3300 " enter hostname, user-id, and password into the hup dictionary
3301 let host = substitute(a:1,'^\a\+:','','')
3302 let host = substitute(host,'\..*$','','')
3303 if !exists('s:netrw_hup[host]')
3304 let s:netrw_hup[host]= {}
3305 endif
3306 let s:netrw_hup[host].uid = a:2
3307 let s:netrw_hup[host].passwd = a:3
3308 let g:netrw_uid = s:netrw_hup[host].uid
3309 let s:netrw_passwd = s:netrw_hup[host].passwd
3310 " call Decho("set s:netrw_hup[".host."].uid <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3311 " call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
Bram Moolenaar5b435d62012-04-05 17:33:26 +02003312 endif
3313
Luca Saccarolac363ca12024-12-19 20:16:18 +01003314 " call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
Bram Moolenaar071d4272004-06-13 20:20:40 +00003315endfun
Bram Moolenaar071d4272004-06-13 20:20:40 +00003316
Bram Moolenaar85850f32019-07-19 22:05:51 +02003317" =================================
Bram Moolenaar9964e462007-05-05 17:54:07 +00003318" Shared Browsing Support: {{{1
Bram Moolenaar85850f32019-07-19 22:05:51 +02003319" =================================
Bram Moolenaar071d4272004-06-13 20:20:40 +00003320
Bram Moolenaar69a7cb42004-06-20 12:51:53 +00003321" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00003322" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3323fun! s:ExplorePatHls(pattern)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003324 " call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
Bram Moolenaar446cb832008-06-24 21:56:24 +00003325 let repat= substitute(a:pattern,'^**/\{1,2}','','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01003326 " call Decho("repat<".repat.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00003327 let repat= escape(repat,'][.\')
Luca Saccarolac363ca12024-12-19 20:16:18 +01003328 " call Decho("repat<".repat.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00003329 let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003330 " call Dret("s:ExplorePatHls repat<".repat.">")
Bram Moolenaar446cb832008-06-24 21:56:24 +00003331 return repat
Bram Moolenaar9964e462007-05-05 17:54:07 +00003332endfun
3333
3334" ---------------------------------------------------------------------
Bram Moolenaar5c736222010-01-06 20:54:52 +01003335" s:NetrwBookHistHandler: {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00003336" 0: (user: <mb>) bookmark current directory
3337" 1: (user: <gb>) change to the bookmarked directory
3338" 2: (user: <qb>) list bookmarks
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003339" 3: (browsing) records current directory history
3340" 4: (user: <u>) go up (previous) directory, using history
3341" 5: (user: <U>) go down (next) directory, using history
Bram Moolenaar446cb832008-06-24 21:56:24 +00003342" 6: (user: <mB>) delete bookmark
Bram Moolenaar5c736222010-01-06 20:54:52 +01003343fun! s:NetrwBookHistHandler(chg,curdir)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003344 " call Dfunc("s:NetrwBookHistHandler(chg=".a:chg." curdir<".a:curdir.">) cnt=".v:count." histcnt=".g:netrw_dirhistcnt." histmax=".g:netrw_dirhistmax)
Bram Moolenaarff034192013-04-24 18:51:19 +02003345 if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003346 " " call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3347 return
Bram Moolenaarff034192013-04-24 18:51:19 +02003348 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003349
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003350 let ykeep = @@
3351 let curbufnr = bufnr("%")
3352
Bram Moolenaar9964e462007-05-05 17:54:07 +00003353 if a:chg == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003354 " bookmark the current directory
3355 " call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3356 if exists("s:netrwmarkfilelist_{curbufnr}")
3357 call s:NetrwBookmark(0)
3358 echo "bookmarked marked files"
3359 else
3360 call s:MakeBookmark(a:curdir)
3361 echo "bookmarked the current directory"
3362 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003363
Luca Saccarolac363ca12024-12-19 20:16:18 +01003364 try
3365 call s:NetrwBookHistSave()
3366 catch
3367 endtry
KSR-Yasudaf4498252023-10-06 03:34:17 +09003368
Bram Moolenaar9964e462007-05-05 17:54:07 +00003369 elseif a:chg == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01003370 " change to the bookmarked directory
3371 " call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3372 if exists("g:netrw_bookmarklist[v:count-1]")
3373 " call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3374 exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3375 else
3376 echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3377 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003378
3379 elseif a:chg == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01003380 " redraw!
3381 let didwork= 0
3382 " list user's bookmarks
3383 " call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3384 if exists("g:netrw_bookmarklist")
3385 " call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3386 let cnt= 1
3387 for bmd in g:netrw_bookmarklist
3388 " call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3389 echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3390 let didwork = 1
3391 let cnt = cnt + 1
3392 endfor
3393 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003394
Luca Saccarolac363ca12024-12-19 20:16:18 +01003395 " list directory history
3396 " Note: history is saved only when PerformListing is done;
3397 " ie. when netrw can re-use a netrw buffer, the current directory is not saved in the history.
3398 let cnt = g:netrw_dirhistcnt
3399 let first = 1
3400 let histcnt = 0
3401 if g:netrw_dirhistmax > 0
3402 while ( first || cnt != g:netrw_dirhistcnt )
3403 " call Decho("first=".first." cnt=".cnt." dirhistcnt=".g:netrw_dirhistcnt,'~'.expand("<slnum>"))
3404 if exists("g:netrw_dirhist_{cnt}")
3405 " call Decho("Netrw History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3406 echo printf("Netrw History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3407 let didwork= 1
3408 endif
3409 let histcnt = histcnt + 1
3410 let first = 0
3411 let cnt = ( cnt - 1 ) % g:netrw_dirhistmax
3412 if cnt < 0
3413 let cnt= cnt + g:netrw_dirhistmax
3414 endif
3415 endwhile
3416 else
3417 let g:netrw_dirhistcnt= 0
3418 endif
3419 if didwork
3420 call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3421 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003422
3423 elseif a:chg == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01003424 " saves most recently visited directories (when they differ)
3425 " call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3426 if !exists("g:netrw_dirhistcnt") || !exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") || g:netrw_dirhist_{g:netrw_dirhistcnt} != a:curdir
3427 if g:netrw_dirhistmax > 0
3428 let g:netrw_dirhistcnt = ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3429 let g:netrw_dirhist_{g:netrw_dirhistcnt} = a:curdir
3430 endif
3431 " call Decho("save dirhist#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
Bram Moolenaaradc21822011-04-01 18:03:16 +02003432 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003433
3434 elseif a:chg == 4
Luca Saccarolac363ca12024-12-19 20:16:18 +01003435 " u: change to the previous directory stored on the history list
3436 " call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
Bram Moolenaaradc21822011-04-01 18:03:16 +02003437 if g:netrw_dirhistmax > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003438 let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - v:count1 ) % g:netrw_dirhistmax
3439 if g:netrw_dirhistcnt < 0
3440 let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3441 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02003442 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003443 let g:netrw_dirhistcnt= 0
Bram Moolenaaradc21822011-04-01 18:03:16 +02003444 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003445 if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3446 " call Decho("changedir u#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3447 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3448 setl ma noro
3449 " call Decho("setl ma noro",'~'.expand("<slnum>"))
3450 sil! NetrwKeepj %d _
3451 setl nomod
3452 " call Decho("setl nomod",'~'.expand("<slnum>"))
3453 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3454 endif
3455 " call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3456 exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3457 else
3458 if g:netrw_dirhistmax > 0
3459 let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + v:count1 ) % g:netrw_dirhistmax
3460 else
3461 let g:netrw_dirhistcnt= 0
3462 endif
3463 echo "Sorry, no predecessor directory exists yet"
3464 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003465
3466 elseif a:chg == 5
Luca Saccarolac363ca12024-12-19 20:16:18 +01003467 " U: change to the subsequent directory stored on the history list
3468 " call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3469 if g:netrw_dirhistmax > 0
3470 let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3471 if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3472 " call Decho("changedir U#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3473 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3474 " call Decho("setl ma noro",'~'.expand("<slnum>"))
3475 setl ma noro
3476 sil! NetrwKeepj %d _
3477 " call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3478 " call Decho("setl nomod",'~'.expand("<slnum>"))
3479 setl nomod
3480 " call Decho("(set nomod) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3481 endif
3482 " call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3483 exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3484 else
3485 let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - 1 ) % g:netrw_dirhistmax
3486 if g:netrw_dirhistcnt < 0
3487 let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3488 endif
3489 echo "Sorry, no successor directory exists yet"
3490 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02003491 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003492 let g:netrw_dirhistcnt= 0
3493 echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
Bram Moolenaar9964e462007-05-05 17:54:07 +00003494 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003495
3496 elseif a:chg == 6
Luca Saccarolac363ca12024-12-19 20:16:18 +01003497 " call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3498 if exists("s:netrwmarkfilelist_{curbufnr}")
3499 call s:NetrwBookmark(1)
3500 echo "removed marked files from bookmarks"
3501 else
3502 " delete the v:count'th bookmark
3503 let iremove = v:count
3504 let dremove = g:netrw_bookmarklist[iremove - 1]
3505 " call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3506 call s:MergeBookmarks()
3507 " call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3508 NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3509 echo "removed ".dremove." from g:netrw_bookmarklist"
3510 " call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3511 endif
3512 " call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
KSR-Yasudaf4498252023-10-06 03:34:17 +09003513
Luca Saccarolac363ca12024-12-19 20:16:18 +01003514 try
3515 call s:NetrwBookHistSave()
3516 catch
3517 endtry
Bram Moolenaar9964e462007-05-05 17:54:07 +00003518 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003519 call s:NetrwBookmarkMenu()
Bram Moolenaarff034192013-04-24 18:51:19 +02003520 call s:NetrwTgtMenu()
Bram Moolenaar97d62492012-11-15 21:28:22 +01003521 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01003522 " call Dret("s:NetrwBookHistHandler")
Bram Moolenaar5c736222010-01-06 20:54:52 +01003523endfun
3524
3525" ---------------------------------------------------------------------
3526" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003527" Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
Bram Moolenaar5c736222010-01-06 20:54:52 +01003528" Sister function: s:NetrwBookHistSave()
3529fun! s:NetrwBookHistRead()
Luca Saccarolac363ca12024-12-19 20:16:18 +01003530 " call Dfunc("s:NetrwBookHistRead()")
Bram Moolenaarff034192013-04-24 18:51:19 +02003531 if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003532 " call Dret("s:NetrwBookHistRead - nothing read (suppressed due to dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a").")")
3533 return
Bram Moolenaarff034192013-04-24 18:51:19 +02003534 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01003535 let ykeep= @@
Bram Moolenaar85850f32019-07-19 22:05:51 +02003536
3537 " read bookmarks
Bram Moolenaar5c736222010-01-06 20:54:52 +01003538 if !exists("s:netrw_initbookhist")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003539 let home = s:NetrwHome()
3540 let savefile= home."/.netrwbook"
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003541 if filereadable(s:NetrwFile(savefile))
Luca Saccarolac363ca12024-12-19 20:16:18 +01003542 " call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3543 exe "keepalt NetrwKeepj so ".savefile
Bram Moolenaaradc21822011-04-01 18:03:16 +02003544 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003545
3546 " read history
3547 if g:netrw_dirhistmax > 0
3548 let savefile= home."/.netrwhist"
3549 if filereadable(s:NetrwFile(savefile))
3550 " call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3551 exe "keepalt NetrwKeepj so ".savefile
3552 endif
3553 let s:netrw_initbookhist= 1
3554 au VimLeave * call s:NetrwBookHistSave()
3555 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003556 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02003557
Bram Moolenaar97d62492012-11-15 21:28:22 +01003558 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01003559 " call Decho("dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a"),'~'.expand("<slnum>"))
3560 " call Decho("dirhistcnt=".(exists("g:netrw_dirhistcnt")? g:netrw_dirhistcnt : "n/a"),'~'.expand("<slnum>"))
3561 " call Dret("s:NetrwBookHistRead")
Bram Moolenaar5c736222010-01-06 20:54:52 +01003562endfun
3563
3564" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02003565" s:NetrwBookHistSave: this function saves bookmarks and history to files {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +01003566" Sister function: s:NetrwBookHistRead()
3567" I used to do this via viminfo but that appears to
3568" be unreliable for long-term storage
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003569" If g:netrw_dirhistmax is <= 0, no history or bookmarks
3570" will be saved.
Bram Moolenaar85850f32019-07-19 22:05:51 +02003571" (s:NetrwBookHistHandler(3,...) used to record history)
Bram Moolenaar5c736222010-01-06 20:54:52 +01003572fun! s:NetrwBookHistSave()
Luca Saccarolac363ca12024-12-19 20:16:18 +01003573 " call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt)
Bram Moolenaarff034192013-04-24 18:51:19 +02003574 if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003575 " call Dret("s:NetrwBookHistSave : nothing saved (dirhistmax=".g:netrw_dirhistmax.")")
3576 return
Bram Moolenaaradc21822011-04-01 18:03:16 +02003577 endif
3578
Bram Moolenaar5c736222010-01-06 20:54:52 +01003579 let savefile= s:NetrwHome()."/.netrwhist"
Luca Saccarolac363ca12024-12-19 20:16:18 +01003580 " call Decho("savefile<".savefile.">",'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +01003581 1split
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02003582
3583 " setting up a new buffer which will become .netrwhist
Bram Moolenaar5c736222010-01-06 20:54:52 +01003584 call s:NetrwEnew()
Luca Saccarolac363ca12024-12-19 20:16:18 +01003585 " call Decho("case g:netrw_use_noswf=".g:netrw_use_noswf.(exists("+acd")? " +acd" : " -acd"),'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003586 if g:netrw_use_noswf
Luca Saccarolac363ca12024-12-19 20:16:18 +01003587 setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003588 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003589 setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003590 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02003591 setl nocin noai noci magic nospell nohid wig= noaw
3592 setl ma noro write
3593 if exists("+acd") | setl noacd | endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003594 sil! NetrwKeepj keepalt %d _
Bram Moolenaar5c736222010-01-06 20:54:52 +01003595
Bram Moolenaar85850f32019-07-19 22:05:51 +02003596 " rename enew'd file: .netrwhist -- no attempt to merge
3597 " record dirhistmax and current dirhistcnt
3598 " save history
Luca Saccarolac363ca12024-12-19 20:16:18 +01003599 " call Decho("saving history: dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt." lastline=".line("$"),'~'.expand("<slnum>"))
Bram Moolenaarff034192013-04-24 18:51:19 +02003600 sil! keepalt file .netrwhist
Bram Moolenaar5c736222010-01-06 20:54:52 +01003601 call setline(1,"let g:netrw_dirhistmax =".g:netrw_dirhistmax)
Bram Moolenaar85850f32019-07-19 22:05:51 +02003602 call setline(2,"let g:netrw_dirhistcnt =".g:netrw_dirhistcnt)
3603 if g:netrw_dirhistmax > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003604 let lastline = line("$")
3605 let cnt = g:netrw_dirhistcnt
3606 let first = 1
3607 while ( first || cnt != g:netrw_dirhistcnt )
3608 let lastline= lastline + 1
3609 if exists("g:netrw_dirhist_{cnt}")
3610 call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3611 " call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("<slnum>"))
3612 endif
3613 let first = 0
3614 let cnt = ( cnt - 1 ) % g:netrw_dirhistmax
3615 if cnt < 0
3616 let cnt= cnt + g:netrw_dirhistmax
3617 endif
3618 endwhile
3619 exe "sil! w! ".savefile
3620 " call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02003621 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003622
Bram Moolenaar85850f32019-07-19 22:05:51 +02003623 " save bookmarks
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003624 sil NetrwKeepj %d _
Bram Moolenaar5c736222010-01-06 20:54:52 +01003625 if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
Luca Saccarolac363ca12024-12-19 20:16:18 +01003626 " call Decho("saving bookmarks",'~'.expand("<slnum>"))
3627 " merge and write .netrwbook
3628 let savefile= s:NetrwHome()."/.netrwbook"
Bram Moolenaar5c736222010-01-06 20:54:52 +01003629
Luca Saccarolac363ca12024-12-19 20:16:18 +01003630 if filereadable(s:NetrwFile(savefile))
3631 let booklist= deepcopy(g:netrw_bookmarklist)
3632 exe "sil NetrwKeepj keepalt so ".savefile
3633 for bdm in booklist
3634 if index(g:netrw_bookmarklist,bdm) == -1
3635 call add(g:netrw_bookmarklist,bdm)
3636 endif
3637 endfor
3638 call sort(g:netrw_bookmarklist)
3639 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003640
Luca Saccarolac363ca12024-12-19 20:16:18 +01003641 " construct and save .netrwbook
3642 call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3643 exe "sil! w! ".savefile
3644 " call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +01003645 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02003646
3647 " cleanup -- remove buffer used to construct history
Bram Moolenaar5c736222010-01-06 20:54:52 +01003648 let bgone= bufnr("%")
3649 q!
Bram Moolenaarff034192013-04-24 18:51:19 +02003650 exe "keepalt ".bgone."bwipe!"
Bram Moolenaar5c736222010-01-06 20:54:52 +01003651
Luca Saccarolac363ca12024-12-19 20:16:18 +01003652 " call Dret("s:NetrwBookHistSave")
Bram Moolenaar9964e462007-05-05 17:54:07 +00003653endfun
3654
3655" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00003656" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3657" list of the contents of a local or remote directory. It is assumed that the
3658" g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3659" with the requested remote hostname first.
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003660" Often called via: Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
Bram Moolenaar446cb832008-06-24 21:56:24 +00003661fun! s:NetrwBrowse(islocal,dirname)
3662 if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
Bram Moolenaara6878372014-03-22 21:02:50 +01003663
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003664 " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3665 " This is useful when one edits a local file, then :e ., then :Rex
3666 if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01003667 let w:netrw_rexfile= bufname("#")
Bram Moolenaar5c736222010-01-06 20:54:52 +01003668 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003669
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003670 " s:NetrwBrowse : initialize history {{{3
3671 if !exists("s:netrw_initbookhist")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003672 NetrwKeepj call s:NetrwBookHistRead()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003673 endif
3674
3675 " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003676 if a:dirname !~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003677 let dirname= simplify(a:dirname)
Bram Moolenaar5c736222010-01-06 20:54:52 +01003678 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003679 let dirname= a:dirname
Bram Moolenaar5c736222010-01-06 20:54:52 +01003680 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003681
Bram Moolenaar85850f32019-07-19 22:05:51 +02003682 " repoint t:netrw_lexbufnr if appropriate
3683 if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
Luca Saccarolac363ca12024-12-19 20:16:18 +01003684 let repointlexbufnr= 1
Bram Moolenaar85850f32019-07-19 22:05:51 +02003685 endif
3686
3687 " s:NetrwBrowse : sanity checks: {{{3
Bram Moolenaar446cb832008-06-24 21:56:24 +00003688 if exists("s:netrw_skipbrowse")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003689 unlet s:netrw_skipbrowse
3690 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003691 endif
3692 if !exists("*shellescape")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003693 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3694 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003695 endif
3696 if !exists("*fnameescape")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003697 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3698 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003699 endif
3700
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003701 " s:NetrwBrowse : save options: {{{3
Bram Moolenaar85850f32019-07-19 22:05:51 +02003702 call s:NetrwOptionsSave("w:")
Bram Moolenaar446cb832008-06-24 21:56:24 +00003703
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003704 " s:NetrwBrowse : re-instate any marked files {{{3
Bram Moolenaar85850f32019-07-19 22:05:51 +02003705 if has("syntax") && exists("g:syntax_on") && g:syntax_on
Luca Saccarolac363ca12024-12-19 20:16:18 +01003706 if exists("s:netrwmarkfilelist_{bufnr('%')}")
3707 exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3708 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003709 endif
3710
3711 if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01003712 " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3713 if s:NetrwLcd(dirname)
3714 return
3715 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003716
Bram Moolenaar5c736222010-01-06 20:54:52 +01003717 elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003718 " s:NetrwBrowse : remote regular file handler {{{3
3719 if bufname(dirname) != ""
3720 exe "NetrwKeepj b ".bufname(dirname)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003721 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003722 " attempt transfer of remote regular file
Bram Moolenaar446cb832008-06-24 21:56:24 +00003723
Luca Saccarolac363ca12024-12-19 20:16:18 +01003724 " remove any filetype indicator from end of dirname, except for the
3725 " "this is a directory" indicator (/).
3726 " There shouldn't be one of those here, anyway.
3727 let path= substitute(dirname,'[*=@|]\r\=$','','e')
3728 call s:RemotePathAnalysis(dirname)
3729
3730 " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3731 call s:NetrwEnew(dirname)
3732 call s:NetrwOptionsSafe(a:islocal)
3733 setl ma noro
3734 let b:netrw_curdir = dirname
3735 let url = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3736 call s:NetrwBufRename(url)
3737 exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3738 sil call netrw#NetRead(2,url)
3739 " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3740 if s:path =~ '.bz2'
3741 exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3742 elseif s:path =~ '.gz'
3743 exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3744 elseif s:path =~ '.gz'
3745 exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3746 else
3747 exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3748 endif
3749 endif
3750
3751 " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3752 call s:SetBufWinVars()
3753 call s:NetrwOptionsRestore("w:")
3754 setl ma nomod noro
3755 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003756 endif
3757
Bram Moolenaaradc21822011-04-01 18:03:16 +02003758 " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
Bram Moolenaar446cb832008-06-24 21:56:24 +00003759 call s:UseBufWinVars()
3760
3761 " set up some variables {{{3
3762 let b:netrw_browser_active = 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01003763 let dirname = dirname
Bram Moolenaar446cb832008-06-24 21:56:24 +00003764 let s:last_sort_by = g:netrw_sort_by
3765
3766 " set up menu {{{3
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003767 NetrwKeepj call s:NetrwMenu(1)
Bram Moolenaar446cb832008-06-24 21:56:24 +00003768
Bram Moolenaar97d62492012-11-15 21:28:22 +01003769 " get/set-up buffer {{{3
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003770 let svpos = winsaveview()
Tom Benham64a536d2024-11-07 21:15:03 +01003771
3772 " NetrwGetBuffer might change buffers but s:rexposn_X was set for the
3773 " previous buffer
3774 let prevbufnr = bufnr('%')
Bram Moolenaar446cb832008-06-24 21:56:24 +00003775 let reusing= s:NetrwGetBuffer(a:islocal,dirname)
Tom Benham64a536d2024-11-07 21:15:03 +01003776 if exists("s:rexposn_".prevbufnr)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003777 let s:rexposn_{bufnr('%')} = s:rexposn_{prevbufnr}
Tom Benham64a536d2024-11-07 21:15:03 +01003778 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003779
Bram Moolenaar446cb832008-06-24 21:56:24 +00003780 " maintain markfile highlighting
Bram Moolenaar85850f32019-07-19 22:05:51 +02003781 if has("syntax") && exists("g:syntax_on") && g:syntax_on
Luca Saccarolac363ca12024-12-19 20:16:18 +01003782 if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3783 exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3784 else
3785 2match none
3786 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003787 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02003788 if reusing && line("$") > 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01003789 call s:NetrwOptionsRestore("w:")
3790 setl noma nomod nowrap
3791 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003792 endif
3793
3794 " set b:netrw_curdir to the new directory name {{{3
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +02003795 let b:netrw_curdir= dirname
Bram Moolenaar446cb832008-06-24 21:56:24 +00003796 if b:netrw_curdir =~ '[/\\]$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003797 let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
Bram Moolenaar446cb832008-06-24 21:56:24 +00003798 endif
Nir Lichtman1e34b952024-05-08 19:19:34 +02003799 if b:netrw_curdir =~ '\a:$' && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003800 let b:netrw_curdir= b:netrw_curdir."/"
Bram Moolenaar8d043172014-01-23 14:24:41 +01003801 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003802 if b:netrw_curdir == ''
Luca Saccarolac363ca12024-12-19 20:16:18 +01003803 if has("amiga")
3804 " On the Amiga, the empty string connotes the current directory
3805 let b:netrw_curdir= getcwd()
3806 else
3807 " under unix, when the root directory is encountered, the result
3808 " from the preceding substitute is an empty string.
3809 let b:netrw_curdir= '/'
3810 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003811 endif
3812 if !a:islocal && b:netrw_curdir !~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003813 let b:netrw_curdir= b:netrw_curdir.'/'
Bram Moolenaar446cb832008-06-24 21:56:24 +00003814 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003815
3816 " ------------
3817 " (local only) {{{3
3818 " ------------
3819 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01003820 " Set up ShellCmdPost handling. Append current buffer to browselist
3821 call s:LocalFastBrowser()
Bram Moolenaar446cb832008-06-24 21:56:24 +00003822
Luca Saccarolac363ca12024-12-19 20:16:18 +01003823 " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3824 if !g:netrw_keepdir
3825 if !exists("&l:acd") || !&l:acd
3826 if s:NetrwLcd(b:netrw_curdir)
3827 return
3828 endif
3829 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003830 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003831
Luca Saccarolac363ca12024-12-19 20:16:18 +01003832 " --------------------------------
3833 " remote handling: {{{3
3834 " --------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00003835 else
Bram Moolenaar446cb832008-06-24 21:56:24 +00003836
Luca Saccarolac363ca12024-12-19 20:16:18 +01003837 " analyze dirname and g:netrw_list_cmd {{{3
3838 if dirname =~# "^NetrwTreeListing\>"
3839 let dirname= b:netrw_curdir
3840 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3841 let dirname= substitute(b:netrw_curdir,'\\','/','g')
3842 if dirname !~ '/$'
3843 let dirname= dirname.'/'
3844 endif
3845 let b:netrw_curdir = dirname
3846 else
3847 let dirname = substitute(dirname,'\\','/','g')
Bram Moolenaar446cb832008-06-24 21:56:24 +00003848 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003849
Luca Saccarolac363ca12024-12-19 20:16:18 +01003850 let dirpat = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3851 if dirname !~ dirpat
3852 if !exists("g:netrw_quiet")
3853 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3854 endif
3855 NetrwKeepj call s:NetrwOptionsRestore("w:")
3856 setl noma nomod nowrap
3857 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003858 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003859 let b:netrw_curdir= dirname
Bram Moolenaar446cb832008-06-24 21:56:24 +00003860 endif " (additional remote handling)
3861
Bram Moolenaar85850f32019-07-19 22:05:51 +02003862 " -------------------------------
3863 " Perform Directory Listing: {{{3
3864 " -------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003865 NetrwKeepj call s:NetrwMaps(a:islocal)
3866 NetrwKeepj call s:NetrwCommands(a:islocal)
3867 NetrwKeepj call s:PerformListing(a:islocal)
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003868
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003869 " restore option(s)
Bram Moolenaar85850f32019-07-19 22:05:51 +02003870 call s:NetrwOptionsRestore("w:")
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003871
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003872 " If there is a rexposn: restore position with rexposn
3873 " Otherwise : set rexposn
3874 if exists("s:rexposn_".bufnr("%"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01003875 NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
3876 if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
3877 NetrwKeepj exe w:netrw_bannercnt
3878 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003879 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003880 NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003881 endif
Bram Moolenaar15146672011-10-20 22:22:38 +02003882 if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003883 let &l:bexpr= "netrw#BalloonHelp()"
3884 setl beval
Bram Moolenaaradc21822011-04-01 18:03:16 +02003885 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003886
Bram Moolenaar85850f32019-07-19 22:05:51 +02003887 " repoint t:netrw_lexbufnr if appropriate
3888 if exists("repointlexbufnr")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003889 let t:netrw_lexbufnr= bufnr("%")
Bram Moolenaar85850f32019-07-19 22:05:51 +02003890 endif
3891
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003892 " restore position
3893 if reusing
Luca Saccarolac363ca12024-12-19 20:16:18 +01003894 call winrestview(svpos)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003895 endif
3896
Bram Moolenaara6878372014-03-22 21:02:50 +01003897 " The s:LocalBrowseRefresh() function is called by an autocmd
Bram Moolenaar85850f32019-07-19 22:05:51 +02003898 " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow or medium speed).
3899 " However, s:NetrwBrowse() causes the FocusGained event to fire the first time.
Bram Moolenaar446cb832008-06-24 21:56:24 +00003900 return
3901endfun
3902
3903" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003904" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
3905" may not apply correctly; ie. netrw's idea of the current directory may
3906" differ from vim's. This function insures that netrw's idea of the current
3907" directory is used.
Bram Moolenaar85850f32019-07-19 22:05:51 +02003908" Returns a path to the file specified by a:fname
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003909fun! s:NetrwFile(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003910 " "" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
3911 " "" call Decho("g:netrw_keepdir =".(exists("g:netrw_keepdir")? g:netrw_keepdir : 'n/a'),'~'.expand("<slnum>"))
3912 " "" call Decho("g:netrw_cygwin =".(exists("g:netrw_cygwin")? g:netrw_cygwin : 'n/a'),'~'.expand("<slnum>"))
3913 " "" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
3914 " "" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003915
3916 " clean up any leading treedepthstring
3917 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01003918 let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
3919 " "" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003920 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003921 let fname= a:fname
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003922 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003923
3924 if g:netrw_keepdir
Luca Saccarolac363ca12024-12-19 20:16:18 +01003925 " vim's idea of the current directory possibly may differ from netrw's
3926 if !exists("b:netrw_curdir")
3927 let b:netrw_curdir= getcwd()
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003928 endif
3929
Luca Saccarolac363ca12024-12-19 20:16:18 +01003930 if !exists("g:netrw_cygwin") && has("win32")
3931 if fname =~ '^\' || fname =~ '^\a:\'
3932 " windows, but full path given
3933 let ret= fname
3934 " "" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3935 else
3936 " windows, relative path given
3937 let ret= s:ComposePath(b:netrw_curdir,fname)
3938 " "" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3939 endif
3940
3941 elseif fname =~ '^/'
3942 " not windows, full path given
3943 let ret= fname
3944 " "" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3945 else
3946 " not windows, relative path given
3947 let ret= s:ComposePath(b:netrw_curdir,fname)
3948 " "" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3949 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003950 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003951 " vim and netrw agree on the current directory
3952 let ret= fname
3953 " "" call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
3954 " "" call Decho("vim directory: ".getcwd(),'~'.expand("<slnum>"))
3955 " "" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003956 endif
3957
Luca Saccarolac363ca12024-12-19 20:16:18 +01003958 " "" call Dret("s:NetrwFile ".ret)
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003959 return ret
3960endfun
3961
3962" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00003963" s:NetrwFileInfo: supports qf (query for file information) {{{2
3964fun! s:NetrwFileInfo(islocal,fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003965 " call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
Bram Moolenaar97d62492012-11-15 21:28:22 +01003966 let ykeep= @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00003967 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01003968 let lsopt= "-lsad"
3969 if g:netrw_sizestyle =~# 'H'
3970 let lsopt= "-lsadh"
3971 elseif g:netrw_sizestyle =~# 'h'
3972 let lsopt= "-lsadh --si"
3973 endif
3974 " call Decho("(s:NetrwFileInfo) lsopt<".lsopt.">")
3975 if (has("unix") || has("macunix")) && executable("/bin/ls")
Bram Moolenaar8d043172014-01-23 14:24:41 +01003976
Luca Saccarolac363ca12024-12-19 20:16:18 +01003977 if getline(".") == "../"
3978 echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
3979 " call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
Bram Moolenaar8d043172014-01-23 14:24:41 +01003980
Luca Saccarolac363ca12024-12-19 20:16:18 +01003981 elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
3982 echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
3983 " call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
Bram Moolenaar8d043172014-01-23 14:24:41 +01003984
Luca Saccarolac363ca12024-12-19 20:16:18 +01003985 elseif exists("b:netrw_curdir")
3986 echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
3987 " call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
Bram Moolenaar8d043172014-01-23 14:24:41 +01003988
Luca Saccarolac363ca12024-12-19 20:16:18 +01003989 else
3990 " call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
3991 echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
3992 " call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
3993 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003994 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003995 " use vim functions to return information about file below cursor
3996 " call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
3997 if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
3998 let fname= substitute(a:fname,".$","","")
3999 else
4000 let fname= a:fname
4001 endif
4002 let t = getftime(s:NetrwFile(fname))
4003 let sz = getfsize(s:NetrwFile(fname))
4004 if g:netrw_sizestyle =~# "[hH]"
4005 let sz= s:NetrwHumanReadable(sz)
4006 endif
4007 echo a:fname.": ".sz." ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
4008 " call Decho("fname.": ".sz." ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004009 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004010 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004011 echo "sorry, \"qf\" not supported yet for remote files"
Bram Moolenaar446cb832008-06-24 21:56:24 +00004012 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01004013 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01004014 " call Dret("s:NetrwFileInfo")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004015endfun
4016
4017" ---------------------------------------------------------------------
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004018" s:NetrwFullPath: returns the full path to a directory and/or file {{{2
4019fun! s:NetrwFullPath(filename)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004020 " " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004021 let filename= a:filename
4022 if filename !~ '^/'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004023 let filename= resolve(getcwd().'/'.filename)
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004024 endif
4025 if filename != "/" && filename =~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004026 let filename= substitute(filename,'/$','','')
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004027 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004028 " " call Dret("s:NetrwFullPath <".filename.">")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004029 return filename
4030endfun
4031
4032" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02004033" s:NetrwGetBuffer: [get a new|find an old netrw] buffer for a netrw listing {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00004034" returns 0=cleared buffer
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004035" 1=re-used buffer (buffer not cleared)
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004036" Nov 09, 2020: tst952 shows that when user does :set hidden that NetrwGetBuffer will come up with a [No Name] buffer (hid fix)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004037fun! s:NetrwGetBuffer(islocal,dirname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004038 " call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
4039 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo." hid=".&hid,'~'.expand("<slnum>"))
4040 " call Decho("netrwbuf dictionary=".(exists("s:netrwbuf")? string(s:netrwbuf) : 'n/a'),'~'.expand("<slnum>"))
4041 " call Dredir("ls!","s:NetrwGetBuffer")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004042 let dirname= a:dirname
4043
4044 " re-use buffer if possible {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01004045 " call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004046 if !exists("s:netrwbuf")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004047 " call Decho(" s:netrwbuf initialized to {}",'~'.expand("<slnum>"))
4048 let s:netrwbuf= {}
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004049 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004050 " call Decho(" s:netrwbuf =".string(s:netrwbuf),'~'.expand("<slnum>"))
4051 " call Decho(" w:netrw_liststyle =".(exists("w:netrw_liststyle")? w:netrw_liststyle : "n/a"),'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004052
4053 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004054 let bufnum = -1
Bram Moolenaar85850f32019-07-19 22:05:51 +02004055
Luca Saccarolac363ca12024-12-19 20:16:18 +01004056 if !empty(s:netrwbuf) && has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4057 if has_key(s:netrwbuf,"NetrwTreeListing")
4058 let bufnum= s:netrwbuf["NetrwTreeListing"]
4059 else
4060 let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4061 endif
4062 " call Decho(" NetrwTreeListing: bufnum#".bufnum,'~'.expand("<slnum>"))
4063 if !bufexists(bufnum)
4064 call remove(s:netrwbuf,"NetrwTreeListing")
4065 let bufnum= -1
4066 endif
4067 elseif bufnr("NetrwTreeListing") != -1
4068 let bufnum= bufnr("NetrwTreeListing")
4069 " call Decho(" NetrwTreeListing".": bufnum#".bufnum,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004070 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004071 " call Decho(" did not find a NetrwTreeListing buffer",'~'.expand("<slnum>"))
4072 let bufnum= -1
Bram Moolenaar85850f32019-07-19 22:05:51 +02004073 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02004074
4075 elseif has_key(s:netrwbuf,s:NetrwFullPath(dirname))
Luca Saccarolac363ca12024-12-19 20:16:18 +01004076 let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4077 " call Decho(" lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum,'~'.expand("<slnum>"))
4078 if !bufexists(bufnum)
4079 call remove(s:netrwbuf,s:NetrwFullPath(dirname))
4080 let bufnum= -1
4081 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02004082
Bram Moolenaar446cb832008-06-24 21:56:24 +00004083 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004084 " call Decho(" lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key",'~'.expand("<slnum>"))
4085 let bufnum= -1
Bram Moolenaar446cb832008-06-24 21:56:24 +00004086 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004087 " call Decho(" bufnum#".bufnum,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004088
Bram Moolenaar71badf92023-04-22 22:40:14 +01004089 " highjack the current buffer
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004090 " IF the buffer already has the desired name
4091 " AND it is empty
4092 let curbuf = bufname("%")
4093 if curbuf == '.'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004094 let curbuf = getcwd()
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004095 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004096 " call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
4097 " call Decho("deciding if netrw may highjack the current buffer#".bufnr("%")."<".curbuf.">",'~'.expand("<slnum>"))
4098 " call Decho("..dirname<".dirname."> IF dirname == bufname",'~'.expand("<slnum>"))
4099 " call Decho("..curbuf<".curbuf.">",'~'.expand("<slnum>"))
4100 " call Decho("..line($)=".line("$")." AND this is 1",'~'.expand("<slnum>"))
4101 " call Decho("..getline(%)<".getline("%")."> AND this line is empty",'~'.expand("<slnum>"))
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004102 if dirname == curbuf && line("$") == 1 && getline("%") == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01004103 " call Dret("s:NetrwGetBuffer 0<cleared buffer> : highjacking buffer#".bufnr("%"))
4104 return 0
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004105 else " DEBUG
Luca Saccarolac363ca12024-12-19 20:16:18 +01004106 " call Decho("..did NOT highjack buffer",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004107 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004108 " Aug 14, 2021: was thinking about looking for a [No Name] buffer here and using it, but that might cause problems
Bram Moolenaar446cb832008-06-24 21:56:24 +00004109
4110 " get enew buffer and name it -or- re-use buffer {{{3
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004111 if bufnum < 0 " get enew buffer and name it
Luca Saccarolac363ca12024-12-19 20:16:18 +01004112 " call Decho("--get enew buffer and name it (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4113 call s:NetrwEnew(dirname)
4114 " call Decho(" got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4115 " name the buffer
4116 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4117 " Got enew buffer; transform into a NetrwTreeListing
4118 " call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4119 let w:netrw_treebufnr = bufnr("%")
4120 call s:NetrwBufRename("NetrwTreeListing")
4121 if g:netrw_use_noswf
4122 setl nobl bt=nofile noswf
4123 else
4124 setl nobl bt=nofile
4125 endif
4126 nnoremap <silent> <buffer> [[ :sil call <SID>TreeListMove('[[')<cr>
4127 nnoremap <silent> <buffer> ]] :sil call <SID>TreeListMove(']]')<cr>
4128 nnoremap <silent> <buffer> [] :sil call <SID>TreeListMove('[]')<cr>
4129 nnoremap <silent> <buffer> ][ :sil call <SID>TreeListMove('][')<cr>
4130 " call Decho(" tree listing bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004131 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004132 call s:NetrwBufRename(dirname)
4133 " enter the new buffer into the s:netrwbuf dictionary
4134 let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%")
4135 " call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>"))
4136 " call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004137 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004138 " call Decho(" named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004139
4140 else " Re-use the buffer
Luca Saccarolac363ca12024-12-19 20:16:18 +01004141 " call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4142 " ignore all events
4143 let eikeep= &ei
4144 setl ei=all
Bram Moolenaar71badf92023-04-22 22:40:14 +01004145
Luca Saccarolac363ca12024-12-19 20:16:18 +01004146 if &ft == "netrw"
4147 " call Decho("buffer type is netrw; not using keepalt with b ".bufnum)
4148 exe "sil! NetrwKeepj noswapfile b ".bufnum
4149 " call Dredir("ls!","one")
4150 else
4151 " call Decho("buffer type is not netrw; using keepalt with b ".bufnum)
4152 call s:NetrwEditBuf(bufnum)
4153 " call Dredir("ls!","two")
4154 endif
4155 " call Decho(" line($)=".line("$"),'~'.expand("<slnum>"))
4156 if bufname("%") == '.'
4157 call s:NetrwBufRename(getcwd())
4158 endif
Bram Moolenaar71badf92023-04-22 22:40:14 +01004159
Luca Saccarolac363ca12024-12-19 20:16:18 +01004160 " restore ei
4161 let &ei= eikeep
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004162
Luca Saccarolac363ca12024-12-19 20:16:18 +01004163 if line("$") <= 1 && getline(1) == ""
4164 " empty buffer
4165 NetrwKeepj call s:NetrwListSettings(a:islocal)
4166 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4167 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4168 " call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4169 return 0
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004170
Luca Saccarolac363ca12024-12-19 20:16:18 +01004171 elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4172 " call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4173 NetrwKeepj call s:NetrwListSettings(a:islocal)
4174 sil NetrwKeepj %d _
4175 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4176 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4177 " call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4178 return 0
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004179
Luca Saccarolac363ca12024-12-19 20:16:18 +01004180 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4181 " call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4182 " call Decho(" clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4183 setl ma
4184 sil NetrwKeepj %d _
4185 NetrwKeepj call s:NetrwListSettings(a:islocal)
4186 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4187 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4188 " call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4189 return 0
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004190
Luca Saccarolac363ca12024-12-19 20:16:18 +01004191 else
4192 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4193 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4194 " call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4195 return 1
4196 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004197 endif
4198
4199 " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4200 " fastbrowse Local Remote Hiding a buffer implies it may be re-used (fast)
4201 " slow 0 D D Deleting a buffer implies it will not be re-used (slow)
4202 " med 1 D H
4203 " fast 2 H H
Luca Saccarolac363ca12024-12-19 20:16:18 +01004204 " call Decho("--do netrw settings: make this buffer#".bufnr("%")." not-a-file, modifiable, not line-numbered, etc--",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004205 let fname= expand("%")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004206 NetrwKeepj call s:NetrwListSettings(a:islocal)
Bram Moolenaar85850f32019-07-19 22:05:51 +02004207 call s:NetrwBufRename(fname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004208
4209 " delete all lines from buffer {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01004210 " call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4211 " call Decho(" clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004212 sil! keepalt NetrwKeepj %d _
Bram Moolenaar446cb832008-06-24 21:56:24 +00004213
Luca Saccarolac363ca12024-12-19 20:16:18 +01004214 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4215 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4216 " call Dret("s:NetrwGetBuffer 0<cleared buffer>")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004217 return 0
4218endfun
4219
4220" ---------------------------------------------------------------------
4221" s:NetrwGetcwd: get the current directory. {{{2
4222" Change backslashes to forward slashes, if any.
4223" If doesc is true, escape certain troublesome characters
4224fun! s:NetrwGetcwd(doesc)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004225 " call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004226 let curdir= substitute(getcwd(),'\\','/','ge')
4227 if curdir !~ '[\/]$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004228 let curdir= curdir.'/'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004229 endif
4230 if a:doesc
Luca Saccarolac363ca12024-12-19 20:16:18 +01004231 let curdir= fnameescape(curdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004232 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004233 " call Dret("NetrwGetcwd <".curdir.">")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004234 return curdir
4235endfun
4236
4237" ---------------------------------------------------------------------
4238" s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4239fun! s:NetrwGetWord()
Luca Saccarolac363ca12024-12-19 20:16:18 +01004240 " call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4241 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004242 let keepsol= &l:sol
4243 setl nosol
4244
Bram Moolenaar446cb832008-06-24 21:56:24 +00004245 call s:UseBufWinVars()
4246
4247 " insure that w:netrw_liststyle is set up
4248 if !exists("w:netrw_liststyle")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004249 if exists("g:netrw_liststyle")
4250 let w:netrw_liststyle= g:netrw_liststyle
4251 else
4252 let w:netrw_liststyle= s:THINLIST
4253 endif
4254 " call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004255 endif
4256
4257 if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
Luca Saccarolac363ca12024-12-19 20:16:18 +01004258 " Active Banner support
4259 " call Decho("active banner handling",'~'.expand("<slnum>"))
4260 NetrwKeepj norm! 0
4261 let dirname= "./"
4262 let curline= getline('.')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004263
Luca Saccarolac363ca12024-12-19 20:16:18 +01004264 if curline =~# '"\s*Sorted by\s'
4265 NetrwKeepj norm! "_s
4266 let s:netrw_skipbrowse= 1
4267 echo 'Pressing "s" also works'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004268
Luca Saccarolac363ca12024-12-19 20:16:18 +01004269 elseif curline =~# '"\s*Sort sequence:'
4270 let s:netrw_skipbrowse= 1
4271 echo 'Press "S" to edit sorting sequence'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004272
Luca Saccarolac363ca12024-12-19 20:16:18 +01004273 elseif curline =~# '"\s*Quick Help:'
4274 NetrwKeepj norm! ?
4275 let s:netrw_skipbrowse= 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00004276
Luca Saccarolac363ca12024-12-19 20:16:18 +01004277 elseif curline =~# '"\s*\%(Hiding\|Showing\):'
4278 NetrwKeepj norm! a
4279 let s:netrw_skipbrowse= 1
4280 echo 'Pressing "a" also works'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004281
Luca Saccarolac363ca12024-12-19 20:16:18 +01004282 elseif line("$") > w:netrw_bannercnt
4283 exe 'sil NetrwKeepj '.w:netrw_bannercnt
4284 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004285
4286 elseif w:netrw_liststyle == s:THINLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004287 " call Decho("thin column handling",'~'.expand("<slnum>"))
4288 NetrwKeepj norm! 0
4289 let dirname= substitute(getline('.'),'\t -->.*$','','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004290
4291 elseif w:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004292 " call Decho("long column handling",'~'.expand("<slnum>"))
4293 NetrwKeepj norm! 0
4294 let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004295
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004296 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004297 " call Decho("treelist handling",'~'.expand("<slnum>"))
4298 let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4299 let dirname= substitute(dirname,'\t -->.*$','','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004300
4301 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004302 " call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4303 let dirname= getline('.')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004304
Luca Saccarolac363ca12024-12-19 20:16:18 +01004305 if !exists("b:netrw_cpf")
4306 let b:netrw_cpf= 0
4307 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
Bram Moolenaar5c736222010-01-06 20:54:52 +01004308 call histdel("/",-1)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004309 " "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004310 endif
4311
Luca Saccarolac363ca12024-12-19 20:16:18 +01004312 " call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4313 let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4314 " call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart." bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4315 " call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4316 if filestart == 0
4317 NetrwKeepj norm! 0ma
4318 else
4319 call cursor(line("."),filestart+1)
4320 NetrwKeepj norm! ma
4321 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004322
Luca Saccarolac363ca12024-12-19 20:16:18 +01004323 let dict={}
4324 " save the unnamed register and register 0-9 and a
4325 let dict.a=[getreg('a'), getregtype('a')]
4326 for i in range(0, 9)
4327 let dict[i] = [getreg(i), getregtype(i)]
4328 endfor
4329 let dict.unnamed = [getreg(''), getregtype('')]
Bram Moolenaar446cb832008-06-24 21:56:24 +00004330
Luca Saccarolac363ca12024-12-19 20:16:18 +01004331 let eofname= filestart + b:netrw_cpf + 1
4332 if eofname <= col("$")
4333 call cursor(line("."),filestart+b:netrw_cpf+1)
4334 NetrwKeepj norm! "ay`a
4335 else
4336 NetrwKeepj norm! "ay$
4337 endif
4338
4339 let dirname = @a
4340 call s:RestoreRegister(dict)
4341
4342 " call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4343 let dirname= substitute(dirname,'\s\+$','','e')
4344 " call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
4345endif
4346
4347" symlinks are indicated by a trailing "@". Remove it before further processing.
4348let dirname= substitute(dirname,"@$","","")
4349
4350" executables are indicated by a trailing "*". Remove it before further processing.
4351let dirname= substitute(dirname,"\*$","","")
4352
4353let &l:sol= keepsol
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004354
Bram Moolenaar446cb832008-06-24 21:56:24 +00004355" call Dret("s:NetrwGetWord <".dirname.">")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004356return dirname
Bram Moolenaar446cb832008-06-24 21:56:24 +00004357endfun
4358
4359" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02004360" s:NetrwListSettings: make standard settings for making a netrw listing {{{2
4361" g:netrw_bufsettings will be used after the listing is produced.
4362" Called by s:NetrwGetBuffer()
Bram Moolenaar446cb832008-06-24 21:56:24 +00004363fun! s:NetrwListSettings(islocal)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004364 " call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4365 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004366 let fname= bufname("%")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004367 " " call Decho("setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004368 " nobl noma nomod nonu noma nowrap ro nornu (std g:netrw_bufsettings)
4369 setl bt=nofile nobl ma nonu nowrap noro nornu
4370 call s:NetrwBufRename(fname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004371 if g:netrw_use_noswf
Luca Saccarolac363ca12024-12-19 20:16:18 +01004372 setl noswf
Bram Moolenaar446cb832008-06-24 21:56:24 +00004373 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004374 " call Dredir("ls!","s:NetrwListSettings")
4375 " call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +01004376 exe "setl ts=".(g:netrw_maxfilenamelen+1)
Bram Moolenaarff034192013-04-24 18:51:19 +02004377 setl isk+=.,~,-
Bram Moolenaar446cb832008-06-24 21:56:24 +00004378 if g:netrw_fastbrowse > a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01004379 setl bh=hide
Bram Moolenaar446cb832008-06-24 21:56:24 +00004380 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004381 setl bh=delete
Bram Moolenaar446cb832008-06-24 21:56:24 +00004382 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004383 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4384 " call Dret("s:NetrwListSettings")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004385endfun
4386
4387" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02004388" s:NetrwListStyle: change list style (thin - long - wide - tree) {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00004389" islocal=0: remote browsing
4390" =1: local browsing
4391fun! s:NetrwListStyle(islocal)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004392 let ykeep = @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00004393 let fname = s:NetrwGetWord()
4394 if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004395 let svpos = winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +00004396 let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
Bram Moolenaar446cb832008-06-24 21:56:24 +00004397
Bram Moolenaar85850f32019-07-19 22:05:51 +02004398 " repoint t:netrw_lexbufnr if appropriate
4399 if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
Luca Saccarolac363ca12024-12-19 20:16:18 +01004400 let repointlexbufnr= 1
Bram Moolenaar85850f32019-07-19 22:05:51 +02004401 endif
4402
Bram Moolenaar446cb832008-06-24 21:56:24 +00004403 if w:netrw_liststyle == s:THINLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004404 " use one column listing
4405 let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004406
4407 elseif w:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004408 " use long list
4409 let g:netrw_list_cmd = g:netrw_list_cmd." -l"
Bram Moolenaar446cb832008-06-24 21:56:24 +00004410
4411 elseif w:netrw_liststyle == s:WIDELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004412 " give wide list
4413 let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004414
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004415 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004416 let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004417
4418 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004419 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4420 let g:netrw_liststyle = s:THINLIST
4421 let w:netrw_liststyle = g:netrw_liststyle
4422 let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004423 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02004424 setl ma noro
Bram Moolenaar446cb832008-06-24 21:56:24 +00004425
4426 " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004427 sil! NetrwKeepj %d _
Bram Moolenaar00a927d2010-05-14 23:24:24 +02004428 " following prevents tree listing buffer from being marked "modified"
Bram Moolenaar5b435d62012-04-05 17:33:26 +02004429 setl nomod
Bram Moolenaar446cb832008-06-24 21:56:24 +00004430
4431 " refresh the listing
Tom Benham64a536d2024-11-07 21:15:03 +01004432 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004433 NetrwKeepj call s:NetrwCursor(0)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004434
Bram Moolenaar85850f32019-07-19 22:05:51 +02004435 " repoint t:netrw_lexbufnr if appropriate
4436 if exists("repointlexbufnr")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004437 let t:netrw_lexbufnr= bufnr("%")
Bram Moolenaar85850f32019-07-19 22:05:51 +02004438 endif
4439
Bram Moolenaar13600302014-05-22 18:26:40 +02004440 " restore position; keep cursor on the filename
Luca Saccarolac363ca12024-12-19 20:16:18 +01004441 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004442 NetrwKeepj call winrestview(svpos)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004443 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00004444
Bram Moolenaar446cb832008-06-24 21:56:24 +00004445endfun
4446
4447" ---------------------------------------------------------------------
Bram Moolenaar5c736222010-01-06 20:54:52 +01004448" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4449fun! s:NetrwBannerCtrl(islocal)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004450 let ykeep= @@
Bram Moolenaar5c736222010-01-06 20:54:52 +01004451 " toggle the banner (enable/suppress)
4452 let g:netrw_banner= !g:netrw_banner
4453
4454 " refresh the listing
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004455 let svpos= winsaveview()
Tom Benham64a536d2024-11-07 21:15:03 +01004456 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
Bram Moolenaar5c736222010-01-06 20:54:52 +01004457
4458 " keep cursor on the filename
Bram Moolenaar85850f32019-07-19 22:05:51 +02004459 if g:netrw_banner && exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt
Luca Saccarolac363ca12024-12-19 20:16:18 +01004460 let fname= s:NetrwGetWord()
4461 sil NetrwKeepj $
4462 let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4463 " " call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4464 if result <= 0 && exists("w:netrw_bannercnt")
4465 exe "NetrwKeepj ".w:netrw_bannercnt
4466 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01004467 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01004468 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01004469 " call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
Bram Moolenaar5c736222010-01-06 20:54:52 +01004470endfun
4471
4472" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004473" s:NetrwBookmark: supports :NetrwMB[!] [file]s {{{2
4474"
4475" No bang: enters files/directories into Netrw's bookmark system
4476" No argument and in netrw buffer:
4477" if there are marked files: bookmark marked files
4478" otherwise : bookmark file/directory under cursor
4479" No argument and not in netrw buffer: bookmarks current open file
4480" Has arguments: globs them individually and bookmarks them
4481"
4482" With bang: deletes files/directories from Netrw's bookmark system
4483fun! s:NetrwBookmark(del,...)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004484 if a:0 == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01004485 if &ft == "netrw"
4486 let curbufnr = bufnr("%")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004487
Luca Saccarolac363ca12024-12-19 20:16:18 +01004488 if exists("s:netrwmarkfilelist_{curbufnr}")
4489 " for every filename in the marked list
4490 let svpos = winsaveview()
4491 let islocal= expand("%") !~ '^\a\{3,}://'
4492 for fname in s:netrwmarkfilelist_{curbufnr}
4493 if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4494 endfor
4495 let curdir = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4496 call s:NetrwUnmarkList(curbufnr,curdir)
4497 NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./',0))
4498 NetrwKeepj call winrestview(svpos)
4499 else
4500 let fname= s:NetrwGetWord()
4501 if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4502 endif
4503
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004504 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004505 " bookmark currently open file
4506 let fname= expand("%")
4507 if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004508 endif
4509
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004510 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004511 " bookmark specified files
4512 " attempts to infer if working remote or local
4513 " by deciding if the current file begins with an url
4514 " Globbing cannot be done remotely.
4515 let islocal= expand("%") !~ '^\a\{3,}://'
4516 let i = 1
4517 while i <= a:0
4518 if islocal
4519 if v:version > 704 || (v:version == 704 && has("patch656"))
4520 let mbfiles= glob(fnameescape(a:{i}),0,1,1)
4521 else
4522 let mbfiles= glob(fnameescape(a:{i}),0,1)
4523 endif
4524 else
4525 let mbfiles= [a:{i}]
4526 endif
4527 for mbfile in mbfiles
4528 if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4529 endfor
4530 let i= i + 1
4531 endwhile
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004532 endif
4533
4534 " update the menu
4535 call s:NetrwBookmarkMenu()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004536endfun
4537
4538" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00004539" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4540" .2.[cnt] for bookmarks, and
4541" .3.[cnt] for history
4542" (see s:NetrwMenu())
4543fun! s:NetrwBookmarkMenu()
Bram Moolenaar9964e462007-05-05 17:54:07 +00004544 if !exists("s:netrw_menucnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004545 return
Bram Moolenaar9964e462007-05-05 17:54:07 +00004546 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004547 " call Dfunc("NetrwBookmarkMenu() histcnt=".g:netrw_dirhistcnt." menucnt=".s:netrw_menucnt)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004548
4549 " the following test assures that gvim is running, has menus available, and has menus enabled.
Bram Moolenaaradc21822011-04-01 18:03:16 +02004550 if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
Luca Saccarolac363ca12024-12-19 20:16:18 +01004551 if exists("g:NetrwTopLvlMenu")
4552 " call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4553 exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4554 exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4555 endif
4556 if !exists("s:netrw_initbookhist")
4557 call s:NetrwBookHistRead()
4558 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004559
Luca Saccarolac363ca12024-12-19 20:16:18 +01004560 " show bookmarked places
4561 if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4562 let cnt= 1
4563 for bmd in g:netrw_bookmarklist
4564 " call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.' :e '.bmd,'~'.expand("<slnum>"))
4565 let bmd= escape(bmd,g:netrw_menu_escape)
Bram Moolenaar5c736222010-01-06 20:54:52 +01004566
Luca Saccarolac363ca12024-12-19 20:16:18 +01004567 " show bookmarks for goto menu
4568 exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.' :e '.bmd."\<cr>"
Bram Moolenaar5c736222010-01-06 20:54:52 +01004569
Luca Saccarolac363ca12024-12-19 20:16:18 +01004570 " show bookmarks for deletion menu
4571 exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.' '.cnt."mB"
4572 let cnt= cnt + 1
4573 endfor
Bram Moolenaar5c736222010-01-06 20:54:52 +01004574
Luca Saccarolac363ca12024-12-19 20:16:18 +01004575 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004576
Luca Saccarolac363ca12024-12-19 20:16:18 +01004577 " show directory browsing history
4578 if g:netrw_dirhistmax > 0
4579 let cnt = g:netrw_dirhistcnt
4580 let first = 1
4581 let histcnt = 0
4582 while ( first || cnt != g:netrw_dirhistcnt )
4583 let histcnt = histcnt + 1
4584 let priority = g:netrw_dirhistcnt + histcnt
4585 if exists("g:netrw_dirhist_{cnt}")
4586 let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4587 " call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.' :e '.histdir,'~'.expand("<slnum>"))
4588 exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.' :e '.histdir."\<cr>"
4589 endif
4590 let first = 0
4591 let cnt = ( cnt - 1 ) % g:netrw_dirhistmax
4592 if cnt < 0
4593 let cnt= cnt + g:netrw_dirhistmax
4594 endif
4595 endwhile
4596 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01004597
Bram Moolenaar9964e462007-05-05 17:54:07 +00004598 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004599 " call Dret("NetrwBookmarkMenu")
Bram Moolenaar9964e462007-05-05 17:54:07 +00004600endfun
4601
4602" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00004603" s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4604" directory and a new directory name. Also, if the
4605" "new directory name" is actually a file,
4606" NetrwBrowseChgDir() edits the file.
Tom Benham64a536d2024-11-07 21:15:03 +01004607" cursor=0: newdir is relative to b:netrw_curdir
4608" =1: newdir is relative to the path to the word under the cursor in
4609" tree view
4610fun! s:NetrwBrowseChgDir(islocal,newdir,cursor,...)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004611 let ykeep= @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00004612 if !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004613 " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4614 " and the current window is the NetrwMessage window.
4615 let @@= ykeep
4616 return
Bram Moolenaar9964e462007-05-05 17:54:07 +00004617 endif
4618
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004619 " NetrwBrowseChgDir; save options and initialize {{{3
Bram Moolenaar85850f32019-07-19 22:05:51 +02004620 call s:SavePosn(s:netrw_posn)
4621 NetrwKeepj call s:NetrwOptionsSave("s:")
4622 NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
Tom Benham64a536d2024-11-07 21:15:03 +01004623
4624 let newdir = a:newdir
4625 if a:cursor && exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treetop")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004626 " dirname is the path to the word under the cursor
4627 let dirname = s:NetrwTreePath(w:netrw_treetop)
4628 " newdir resolves to a directory and points to a directory in dirname
4629 " /tmp/test/folder_symlink/ -> /tmp/test/original_folder/
4630 if a:islocal && fnamemodify(dirname, ':t') == newdir && isdirectory(resolve(dirname)) && resolve(dirname) == resolve(newdir)
4631 let dirname = fnamemodify(resolve(dirname), ':p:h:h')
4632 let newdir = fnamemodify(resolve(newdir), ':t')
4633 endif
4634 " Remove trailing "/"
4635 let dirname = substitute(dirname, "/$", "", "")
Tom Benham64a536d2024-11-07 21:15:03 +01004636
Luca Saccarolac363ca12024-12-19 20:16:18 +01004637 " If the word under the cursor is a directory (except for ../), NetrwTreePath
4638 " returns the full path, including the word under the cursor, remove it
4639 if newdir =~ "/$" && newdir != "../"
4640 let dirname = fnamemodify(dirname, ":h")
4641 endif
Bram Moolenaar00a927d2010-05-14 23:24:24 +02004642 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004643 let dirname = b:netrw_curdir
Bram Moolenaar00a927d2010-05-14 23:24:24 +02004644 endif
Tom Benham64a536d2024-11-07 21:15:03 +01004645 if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004646 let dirname = substitute(dirname,'\\','/','ge')
Tom Benham64a536d2024-11-07 21:15:03 +01004647 endif
Bram Moolenaar00a927d2010-05-14 23:24:24 +02004648 let dolockout = 0
Bram Moolenaar13600302014-05-22 18:26:40 +02004649 let dorestore = 1
Bram Moolenaara6878372014-03-22 21:02:50 +01004650
4651 " ignore <cr>s when done in the banner
4652 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01004653 if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4654 if getline(".") =~# 'Quick Help'
4655 let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4656 setl ma noro nowrap
4657 NetrwKeepj call setline(line('.'),'" Quick Help: <F1>:help '.s:QuickHelp[g:netrw_quickhelp])
4658 setl noma nomod nowrap
4659 NetrwKeepj call s:NetrwOptionsRestore("s:")
4660 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01004661 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01004662 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004663
Bram Moolenaar446cb832008-06-24 21:56:24 +00004664 " set up o/s-dependent directory recognition pattern
4665 if has("amiga")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004666 let dirpat= '[\/:]$'
Bram Moolenaar9964e462007-05-05 17:54:07 +00004667 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004668 let dirpat= '[\/]$'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004669 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004670
4671 if dirname !~ dirpat
Luca Saccarolac363ca12024-12-19 20:16:18 +01004672 " apparently vim is "recognizing" that it is in a directory and
4673 " is removing the trailing "/". Bad idea, so let's put it back.
4674 let dirname= dirname.'/'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004675 endif
4676
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004677 if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
Luca Saccarolac363ca12024-12-19 20:16:18 +01004678 " ------------------------------
4679 " NetrwBrowseChgDir: edit a file {{{3
4680 " ------------------------------
Bram Moolenaar5b435d62012-04-05 17:33:26 +02004681
Luca Saccarolac363ca12024-12-19 20:16:18 +01004682 " save position for benefit of Rexplore
4683 let s:rexposn_{bufnr("%")}= winsaveview()
Bram Moolenaara6878372014-03-22 21:02:50 +01004684
Luca Saccarolac363ca12024-12-19 20:16:18 +01004685 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4686 if dirname =~ '/$'
4687 let dirname= dirname.newdir
4688 else
4689 let dirname= dirname."/".newdir
4690 endif
4691 elseif newdir =~ '^\(/\|\a:\)'
4692 let dirname= newdir
Bram Moolenaar446cb832008-06-24 21:56:24 +00004693 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004694 let dirname= s:ComposePath(dirname,newdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004695 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004696 " this lets netrw#BrowseX avoid the edit
4697 if a:0 < 1
4698 NetrwKeepj call s:NetrwOptionsRestore("s:")
4699 let curdir= b:netrw_curdir
4700 if !exists("s:didsplit")
4701 if type(g:netrw_browse_split) == 3
4702 " open file in server
4703 " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4704 call s:NetrwServerEdit(a:islocal,dirname)
4705 return
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02004706
Luca Saccarolac363ca12024-12-19 20:16:18 +01004707 elseif g:netrw_browse_split == 1
4708 " horizontally splitting the window first
4709 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
4710 exe "keepalt ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
4711 if !&ea
4712 keepalt wincmd _
4713 endif
4714 call s:SetRexDir(a:islocal,curdir)
4715
4716 elseif g:netrw_browse_split == 2
4717 " vertically splitting the window first
4718 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
4719 exe "keepalt ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
4720 if !&ea
4721 keepalt wincmd |
4722 endif
4723 call s:SetRexDir(a:islocal,curdir)
4724
4725 elseif g:netrw_browse_split == 3
4726 " open file in new tab
4727 keepalt tabnew
4728 if !exists("b:netrw_curdir")
4729 let b:netrw_curdir= getcwd()
4730 endif
4731 call s:SetRexDir(a:islocal,curdir)
4732
4733 elseif g:netrw_browse_split == 4
4734 " act like "P" (ie. open previous window)
4735 if s:NetrwPrevWinOpen(2) == 3
4736 let @@= ykeep
4737 return
4738 endif
4739 call s:SetRexDir(a:islocal,curdir)
4740
4741 else
4742 " handling a file, didn't split, so remove menu
4743 call s:NetrwMenu(0)
4744 " optional change to window
4745 if g:netrw_chgwin >= 1
4746 if winnr("$")+1 == g:netrw_chgwin
4747 " if g:netrw_chgwin is set to one more than the last window, then
4748 " vertically split the last window to make that window available.
4749 let curwin= winnr()
4750 exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4751 vs
4752 exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4753 endif
4754 exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4755 endif
4756 call s:SetRexDir(a:islocal,curdir)
4757 endif
4758
Bram Moolenaar5c736222010-01-06 20:54:52 +01004759 endif
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02004760
Luca Saccarolac363ca12024-12-19 20:16:18 +01004761 " the point where netrw actually edits the (local) file
4762 " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4763 " use keepalt to support :e # to return to a directory listing
4764 if !&mod
4765 " if e the new file would fail due to &mod, then don't change any of the flags
4766 let dolockout= 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01004767 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004768 if a:islocal
4769 " some like c-^ to return to the last edited file
4770 " others like c-^ to return to the netrw buffer
4771 " Apr 30, 2020: used to have e! here. That can cause loss of a modified file,
4772 " so emit error E37 instead.
4773 call s:NetrwEditFile("e","",dirname)
4774 call s:NetrwCursor(1)
4775 if &hidden || &bufhidden == "hide"
4776 " file came from vim's hidden storage. Don't "restore" options with it.
4777 let dorestore= 0
4778 endif
4779 else
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004780 endif
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02004781
Luca Saccarolac363ca12024-12-19 20:16:18 +01004782 " handle g:Netrw_funcref -- call external-to-netrw functions
4783 " This code will handle g:Netrw_funcref as an individual function reference
4784 " or as a list of function references. It will ignore anything that's not
4785 " a function reference. See :help Funcref for information about function references.
4786 if exists("g:Netrw_funcref")
4787 if type(g:Netrw_funcref) == 2
4788 NetrwKeepj call g:Netrw_funcref()
4789 elseif type(g:Netrw_funcref) == 3
4790 for Fncref in g:Netrw_funcref
4791 if type(Fncref) == 2
4792 NetrwKeepj call Fncref()
4793 endif
4794 endfor
4795 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004796 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004797 endif
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +02004798
Bram Moolenaar446cb832008-06-24 21:56:24 +00004799 elseif newdir =~ '^/'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004800 " ----------------------------------------------------
4801 " NetrwBrowseChgDir: just go to the new directory spec {{{3
4802 " ----------------------------------------------------
4803 let dirname = newdir
4804 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4805 NetrwKeepj call s:NetrwOptionsRestore("s:")
4806 norm! m`
Bram Moolenaar446cb832008-06-24 21:56:24 +00004807
4808 elseif newdir == './'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004809 " ---------------------------------------------
4810 " NetrwBrowseChgDir: refresh the directory list {{{3
4811 " ---------------------------------------------
4812 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4813 norm! m`
Bram Moolenaar446cb832008-06-24 21:56:24 +00004814
4815 elseif newdir == '../'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004816 " --------------------------------------
4817 " NetrwBrowseChgDir: go up one directory {{{3
4818 " --------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00004819
Luca Saccarolac363ca12024-12-19 20:16:18 +01004820 if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4821 " force a refresh
4822 setl noro ma
4823 NetrwKeepj %d _
4824 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004825
Luca Saccarolac363ca12024-12-19 20:16:18 +01004826 if has("amiga")
4827 " amiga
4828 if a:islocal
4829 let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
4830 let dirname= substitute(dirname,'/$','','')
4831 else
4832 let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
4833 endif
4834
4835 elseif !g:netrw_cygwin && has("win32")
4836 " windows
4837 if a:islocal
4838 let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4839 if dirname == ""
4840 let dirname= '/'
4841 endif
4842 else
4843 let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4844 endif
4845 if dirname =~ '^\a:$'
4846 let dirname= dirname.'/'
4847 endif
4848
Bram Moolenaar446cb832008-06-24 21:56:24 +00004849 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004850 " unix or cygwin
4851 if a:islocal
4852 let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4853 if dirname == ""
4854 let dirname= '/'
4855 endif
4856 else
4857 let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4858 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004859 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004860 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4861 norm! m`
Bram Moolenaar446cb832008-06-24 21:56:24 +00004862
4863 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004864 " --------------------------------------
4865 " NetrwBrowseChgDir: Handle Tree Listing {{{3
4866 " --------------------------------------
4867 " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
4868 setl noro ma
4869 if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
4870 NetrwKeepj %d _
Bram Moolenaar446cb832008-06-24 21:56:24 +00004871 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004872 let treedir = s:NetrwTreeDir(a:islocal)
4873 let s:treecurpos = winsaveview()
4874 let haskey = 0
Bram Moolenaar446cb832008-06-24 21:56:24 +00004875
Luca Saccarolac363ca12024-12-19 20:16:18 +01004876 " search treedict for tree dir as-is
Bram Moolenaar446cb832008-06-24 21:56:24 +00004877 if has_key(w:netrw_treedict,treedir)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004878 let haskey= 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00004879 else
Bram Moolenaar446cb832008-06-24 21:56:24 +00004880 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004881
Luca Saccarolac363ca12024-12-19 20:16:18 +01004882 " search treedict for treedir with a [/@] appended
4883 if !haskey && treedir !~ '[/@]$'
4884 if has_key(w:netrw_treedict,treedir."/")
4885 let treedir= treedir."/"
4886 let haskey = 1
4887 else
4888 endif
4889 endif
4890
4891 " search treedict for treedir with any trailing / elided
4892 if !haskey && treedir =~ '/$'
4893 let treedir= substitute(treedir,'/$','','')
4894 if has_key(w:netrw_treedict,treedir)
4895 let haskey = 1
4896 else
4897 endif
4898 endif
4899
4900 if haskey
4901 " close tree listing for selected subdirectory
4902 call remove(w:netrw_treedict,treedir)
4903 let dirname= w:netrw_treetop
4904 else
4905 " go down one directory
4906 let dirname= substitute(treedir,'/*$','/','')
4907 endif
4908 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4909 let s:treeforceredraw = 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00004910
4911 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004912 " ----------------------------------------
4913 " NetrwBrowseChgDir: Go down one directory {{{3
4914 " ----------------------------------------
4915 let dirname = s:ComposePath(dirname,newdir)
4916 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4917 norm! m`
Bram Moolenaar9964e462007-05-05 17:54:07 +00004918 endif
4919
Luca Saccarolac363ca12024-12-19 20:16:18 +01004920 " --------------------------------------
4921 " NetrwBrowseChgDir: Restore and Cleanup {{{3
4922 " --------------------------------------
Bram Moolenaar13600302014-05-22 18:26:40 +02004923 if dorestore
Luca Saccarolac363ca12024-12-19 20:16:18 +01004924 " dorestore is zero'd when a local file was hidden or bufhidden;
4925 " in such a case, we want to keep whatever settings it may have.
4926 NetrwKeepj call s:NetrwOptionsRestore("s:")
Bram Moolenaar13600302014-05-22 18:26:40 +02004927 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02004928 if dolockout && dorestore
Luca Saccarolac363ca12024-12-19 20:16:18 +01004929 if filewritable(dirname)
4930 setl ma noro nomod
4931 else
4932 setl ma ro nomod
4933 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004934 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02004935 call s:RestorePosn(s:netrw_posn)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004936 let @@= ykeep
Bram Moolenaar9964e462007-05-05 17:54:07 +00004937
Bram Moolenaar446cb832008-06-24 21:56:24 +00004938 return dirname
Bram Moolenaar9964e462007-05-05 17:54:07 +00004939endfun
4940
4941" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01004942" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
4943" for thin, long, and wide: cursor placed just after banner
4944" for tree, keeps cursor on current filename
4945fun! s:NetrwBrowseUpDir(islocal)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004946 if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
Luca Saccarolac363ca12024-12-19 20:16:18 +01004947 " this test needed because occasionally this function seems to be incorrectly called
4948 " when multiple leftmouse clicks are taken when atop the one line help in the banner.
4949 " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
4950 " directories.
4951 return
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004952 endif
4953
Bram Moolenaara6878372014-03-22 21:02:50 +01004954 norm! 0
4955 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004956 let curline= getline(".")
4957 let swwline= winline() - 1
4958 if exists("w:netrw_treetop")
4959 let b:netrw_curdir= w:netrw_treetop
4960 elseif exists("b:netrw_curdir")
4961 let w:netrw_treetop= b:netrw_curdir
4962 else
4963 let w:netrw_treetop= getcwd()
4964 let b:netrw_curdir = w:netrw_treetop
4965 endif
4966 let curfile = getline(".")
4967 let curpath = s:NetrwTreePath(w:netrw_treetop)
4968 if a:islocal
4969 call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../',0))
4970 else
4971 call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../',0))
4972 endif
4973 if w:netrw_treetop == '/'
4974 keepj call search('^\M'.curfile,"w")
4975 elseif curfile == '../'
4976 keepj call search('^\M'.curfile,"wb")
4977 else
4978 while 1
4979 keepj call search('^\M'.s:treedepthstring.curfile,"wb")
4980 let treepath= s:NetrwTreePath(w:netrw_treetop)
4981 if treepath == curpath
4982 break
4983 endif
4984 endwhile
4985 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02004986
Bram Moolenaara6878372014-03-22 21:02:50 +01004987 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004988 call s:SavePosn(s:netrw_posn)
4989 if exists("b:netrw_curdir")
4990 let curdir= b:netrw_curdir
4991 else
4992 let curdir= expand(getcwd())
4993 endif
4994 if a:islocal
4995 call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../',0))
4996 else
4997 call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../',0))
4998 endif
4999 call s:RestorePosn(s:netrw_posn)
5000 let curdir= substitute(curdir,'^.*[\/]','','')
5001 let curdir= '\<'. escape(curdir, '~'). '/'
5002 call search(curdir,'wc')
Bram Moolenaara6878372014-03-22 21:02:50 +01005003 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01005004endfun
5005
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005006func s:redir()
5007 " set up redirection (avoids browser messages)
5008 " by default if not set, g:netrw_suppress_gx_mesg is true
5009 if get(g:, 'netrw_suppress_gx_mesg', 1)
5010 if &srr =~# "%s"
5011 return printf(&srr, has("win32") ? "nul" : "/dev/null")
5012 else
5013 return &srr .. (has("win32") ? "nul" : "/dev/null")
5014 endif
5015 endif
5016 return ''
5017endfunc
5018
5019if has('unix')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005020 if has('win32unix')
5021 " Cygwin provides cygstart
5022 if executable('cygstart')
5023 fun! netrw#Launch(args)
5024 exe 'silent ! cygstart --hide' a:args s:redir() | redraw!
5025 endfun
5026 elseif !empty($MSYSTEM) && executable('start')
5027 " MSYS2/Git Bash comes by default without cygstart; see
5028 " https://www.msys2.org/wiki/How-does-MSYS2-differ-from-Cygwin
5029 " Instead it provides /usr/bin/start script running `cmd.exe //c start`
5030 " Adding "" //b` sets void title, hides cmd window and blocks path conversion
5031 " of /b to \b\ " by MSYS2; see https://www.msys2.org/docs/filesystem-paths/
5032 fun! netrw#Launch(args)
5033 exe 'silent !start "" //b' a:args s:redir() | redraw!
5034 endfun
5035 else
5036 " imitate /usr/bin/start script for other environments and hope for the best
5037 fun! netrw#Launch(args)
5038 exe 'silent !cmd //c start "" //b' a:args s:redir() | redraw!
5039 endfun
5040 endif
5041 elseif exists('$WSL_DISTRO_NAME') " use cmd.exe to start GUI apps in WSL
5042 fun! netrw#Launch(args)
5043 let args = a:args
5044 exe 'silent !' ..
5045 \ ((args =~? '\v<\f+\.(exe|com|bat|cmd)>') ?
5046 \ 'cmd.exe /c start /b ' .. args :
5047 \ 'nohup ' .. args .. ' ' .. s:redir() .. ' &')
5048 \ | redraw!
5049 endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005050 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01005051 fun! netrw#Launch(args)
5052 exe ':silent ! nohup' a:args s:redir() (has('gui_running') ? '' : '&') | redraw!
5053 endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005054 endif
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005055elseif has('win32')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005056 fun! netrw#Launch(args)
5057 exe 'silent !' .. (&shell =~? '\<cmd\.exe\>' ? '' : 'cmd.exe /c')
5058 \ 'start "" /b' a:args s:redir() | redraw!
5059 endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005060else
Luca Saccarolac363ca12024-12-19 20:16:18 +01005061 fun! netrw#Launch(dummy)
5062 echom 'No common launcher found'
5063 endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005064endif
5065
5066" Git Bash
5067if has('win32unix')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005068 " (cyg)start suffices
5069 let s:os_viewer = ''
5070 " Windows / WSL
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005071elseif executable('explorer.exe')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005072 let s:os_viewer = 'explorer.exe'
5073 " Linux / BSD
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005074elseif executable('xdg-open')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005075 let s:os_viewer = 'xdg-open'
5076 " MacOS
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005077elseif executable('open')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005078 let s:os_viewer = 'open'
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005079endif
5080
5081fun! s:viewer()
Christian Brabandt92b36662024-12-08 09:52:37 +01005082 " g:netrw_browsex_viewer could be a string of program + its arguments,
5083 " test if first argument is executable
5084 if exists('g:netrw_browsex_viewer') && executable(split(g:netrw_browsex_viewer)[0])
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005085 " extract any viewing options. Assumes that they're set apart by spaces.
5086 " call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5087 if g:netrw_browsex_viewer =~ '\s'
5088 let viewer = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5089 let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5090 let oviewer = ''
5091 let cnt = 1
5092 while !executable(viewer) && viewer != oviewer
5093 let viewer = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5094 let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5095 let cnt = cnt + 1
5096 let oviewer = viewer
5097 " call Decho("!exe: viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
5098 endwhile
5099 else
5100 let viewer = g:netrw_browsex_viewer
5101 let viewopt = ""
5102 endif
5103 " call Decho("viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
5104 return viewer .. ' ' .. viewopt
5105 else
5106 if !exists('s:os_viewer')
5107 call netrw#ErrorMsg(s:ERROR,"No program to open this path found. See :help Open for more information.",106)
5108 else
5109 return s:os_viewer
5110 endif
5111 endif
5112endfun
5113
5114fun! netrw#Open(file) abort
5115 call netrw#Launch(s:viewer() .. ' ' .. shellescape(a:file, 1))
Luca Saccarolac363ca12024-12-19 20:16:18 +01005116 endf
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005117
Luca Saccarolac363ca12024-12-19 20:16:18 +01005118 if !exists('g:netrw_regex_url')
5119 let g:netrw_regex_url = '\%(\%(http\|ftp\|irc\)s\?\|file\)://\S\{-}'
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005120 endif
5121
Luca Saccarolac363ca12024-12-19 20:16:18 +01005122 " ---------------------------------------------------------------------
5123 " netrw#BrowseX: (implements "x" and "gx") executes a special "viewer" script or program for the {{{2
5124 " given filename; typically this means given their extension.
5125 " 0=local, 1=remote
5126 fun! netrw#BrowseX(fname,remote)
5127 if a:remote == 1 && a:fname !~ '^https\=:' && a:fname =~ '/$'
5128 " remote directory, not a webpage access, looks like an attempt to do a directory listing
5129 norm! gf
5130 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02005131
Luca Saccarolac363ca12024-12-19 20:16:18 +01005132 if exists("g:netrw_browsex_viewer") && exists("g:netrw_browsex_support_remote") && !g:netrw_browsex_support_remote
5133 let remote = a:remote
5134 else
5135 let remote = 0
5136 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01005137
Luca Saccarolac363ca12024-12-19 20:16:18 +01005138 let ykeep = @@
5139 let screenposn = winsaveview()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005140
Luca Saccarolac363ca12024-12-19 20:16:18 +01005141 " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
5142 let awkeep = &aw
5143 set noaw
5144
5145 " special core dump handler
5146 if a:fname =~ '/core\(\.\d\+\)\=$'
5147 if exists("g:Netrw_corehandler")
5148 if type(g:Netrw_corehandler) == 2
5149 " g:Netrw_corehandler is a function reference (see :help Funcref)
5150 call g:Netrw_corehandler(s:NetrwFile(a:fname))
5151 elseif type(g:Netrw_corehandler) == 3
5152 " g:Netrw_corehandler is a List of function references (see :help Funcref)
5153 for Fncref in g:Netrw_corehandler
5154 if type(Fncref) == 2
5155 call Fncref(a:fname)
5156 endif
5157 endfor
5158 endif
5159 call winrestview(screenposn)
5160 let @@= ykeep
5161 let &aw= awkeep
5162 return
Bram Moolenaar5c736222010-01-06 20:54:52 +01005163 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005164 endif
5165
5166 " set up the filename
5167 " (lower case the extension, make a local copy of a remote file)
5168 let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5169 if has("win32")
5170 let exten= substitute(exten,'^.*$','\L&\E','')
5171 endif
5172 if exten =~ "[\\/]"
5173 let exten= ""
5174 endif
5175
5176 if remote == 1
5177 " create a local copy
5178 setl bh=delete
5179 call netrw#NetRead(3,a:fname)
5180 " attempt to rename tempfile
5181 let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5182 let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5183 if s:netrw_tmpfile != newname && newname != ""
5184 if rename(s:netrw_tmpfile,newname) == 0
5185 " renaming succeeded
5186 let fname= newname
5187 else
5188 " renaming failed
5189 let fname= s:netrw_tmpfile
5190 endif
5191 else
5192 let fname= s:netrw_tmpfile
5193 endif
5194 else
5195 let fname= a:fname
5196 " special ~ handler for local
5197 if fname =~ '^\~' && expand("$HOME") != ""
5198 let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
5199 endif
5200 endif
5201
5202 " although shellescape(..., 1) is used in netrw#Open(), it's insufficient
5203 call netrw#Open(escape(fname, '#%'))
5204
5205 " cleanup: remove temporary file,
5206 " delete current buffer if success with handler,
5207 " return to prior buffer (directory listing)
5208 " Feb 12, 2008: had to de-activate removal of
5209 " temporary file because it wasn't getting seen.
5210 " if remote == 1 && fname != a:fname
5211 " call s:NetrwDelete(fname)
5212 " endif
5213
5214 if remote == 1
5215 setl bh=delete bt=nofile
5216 if g:netrw_use_noswf
5217 setl noswf
5218 endif
5219 exe "sil! NetrwKeepj norm! \<c-o>"
Bram Moolenaar5c736222010-01-06 20:54:52 +01005220 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +01005221 call winrestview(screenposn)
Luca Saccarolac363ca12024-12-19 20:16:18 +01005222 let @@ = ykeep
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005223 let &aw= awkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01005224 endfun
Bram Moolenaar5c736222010-01-06 20:54:52 +01005225
Luca Saccarolac363ca12024-12-19 20:16:18 +01005226 " ---------------------------------------------------------------------
5227 " netrw#GX: gets word under cursor for gx support {{{2
5228 " See also: netrw#BrowseXVis
5229 " netrw#BrowseX
5230 fun! netrw#GX()
5231 " call Dfunc("netrw#GX()")
5232 if &ft == "netrw"
5233 let fname= s:NetrwGetWord()
Bram Moolenaar85850f32019-07-19 22:05:51 +02005234 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01005235 let fname= exists("g:netrw_gx")? expand(g:netrw_gx) : s:GetURL()
Bram Moolenaar85850f32019-07-19 22:05:51 +02005236 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005237 " call Dret("netrw#GX <".fname.">")
5238 return fname
5239 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00005240
Luca Saccarolac363ca12024-12-19 20:16:18 +01005241 fun! s:GetURL() abort
5242 let URL = ''
5243 if exists('*Netrw_get_URL_' .. &filetype)
Konfekt3d7e5672024-10-27 22:16:49 +01005244 let URL = call('Netrw_get_URL_' .. &filetype, [])
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005245 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005246 if !empty(URL) | return URL | endif
5247 " URLs end in letter, digit or forward slash
5248 let URL = matchstr(expand("<cWORD>"), '\<' .. g:netrw_regex_url .. '\ze[^A-Za-z0-9/]*$')
5249 if !empty(URL) | return URL | endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005250
Luca Saccarolac363ca12024-12-19 20:16:18 +01005251 " Is it a file in the current work dir ...
5252 let file = expand("<cfile>")
5253 if filereadable(file) | return file | endif
5254 " ... or in that of the current buffer?
5255 let path = fnamemodify(expand('%'), ':p')
5256 if isdirectory(path)
5257 let dir = path
5258 elseif filereadable(path)
5259 let dir = fnamemodify(path, ':h')
Christian Brabandt98b73eb2024-06-04 18:15:57 +02005260 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005261 if exists('dir') && filereadable(dir..'/'..file) | return dir..'/'..file | endif
Bram Moolenaar71badf92023-04-22 22:40:14 +01005262
Luca Saccarolac363ca12024-12-19 20:16:18 +01005263 return ''
5264 endf
Bram Moolenaar5c736222010-01-06 20:54:52 +01005265
Luca Saccarolac363ca12024-12-19 20:16:18 +01005266 " ---------------------------------------------------------------------
5267 " netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5268 fun! netrw#BrowseXVis()
5269 let dict={}
5270 let dict.a=[getreg('a'), getregtype('a')]
5271 norm! gv"ay
5272 let gxfile= @a
5273 call s:RestoreRegister(dict)
5274 call netrw#BrowseX(gxfile,netrw#CheckIfRemote(gxfile))
5275 endfun
Bram Moolenaaradc21822011-04-01 18:03:16 +02005276
Luca Saccarolac363ca12024-12-19 20:16:18 +01005277 " ---------------------------------------------------------------------
5278 " s:NetrwBufRename: renames a buffer without the side effect of retaining an unlisted buffer having the old name {{{2
5279 " Using the file command on a "[No Name]" buffer does not seem to cause the old "[No Name]" buffer
5280 " to become an unlisted buffer, so in that case don't bwipe it.
5281 fun! s:NetrwBufRename(newname)
5282 " call Dfunc("s:NetrwBufRename(newname<".a:newname.">) buf(%)#".bufnr("%")."<".bufname(bufnr("%")).">")
5283 " call Dredir("ls!","s:NetrwBufRename (before rename)")
5284 let oldbufname= bufname(bufnr("%"))
5285 " call Decho("buf#".bufnr("%").": oldbufname<".oldbufname.">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01005286
Luca Saccarolac363ca12024-12-19 20:16:18 +01005287 if oldbufname != a:newname
5288 " call Decho("do buffer rename: oldbufname<".oldbufname."> ≠ a:newname<".a:newname.">",'~'.expand("<slnum>"))
5289 let b:junk= 1
5290 " call Decho("rename buffer: sil! keepj keepalt file ".fnameescape(a:newname),'~'.expand("<slnum>"))
5291 exe 'sil! keepj keepalt file '.fnameescape(a:newname)
5292 " call Dredir("ls!","s:NetrwBufRename (before bwipe)~".expand("<slnum>"))
5293 let oldbufnr= bufnr(oldbufname)
5294 " call Decho("oldbufname<".oldbufname."> oldbufnr#".oldbufnr,'~'.expand("<slnum>"))
5295 " call Decho("bufnr(%)=".bufnr("%"),'~'.expand("<slnum>"))
5296 if oldbufname != "" && oldbufnr != -1 && oldbufnr != bufnr("%")
5297 " call Decho("bwipe ".oldbufnr,'~'.expand("<slnum>"))
5298 exe "bwipe! ".oldbufnr
5299 " else " Decho
5300 " call Decho("did *not* bwipe buf#".oldbufnr,'~'.expand("<slnum>"))
5301 " call Decho("..reason: if oldbufname<".oldbufname."> is empty",'~'.expand("<slnum>"))"
5302 " call Decho("..reason: if oldbufnr#".oldbufnr." is -1",'~'.expand("<slnum>"))"
5303 " call Decho("..reason: if oldbufnr#".oldbufnr." != bufnr(%)#".bufnr("%"),'~'.expand("<slnum>"))"
5304 endif
5305 " call Dredir("ls!","s:NetrwBufRename (after rename)")
5306 " else " Decho
5307 " call Decho("oldbufname<".oldbufname."> == a:newname: did *not* rename",'~'.expand("<slnum>"))
5308 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02005309
Luca Saccarolac363ca12024-12-19 20:16:18 +01005310 " call Dret("s:NetrwBufRename : buf#".bufnr("%").": oldname<".oldbufname."> newname<".a:newname."> expand(%)<".expand("%").">")
5311 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00005312
Luca Saccarolac363ca12024-12-19 20:16:18 +01005313 " ---------------------------------------------------------------------
5314 " netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5315 fun! netrw#CheckIfRemote(...)
5316 " call Dfunc("netrw#CheckIfRemote() a:0=".a:0)
5317 if a:0 > 0
5318 let curfile= a:1
5319 else
5320 let curfile= expand("%")
5321 endif
5322 " call Decho("curfile<".curfile.">")
5323 if curfile =~ '^\a\{3,}://'
5324 " call Dret("netrw#CheckIfRemote 1")
5325 return 1
5326 else
5327 " call Dret("netrw#CheckIfRemote 0")
5328 return 0
5329 endif
5330 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00005331
Luca Saccarolac363ca12024-12-19 20:16:18 +01005332 " ---------------------------------------------------------------------
5333 " s:NetrwChgPerm: (implements "gp") change file permission {{{2
5334 fun! s:NetrwChgPerm(islocal,curdir)
5335 let ykeep = @@
5336 call inputsave()
5337 let newperm= input("Enter new permission: ")
5338 call inputrestore()
5339 let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5340 let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5341 call system(chgperm)
5342 if v:shell_error != 0
5343 NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5344 endif
5345 if a:islocal
5346 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
5347 endif
5348 let @@= ykeep
5349 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00005350
Luca Saccarolac363ca12024-12-19 20:16:18 +01005351 " ---------------------------------------------------------------------
5352 " s:CheckIfKde: checks if kdeinit is running {{{2
5353 " Returns 0: kdeinit not running
5354 " 1: kdeinit is running
5355 fun! s:CheckIfKde()
5356 " call Dfunc("s:CheckIfKde()")
5357 " seems kde systems often have gnome-open due to dependencies, even though
5358 " gnome-open's subsidiary display tools are largely absent. Kde systems
5359 " usually have "kdeinit" running, though... (tnx Mikolaj Machowski)
5360 if !exists("s:haskdeinit")
5361 if has("unix") && executable("ps") && !has("win32unix")
5362 let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5363 if v:shell_error
5364 let s:haskdeinit = 0
5365 endif
5366 else
5367 let s:haskdeinit= 0
5368 endif
5369 " call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5370 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00005371
Luca Saccarolac363ca12024-12-19 20:16:18 +01005372 " call Dret("s:CheckIfKde ".s:haskdeinit)
5373 return s:haskdeinit
5374 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00005375
Luca Saccarolac363ca12024-12-19 20:16:18 +01005376 " ---------------------------------------------------------------------
5377 " s:NetrwClearExplore: clear explore variables (if any) {{{2
5378 fun! s:NetrwClearExplore()
5379 " call Dfunc("s:NetrwClearExplore()")
5380 2match none
5381 if exists("s:explore_match") |unlet s:explore_match |endif
5382 if exists("s:explore_indx") |unlet s:explore_indx |endif
5383 if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5384 if exists("s:dirstarstar") |unlet s:dirstarstar |endif
5385 if exists("s:explore_prvdir") |unlet s:explore_prvdir |endif
5386 if exists("w:netrw_explore_indx") |unlet w:netrw_explore_indx |endif
5387 if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5388 if exists("w:netrw_explore_list") |unlet w:netrw_explore_list |endif
5389 if exists("w:netrw_explore_bufnr") |unlet w:netrw_explore_bufnr |endif
5390 " redraw!
5391 " call Dret("s:NetrwClearExplore")
5392 endfun
Bram Moolenaar9964e462007-05-05 17:54:07 +00005393
Luca Saccarolac363ca12024-12-19 20:16:18 +01005394 " ---------------------------------------------------------------------
5395 " s:NetrwEditBuf: decides whether or not to use keepalt to edit a buffer {{{2
5396 fun! s:NetrwEditBuf(bufnum)
5397 " call Dfunc("s:NetrwEditBuf(fname<".a:bufnum.">)")
5398 if exists("g:netrw_altfile") && g:netrw_altfile && &ft == "netrw"
5399 " call Decho("exe sil! NetrwKeepj keepalt noswapfile b ".fnameescape(a:bufnum))
5400 exe "sil! NetrwKeepj keepalt noswapfile b ".fnameescape(a:bufnum)
5401 else
5402 " call Decho("exe sil! NetrwKeepj noswapfile b ".fnameescape(a:bufnum))
5403 exe "sil! NetrwKeepj noswapfile b ".fnameescape(a:bufnum)
5404 endif
5405 " call Dret("s:NetrwEditBuf")
5406 endfun
Bram Moolenaara0f849e2015-10-30 14:37:44 +01005407
Luca Saccarolac363ca12024-12-19 20:16:18 +01005408 " ---------------------------------------------------------------------
5409 " s:NetrwEditFile: decides whether or not to use keepalt to edit a file {{{2
5410 " NetrwKeepj [keepalt] <OPT> <CMD> <FILENAME>
5411 fun! s:NetrwEditFile(cmd,opt,fname)
5412 " call Dfunc("s:NetrwEditFile(cmd<".a:cmd.">,opt<".a:opt.">,fname<".a:fname.">) ft<".&ft.">")
5413 if exists("g:netrw_altfile") && g:netrw_altfile && &ft == "netrw"
5414 " call Decho("exe NetrwKeepj keepalt ".a:opt." ".a:cmd." ".fnameescape(a:fname))
5415 exe "NetrwKeepj keepalt ".a:opt." ".a:cmd." ".fnameescape(a:fname)
5416 else
5417 " call Decho("exe NetrwKeepj ".a:opt." ".a:cmd." ".fnameescape(a:fname))
5418 if a:cmd =~# 'e\%[new]!' && !&hidden && getbufvar(bufname('%'), '&modified', 0)
5419 call setbufvar(bufname('%'), '&bufhidden', 'hide')
5420 endif
5421 exe "NetrwKeepj ".a:opt." ".a:cmd." ".fnameescape(a:fname)
5422 endif
5423 " call Dret("s:NetrwEditFile")
5424 endfun
Bram Moolenaara0f849e2015-10-30 14:37:44 +01005425
Luca Saccarolac363ca12024-12-19 20:16:18 +01005426 " ---------------------------------------------------------------------
5427 " s:NetrwExploreListUniq: {{{2
5428 fun! s:NetrwExploreListUniq(explist)
5429 " this assumes that the list is already sorted
5430 let newexplist= []
5431 for member in a:explist
5432 if !exists("uniqmember") || member != uniqmember
5433 let uniqmember = member
5434 let newexplist = newexplist + [ member ]
5435 endif
5436 endfor
5437 return newexplist
5438 endfun
Bram Moolenaara0f849e2015-10-30 14:37:44 +01005439
Luca Saccarolac363ca12024-12-19 20:16:18 +01005440 " ---------------------------------------------------------------------
5441 " s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5442 fun! s:NetrwForceChgDir(islocal,newdir)
5443 let ykeep= @@
5444 if a:newdir !~ '/$'
5445 " ok, looks like force is needed to get directory-style treatment
5446 if a:newdir =~ '@$'
5447 let newdir= substitute(a:newdir,'@$','/','')
5448 elseif a:newdir =~ '[*=|\\]$'
5449 let newdir= substitute(a:newdir,'.$','/','')
5450 else
5451 let newdir= a:newdir.'/'
5452 endif
5453 else
5454 " should already be getting treatment as a directory
5455 let newdir= a:newdir
5456 endif
5457 let newdir= s:NetrwBrowseChgDir(a:islocal,newdir,0)
5458 call s:NetrwBrowse(a:islocal,newdir)
5459 let @@= ykeep
5460 endfun
Bram Moolenaara0f849e2015-10-30 14:37:44 +01005461
Luca Saccarolac363ca12024-12-19 20:16:18 +01005462 " ---------------------------------------------------------------------
5463 " s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5464 " direntry: this is the name of the directory. Will be fnameescape'd to prevent wildcard handling by glob()
5465 " expr : this is the expression to follow the directory. Will use s:ComposePath()
5466 " pare =1: remove the current directory from the resulting glob() filelist
5467 " =0: leave the current directory in the resulting glob() filelist
5468 fun! s:NetrwGlob(direntry,expr,pare)
5469 " call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")")
5470 if netrw#CheckIfRemote()
5471 keepalt 1sp
5472 keepalt enew
5473 let keep_liststyle = w:netrw_liststyle
5474 let w:netrw_liststyle = s:THINLIST
5475 if s:NetrwRemoteListing() == 0
5476 keepj keepalt %s@/@@
5477 let filelist= getline(1,$)
5478 q!
5479 else
5480 " remote listing error -- leave treedict unchanged
5481 let filelist= w:netrw_treedict[a:direntry]
5482 endif
5483 let w:netrw_liststyle= keep_liststyle
5484 else
5485 let path= s:ComposePath(fnameescape(a:direntry), a:expr)
5486 if has("win32")
5487 " escape [ so it is not detected as wildcard character, see :h wildcard
5488 let path= substitute(path, '[', '[[]', 'g')
5489 endif
5490 if v:version > 704 || (v:version == 704 && has("patch656"))
5491 let filelist= glob(path,0,1,1)
5492 else
5493 let filelist= glob(path,0,1)
5494 endif
5495 if a:pare
5496 let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5497 endif
5498 endif
5499 return filelist
5500 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00005501
Luca Saccarolac363ca12024-12-19 20:16:18 +01005502 " ---------------------------------------------------------------------
5503 " s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5504 fun! s:NetrwForceFile(islocal,newfile)
5505 if a:newfile =~ '[/@*=|\\]$'
5506 let newfile= substitute(a:newfile,'.$','','')
5507 else
5508 let newfile= a:newfile
5509 endif
5510 if a:islocal
5511 call s:NetrwBrowseChgDir(a:islocal,newfile,0)
5512 else
5513 call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile,0))
5514 endif
5515 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00005516
Luca Saccarolac363ca12024-12-19 20:16:18 +01005517 " ---------------------------------------------------------------------
5518 " s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5519 " and switches the hiding mode. The actual hiding is done by
5520 " s:NetrwListHide().
5521 " g:netrw_hide= 0: show all
5522 " 1: show not-hidden files
5523 " 2: show hidden files only
5524 fun! s:NetrwHide(islocal)
5525 let ykeep= @@
5526 let svpos= winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +00005527
Luca Saccarolac363ca12024-12-19 20:16:18 +01005528 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Bram Moolenaar5c736222010-01-06 20:54:52 +01005529
Luca Saccarolac363ca12024-12-19 20:16:18 +01005530 " hide the files in the markfile list
5531 for fname in s:netrwmarkfilelist_{bufnr("%")}
5532 if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5533 " remove fname from hiding list
5534 let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5535 let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5536 let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
5537 else
5538 " append fname to hiding list
5539 if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5540 let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
5541 else
5542 let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
5543 endif
5544 endif
5545 endfor
5546 NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5547 let g:netrw_hide= 1
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005548
5549 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01005550
5551 " switch between show-all/show-not-hidden/show-hidden
5552 let g:netrw_hide=(g:netrw_hide+1)%3
5553 exe "NetrwKeepj norm! 0"
5554 if g:netrw_hide && g:netrw_list_hide == ""
5555 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
5556 let @@= ykeep
5557 return
5558 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005559 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005560
Luca Saccarolac363ca12024-12-19 20:16:18 +01005561 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
5562 NetrwKeepj call winrestview(svpos)
5563 let @@= ykeep
5564 endfun
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005565
Luca Saccarolac363ca12024-12-19 20:16:18 +01005566 " ---------------------------------------------------------------------
5567 " s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5568 fun! s:NetrwHideEdit(islocal)
5569 let ykeep= @@
5570 " save current cursor position
5571 let svpos= winsaveview()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005572
Luca Saccarolac363ca12024-12-19 20:16:18 +01005573 " get new hiding list from user
5574 call inputsave()
5575 let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5576 call inputrestore()
5577 let g:netrw_list_hide= newhide
5578
5579 " refresh the listing
5580 sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./",0))
5581
5582 " restore cursor position
5583 call winrestview(svpos)
5584 let @@= ykeep
5585 endfun
5586
5587 " ---------------------------------------------------------------------
5588 " s:NetrwHidden: invoked by "gh" {{{2
5589 fun! s:NetrwHidden(islocal)
5590 let ykeep= @@
5591 " save current position
5592 let svpos = winsaveview()
5593
5594 if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5595 " remove .file pattern from hiding list
5596 let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5597 elseif s:Strlen(g:netrw_list_hide) >= 1
5598 let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5599 else
5600 let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5601 endif
5602 if g:netrw_list_hide =~ '^,'
5603 let g:netrw_list_hide= strpart(g:netrw_list_hide,1)
5604 endif
5605
5606 " refresh screen and return to saved position
5607 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
5608 NetrwKeepj call winrestview(svpos)
5609 let @@= ykeep
5610 endfun
5611
5612 " ---------------------------------------------------------------------
5613 " s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5614 fun! s:NetrwHome()
5615 if exists("g:netrw_home")
5616 let home= expand(g:netrw_home)
5617 else
5618 " go to vim plugin home
5619 for home in split(&rtp,',') + ['']
5620 if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5621 let basehome= substitute(home,'[/\\]\.vim$','','')
5622 if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5623 let home= basehome."/.vim"
5624 break
5625 endif
5626 endfor
5627 if home == ""
5628 " just pick the first directory
5629 let home= substitute(&rtp,',.*$','','')
5630 endif
5631 if has("win32")
5632 let home= substitute(home,'/','\\','g')
5633 endif
5634 endif
5635 " insure that the home directory exists
5636 if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5637 " call Decho("insure that the home<".home."> directory exists")
5638 if exists("g:netrw_mkdir")
5639 " call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")")
5640 call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5641 else
5642 " call Decho("mkdir(".home.")")
5643 call mkdir(home)
5644 endif
5645 endif
5646 let g:netrw_home= home
5647 return home
5648 endfun
5649
5650 " ---------------------------------------------------------------------
5651 " s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5652 fun! s:NetrwLeftmouse(islocal)
5653 if exists("s:netrwdrag")
5654 return
5655 endif
5656 if &ft != "netrw"
5657 return
5658 endif
5659
5660 let ykeep= @@
5661 " check if the status bar was clicked on instead of a file/directory name
5662 while getchar(0) != 0
5663 "clear the input stream
5664 endwhile
5665 call feedkeys("\<LeftMouse>")
5666 let c = getchar()
5667 let mouse_lnum = v:mouse_lnum
5668 let wlastline = line('w$')
5669 let lastline = line('$')
5670 if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5671 " appears to be a status bar leftmouse click
5672 let @@= ykeep
5673 return
5674 endif
5675 " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5676 " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5677 " without this test when its disabled.
5678 " May 26, 2014: edit file, :Lex, resize window -- causes refresh. Reinstated a modified test. See if problems develop.
5679 if v:mouse_col > virtcol('.')
5680 let @@= ykeep
5681 return
5682 endif
5683
5684 if a:islocal
5685 if exists("b:netrw_curdir")
5686 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord(),1))
5687 endif
5688 else
5689 if exists("b:netrw_curdir")
5690 NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1))
5691 endif
5692 endif
5693 let @@= ykeep
5694 endfun
5695
5696 " ---------------------------------------------------------------------
5697 " s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5698 fun! s:NetrwCLeftmouse(islocal)
5699 if &ft != "netrw"
5700 return
5701 endif
5702 call s:NetrwMarkFileTgt(a:islocal)
5703 endfun
5704
5705 " ---------------------------------------------------------------------
5706 " s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER (implements <c-r>){{{2
5707 " a:islocal=0 : <c-r> not used, remote
5708 " a:islocal=1 : <c-r> not used, local
5709 " a:islocal=2 : <c-r> used, remote
5710 " a:islocal=3 : <c-r> used, local
5711 fun! s:NetrwServerEdit(islocal,fname)
5712 " call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5713 let islocal = a:islocal%2 " =0: remote =1: local
5714 let ctrlr = a:islocal >= 2 " =0: <c-r> not used =1: <c-r> used
5715
5716 if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5717 " handle directories in the local window -- not in the remote vim server
5718 " user must have closed the NETRWSERVER window. Treat as normal editing from netrw.
5719 let g:netrw_browse_split= 0
5720 if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
5721 let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5722 unlet s:netrw_browse_split_{winnr()}
5723 endif
5724 call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname,0))
5725 return
5726 endif
5727
5728 if has("clientserver") && executable("gvim")
5729
5730 if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
5731 let srvrname = g:netrw_browse_split[0]
5732 let tabnum = g:netrw_browse_split[1]
5733 let winnum = g:netrw_browse_split[2]
5734
5735 if serverlist() !~ '\<'.srvrname.'\>'
5736 if !ctrlr
5737 " user must have closed the server window and the user did not use <c-r>, but
5738 " used something like <cr>.
5739 if exists("g:netrw_browse_split")
5740 unlet g:netrw_browse_split
5741 endif
5742 let g:netrw_browse_split= 0
5743 if exists("s:netrw_browse_split_".winnr())
5744 let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5745 endif
5746 call s:NetrwBrowseChgDir(islocal,a:fname,0)
5747 return
5748
5749 elseif has("win32") && executable("start")
5750 " start up remote netrw server under windows
5751 call system("start gvim --servername ".srvrname)
5752
5753 else
5754 " start up remote netrw server under linux
5755 call system("gvim --servername ".srvrname)
5756 endif
5757 endif
5758
5759 call remote_send(srvrname,":tabn ".tabnum."\<cr>")
5760 call remote_send(srvrname,":".winnum."wincmd w\<cr>")
5761 call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5762 else
5763
5764 if serverlist() !~ '\<'.g:netrw_servername.'\>'
5765
5766 if !ctrlr
5767 if exists("g:netrw_browse_split")
5768 unlet g:netrw_browse_split
5769 endif
5770 let g:netrw_browse_split= 0
5771 call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname,0))
5772 return
5773
5774 else
5775 if has("win32") && executable("start")
5776 " start up remote netrw server under windows
5777 call system("start gvim --servername ".g:netrw_servername)
5778 else
5779 " start up remote netrw server under linux
5780 call system("gvim --servername ".g:netrw_servername)
5781 endif
5782 endif
5783 endif
5784
5785 while 1
5786 try
5787 call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5788 break
5789 catch /^Vim\%((\a\+)\)\=:E241/
5790 sleep 200m
5791 endtry
5792 endwhile
5793
5794 if exists("g:netrw_browse_split")
5795 if type(g:netrw_browse_split) != 3
5796 let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
5797 endif
5798 unlet g:netrw_browse_split
5799 endif
5800 let g:netrw_browse_split= [g:netrw_servername,1,1]
5801 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005802
5803 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01005804 call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005805 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005806
Luca Saccarolac363ca12024-12-19 20:16:18 +01005807 endfun
5808
5809 " ---------------------------------------------------------------------
5810 " s:NetrwSLeftmouse: marks the file under the cursor. May be dragged to select additional files {{{2
5811 fun! s:NetrwSLeftmouse(islocal)
5812 if &ft != "netrw"
5813 return
5814 endif
5815 " call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
5816
5817 let s:ngw= s:NetrwGetWord()
5818 call s:NetrwMarkFile(a:islocal,s:ngw)
5819
5820 " call Dret("s:NetrwSLeftmouse")
5821 endfun
5822
5823 " ---------------------------------------------------------------------
5824 " s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
5825 " Used to mark multiple files.
5826 fun! s:NetrwSLeftdrag(islocal)
5827 " call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
5828 if !exists("s:netrwdrag")
5829 let s:netrwdrag = winnr()
5830 if a:islocal
5831 nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
5832 else
5833 nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
5834 endif
5835 endif
5836 let ngw = s:NetrwGetWord()
5837 if !exists("s:ngw") || s:ngw != ngw
5838 call s:NetrwMarkFile(a:islocal,ngw)
5839 endif
5840 let s:ngw= ngw
5841 " call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5842 endfun
5843
5844 " ---------------------------------------------------------------------
5845 " s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
5846 fun! s:NetrwSLeftrelease(islocal)
5847 " call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5848 if exists("s:netrwdrag")
5849 nunmap <s-leftrelease>
5850 let ngw = s:NetrwGetWord()
5851 if !exists("s:ngw") || s:ngw != ngw
5852 call s:NetrwMarkFile(a:islocal,ngw)
5853 endif
5854 if exists("s:ngw")
5855 unlet s:ngw
5856 endif
5857 unlet s:netrwdrag
5858 endif
5859 " call Dret("s:NetrwSLeftrelease")
5860 endfun
5861
5862 " ---------------------------------------------------------------------
5863 " s:NetrwListHide: uses [range]g~...~d to delete files that match {{{2
5864 " comma-separated patterns given in g:netrw_list_hide
5865 fun! s:NetrwListHide()
5866 " call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
5867 " call Decho("initial: ".string(getline(w:netrw_bannercnt,'$')))
5868 let ykeep= @@
5869
5870 " find a character not in the "hide" string to use as a separator for :g and :v commands
5871 " How-it-works: take the hiding command, convert it into a range.
5872 " Duplicate characters don't matter.
5873 " Remove all such characters from the '/~@#...890' string.
5874 " Use the first character left as a separator character.
5875 " call Decho("find a character not in the hide string to use as a separator",'~'.expand("<slnum>"))
5876 let listhide= g:netrw_list_hide
5877 let sep = strpart(substitute('~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
5878 " call Decho("sep<".sep."> (sep not in hide string)",'~'.expand("<slnum>"))
5879
5880 while listhide != ""
5881 if listhide =~ ','
5882 let hide = substitute(listhide,',.*$','','e')
5883 let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
5884 else
5885 let hide = listhide
5886 let listhide = ""
5887 endif
5888 " call Decho("..extracted pattern from listhide: hide<".hide."> g:netrw_sort_by<".g:netrw_sort_by.'>','~'.expand("<slnum>"))
5889 if g:netrw_sort_by =~ '^[ts]'
5890 if hide =~ '^\^'
5891 " call Decho("..modify hide to handle a \"^...\" pattern",'~'.expand("<slnum>"))
5892 let hide= substitute(hide,'^\^','^\(\\d\\+/\)','')
5893 elseif hide =~ '^\\(\^'
5894 let hide= substitute(hide,'^\\(\^','\\(^\\(\\d\\+/\\)','')
5895 endif
5896 " call Decho("..hide<".hide."> listhide<".listhide.'>','~'.expand("<slnum>"))
5897 endif
5898
5899 " Prune the list by hiding any files which match
5900 " call Decho("..prune the list by hiding any files which ".((g:netrw_hide == 1)? "" : "don't")."match hide<".hide.">")
5901 if g:netrw_hide == 1
5902 " call Decho("..hiding<".hide.">",'~'.expand("<slnum>"))
5903 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
5904 elseif g:netrw_hide == 2
5905 " call Decho("..showing<".hide.">",'~'.expand("<slnum>"))
5906 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
5907 endif
5908 " call Decho("..result: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
5909 endwhile
5910
5911 if g:netrw_hide == 2
5912 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
5913 " call Decho("..v KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
5914 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
5915 " call Decho("..g KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
5916 endif
5917
5918 " remove any blank lines that have somehow remained.
5919 " This seems to happen under Windows.
5920 exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
5921
5922 let @@= ykeep
5923 " call Dret("s:NetrwListHide")
5924 endfun
5925
5926 " ---------------------------------------------------------------------
5927 " s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
5928 " implements the "d" mapping.
5929 fun! s:NetrwMakeDir(usrhost)
5930
5931 let ykeep= @@
5932 " get name of new directory from user. A bare <CR> will skip.
5933 " if its currently a directory, also request will be skipped, but with
5934 " a message.
5935 call inputsave()
5936 let newdirname= input("Please give directory name: ")
5937 call inputrestore()
5938
5939 if newdirname == ""
5940 let @@= ykeep
5941 return
5942 endif
5943
5944 if a:usrhost == ""
5945
5946 " Local mkdir:
5947 " sanity checks
5948 let fullnewdir= b:netrw_curdir.'/'.newdirname
5949 if isdirectory(s:NetrwFile(fullnewdir))
5950 if !exists("g:netrw_quiet")
5951 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
5952 endif
5953 let @@= ykeep
5954 return
5955 endif
5956 if s:FileReadable(fullnewdir)
5957 if !exists("g:netrw_quiet")
5958 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
5959 endif
5960 let @@= ykeep
5961 return
5962 endif
5963
5964 " requested new local directory is neither a pre-existing file or
5965 " directory, so make it!
5966 if exists("*mkdir")
5967 if has("unix")
5968 call mkdir(fullnewdir,"p",xor(0777, system("umask")))
5969 else
5970 call mkdir(fullnewdir,"p")
5971 endif
5972 else
5973 let netrw_origdir= s:NetrwGetcwd(1)
5974 if s:NetrwLcd(b:netrw_curdir)
5975 return
5976 endif
5977 call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(newdirname,1))
5978 if v:shell_error != 0
5979 let @@= ykeep
5980 call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
5981 return
5982 endif
5983 if !g:netrw_keepdir
5984 if s:NetrwLcd(netrw_origdir)
5985 return
5986 endif
5987 endif
5988 endif
5989
5990 if v:shell_error == 0
5991 " refresh listing
5992 let svpos= winsaveview()
5993 call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
5994 call winrestview(svpos)
5995 elseif !exists("g:netrw_quiet")
5996 call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
5997 endif
5998
5999 elseif !exists("b:netrw_method") || b:netrw_method == 4
6000 " Remote mkdir: using ssh
6001 let mkdircmd = s:MakeSshCmd(g:netrw_mkdir_cmd)
6002 let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
6003 call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
6004 if v:shell_error == 0
6005 " refresh listing
6006 let svpos= winsaveview()
6007 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
6008 NetrwKeepj call winrestview(svpos)
6009 elseif !exists("g:netrw_quiet")
6010 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
6011 endif
6012
6013 elseif b:netrw_method == 2
6014 " Remote mkdir: using ftp+.netrc
6015 let svpos= winsaveview()
6016 if exists("b:netrw_fname")
6017 let remotepath= b:netrw_fname
6018 else
6019 let remotepath= ""
6020 endif
6021 call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6022 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
6023 NetrwKeepj call winrestview(svpos)
6024
6025 elseif b:netrw_method == 3
6026 " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
6027 let svpos= winsaveview()
6028 if exists("b:netrw_fname")
6029 let remotepath= b:netrw_fname
6030 else
6031 let remotepath= ""
6032 endif
6033 call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6034 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
6035 NetrwKeepj call winrestview(svpos)
6036 endif
6037
6038 let @@= ykeep
6039 endfun
6040
6041 " ---------------------------------------------------------------------
6042 " s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
6043 fun! s:TreeSqueezeDir(islocal)
6044 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6045 " its a tree-listing style
6046 let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
6047 let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
6048 let depth = strchars(substitute(curdepth,' ','','g'))
6049 let srch = -1
6050 if depth >= 2
6051 NetrwKeepj norm! 0
6052 let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
6053 let srch = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
6054 elseif depth == 1
6055 NetrwKeepj norm! 0
6056 let treedepthchr= substitute(s:treedepthstring,' ','','')
6057 let srch = search('^[^'.treedepthchr.']','bW',stopline)
6058 endif
6059 if srch > 0
6060 call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord(),1))
6061 exe srch
6062 endif
6063 endif
6064 endfun
6065
6066 " ---------------------------------------------------------------------
6067 " s:NetrwMaps: {{{2
6068 fun! s:NetrwMaps(islocal)
6069
6070 " mouse <Plug> maps: {{{3
6071 if g:netrw_mousemaps && g:netrw_retmap
6072 " call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
6073 if !hasmapto("<Plug>NetrwReturn")
6074 if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
6075 nmap <unique> <silent> <2-leftmouse> <Plug>NetrwReturn
6076 elseif maparg("<c-leftmouse>","n") == ""
6077 nmap <unique> <silent> <c-leftmouse> <Plug>NetrwReturn
6078 endif
6079 endif
6080 nno <silent> <Plug>NetrwReturn :Rexplore<cr>
6081 endif
6082
6083 " generate default <Plug> maps {{{3
6084 if !hasmapto('<Plug>NetrwHide') |nmap <buffer> <silent> <nowait> a <Plug>NetrwHide_a|endif
6085 if !hasmapto('<Plug>NetrwBrowseUpDir') |nmap <buffer> <silent> <nowait> - <Plug>NetrwBrowseUpDir|endif
6086 if !hasmapto('<Plug>NetrwOpenFile') |nmap <buffer> <silent> <nowait> % <Plug>NetrwOpenFile|endif
6087 if !hasmapto('<Plug>NetrwBadd_cb') |nmap <buffer> <silent> <nowait> cb <Plug>NetrwBadd_cb|endif
6088 if !hasmapto('<Plug>NetrwBadd_cB') |nmap <buffer> <silent> <nowait> cB <Plug>NetrwBadd_cB|endif
6089 if !hasmapto('<Plug>NetrwLcd') |nmap <buffer> <silent> <nowait> cd <Plug>NetrwLcd|endif
6090 if !hasmapto('<Plug>NetrwSetChgwin') |nmap <buffer> <silent> <nowait> C <Plug>NetrwSetChgwin|endif
6091 if !hasmapto('<Plug>NetrwRefresh') |nmap <buffer> <silent> <nowait> <c-l> <Plug>NetrwRefresh|endif
6092 if !hasmapto('<Plug>NetrwLocalBrowseCheck') |nmap <buffer> <silent> <nowait> <cr> <Plug>NetrwLocalBrowseCheck|endif
6093 if !hasmapto('<Plug>NetrwServerEdit') |nmap <buffer> <silent> <nowait> <c-r> <Plug>NetrwServerEdit|endif
6094 if !hasmapto('<Plug>NetrwMakeDir') |nmap <buffer> <silent> <nowait> d <Plug>NetrwMakeDir|endif
6095 if !hasmapto('<Plug>NetrwBookHistHandler_gb')|nmap <buffer> <silent> <nowait> gb <Plug>NetrwBookHistHandler_gb|endif
6096
6097 if a:islocal
6098 " local normal-mode maps {{{3
6099 nnoremap <buffer> <silent> <Plug>NetrwHide_a :<c-u>call <SID>NetrwHide(1)<cr>
6100 nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir :<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6101 nnoremap <buffer> <silent> <Plug>NetrwOpenFile :<c-u>call <SID>NetrwOpenFile(1)<cr>
6102 nnoremap <buffer> <silent> <Plug>NetrwBadd_cb :<c-u>call <SID>NetrwBadd(1,0)<cr>
6103 nnoremap <buffer> <silent> <Plug>NetrwBadd_cB :<c-u>call <SID>NetrwBadd(1,1)<cr>
6104 nnoremap <buffer> <silent> <Plug>NetrwLcd :<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6105 nnoremap <buffer> <silent> <Plug>NetrwSetChgwin :<c-u>call <SID>NetrwSetChgwin()<cr>
6106 nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck :<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6107 nnoremap <buffer> <silent> <Plug>NetrwServerEdit :<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6108 nnoremap <buffer> <silent> <Plug>NetrwMakeDir :<c-u>call <SID>NetrwMakeDir("")<cr>
6109 nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb :<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6110 " ---------------------------------------------------------------------
6111 nnoremap <buffer> <silent> <nowait> gd :<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6112 nnoremap <buffer> <silent> <nowait> gf :<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6113 nnoremap <buffer> <silent> <nowait> gh :<c-u>call <SID>NetrwHidden(1)<cr>
6114 nnoremap <buffer> <silent> <nowait> gn :<c-u>call netrw#SetTreetop(0,<SID>NetrwGetWord())<cr>
6115 nnoremap <buffer> <silent> <nowait> gp :<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6116 nnoremap <buffer> <silent> <nowait> I :<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6117 nnoremap <buffer> <silent> <nowait> i :<c-u>call <SID>NetrwListStyle(1)<cr>
6118 nnoremap <buffer> <silent> <nowait> ma :<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6119 nnoremap <buffer> <silent> <nowait> mA :<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6120 nnoremap <buffer> <silent> <nowait> mb :<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6121 nnoremap <buffer> <silent> <nowait> mB :<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6122 nnoremap <buffer> <silent> <nowait> mc :<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6123 nnoremap <buffer> <silent> <nowait> md :<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6124 nnoremap <buffer> <silent> <nowait> me :<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6125 nnoremap <buffer> <silent> <nowait> mf :<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6126 nnoremap <buffer> <silent> <nowait> mF :<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6127 nnoremap <buffer> <silent> <nowait> mg :<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6128 nnoremap <buffer> <silent> <nowait> mh :<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6129 nnoremap <buffer> <silent> <nowait> mm :<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6130 nnoremap <buffer> <silent> <nowait> mp :<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6131 nnoremap <buffer> <silent> <nowait> mr :<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6132 nnoremap <buffer> <silent> <nowait> ms :<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6133 nnoremap <buffer> <silent> <nowait> mT :<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6134 nnoremap <buffer> <silent> <nowait> mt :<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6135 nnoremap <buffer> <silent> <nowait> mu :<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6136 nnoremap <buffer> <silent> <nowait> mv :<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6137 nnoremap <buffer> <silent> <nowait> mx :<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6138 nnoremap <buffer> <silent> <nowait> mX :<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6139 nnoremap <buffer> <silent> <nowait> mz :<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6140 nnoremap <buffer> <silent> <nowait> O :<c-u>call <SID>NetrwObtain(1)<cr>
6141 nnoremap <buffer> <silent> <nowait> o :call <SID>NetrwSplit(3)<cr>
6142 nnoremap <buffer> <silent> <nowait> p :<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1,1))<cr>
6143 nnoremap <buffer> <silent> <nowait> P :<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6144 nnoremap <buffer> <silent> <nowait> qb :<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6145 nnoremap <buffer> <silent> <nowait> qf :<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6146 nnoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6147 nnoremap <buffer> <silent> <nowait> qL :<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6148 nnoremap <buffer> <silent> <nowait> s :call <SID>NetrwSortStyle(1)<cr>
6149 nnoremap <buffer> <silent> <nowait> S :<c-u>call <SID>NetSortSequence(1)<cr>
6150 nnoremap <buffer> <silent> <nowait> Tb :<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6151 nnoremap <buffer> <silent> <nowait> t :call <SID>NetrwSplit(4)<cr>
6152 nnoremap <buffer> <silent> <nowait> Th :<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6153 nnoremap <buffer> <silent> <nowait> u :<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6154 nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6155 nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(5)<cr>
6156 nnoremap <buffer> <silent> <nowait> x :<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1,0),0)"<cr>
6157 nnoremap <buffer> <silent> <nowait> X :<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6158
6159 nnoremap <buffer> <silent> <nowait> r :<c-u>let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,'./',0))<cr>
6160 if !hasmapto('<Plug>NetrwHideEdit')
6161 nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6162 endif
6163 nnoremap <buffer> <silent> <Plug>NetrwHideEdit :call <SID>NetrwHideEdit(1)<cr>
6164 if !hasmapto('<Plug>NetrwRefresh')
6165 nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6166 endif
6167 nnoremap <buffer> <silent> <Plug>NetrwRefresh <c-l>:call <SID>NetrwRefresh(1,<SID>NetrwBrowseChgDir(1,(exists("w:netrw_liststyle") && exists("w:netrw_treetop") && w:netrw_liststyle == 3)? w:netrw_treetop : './',0))<cr>
6168 if s:didstarstar || !mapcheck("<s-down>","n")
6169 nnoremap <buffer> <silent> <s-down> :Nexplore<cr>
6170 endif
6171 if s:didstarstar || !mapcheck("<s-up>","n")
6172 nnoremap <buffer> <silent> <s-up> :Pexplore<cr>
6173 endif
6174 if !hasmapto('<Plug>NetrwTreeSqueeze')
6175 nmap <buffer> <silent> <nowait> <s-cr> <Plug>NetrwTreeSqueeze
6176 endif
6177 nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze :call <SID>TreeSqueezeDir(1)<cr>
6178 let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6179 if g:netrw_mousemaps == 1
6180 nmap <buffer> <leftmouse> <Plug>NetrwLeftmouse
6181 nmap <buffer> <c-leftmouse> <Plug>NetrwCLeftmouse
6182 nmap <buffer> <middlemouse> <Plug>NetrwMiddlemouse
6183 nmap <buffer> <s-leftmouse> <Plug>NetrwSLeftmouse
6184 nmap <buffer> <s-leftdrag> <Plug>NetrwSLeftdrag
6185 nmap <buffer> <2-leftmouse> <Plug>Netrw2Leftmouse
6186 imap <buffer> <leftmouse> <Plug>ILeftmouse
6187 imap <buffer> <middlemouse> <Plug>IMiddlemouse
6188 nno <buffer> <silent> <Plug>NetrwLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwLeftmouse(1)<cr>
6189 nno <buffer> <silent> <Plug>NetrwCLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwCLeftmouse(1)<cr>
6190 nno <buffer> <silent> <Plug>NetrwMiddlemouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwPrevWinOpen(1)<cr>
6191 nno <buffer> <silent> <Plug>NetrwSLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwSLeftmouse(1)<cr>
6192 nno <buffer> <silent> <Plug>NetrwSLeftdrag :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwSLeftdrag(1)<cr>
6193 nmap <buffer> <silent> <Plug>Netrw2Leftmouse -
6194 exe 'nnoremap <buffer> <silent> <rightmouse> :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6195 exe 'vnoremap <buffer> <silent> <rightmouse> :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6196 endif
6197 exe 'nnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6198 exe 'nnoremap <buffer> <silent> <nowait> D :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6199 exe 'nnoremap <buffer> <silent> <nowait> R :call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6200 exe 'nnoremap <buffer> <silent> <nowait> d :call <SID>NetrwMakeDir("")<cr>'
6201 exe 'vnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6202 exe 'vnoremap <buffer> <silent> <nowait> D :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6203 exe 'vnoremap <buffer> <silent> <nowait> R :call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6204 nnoremap <buffer> <F1> :he netrw-quickhelp<cr>
6205
6206 " support user-specified maps
6207 call netrw#UserMaps(1)
6208
6209 else
6210 " remote normal-mode maps {{{3
6211 call s:RemotePathAnalysis(b:netrw_curdir)
6212 nnoremap <buffer> <silent> <Plug>NetrwHide_a :<c-u>call <SID>NetrwHide(0)<cr>
6213 nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir :<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6214 nnoremap <buffer> <silent> <Plug>NetrwOpenFile :<c-u>call <SID>NetrwOpenFile(0)<cr>
6215 nnoremap <buffer> <silent> <Plug>NetrwBadd_cb :<c-u>call <SID>NetrwBadd(0,0)<cr>
6216 nnoremap <buffer> <silent> <Plug>NetrwBadd_cB :<c-u>call <SID>NetrwBadd(0,1)<cr>
6217 nnoremap <buffer> <silent> <Plug>NetrwLcd :<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6218 nnoremap <buffer> <silent> <Plug>NetrwSetChgwin :<c-u>call <SID>NetrwSetChgwin()<cr>
6219 nnoremap <buffer> <silent> <Plug>NetrwRefresh :<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./',0))<cr>
6220 nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck :<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord(),1))<cr>
6221 nnoremap <buffer> <silent> <Plug>NetrwServerEdit :<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6222 nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb :<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6223 " ---------------------------------------------------------------------
6224 nnoremap <buffer> <silent> <nowait> gd :<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6225 nnoremap <buffer> <silent> <nowait> gf :<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6226 nnoremap <buffer> <silent> <nowait> gh :<c-u>call <SID>NetrwHidden(0)<cr>
6227 nnoremap <buffer> <silent> <nowait> gp :<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6228 nnoremap <buffer> <silent> <nowait> I :<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6229 nnoremap <buffer> <silent> <nowait> i :<c-u>call <SID>NetrwListStyle(0)<cr>
6230 nnoremap <buffer> <silent> <nowait> ma :<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6231 nnoremap <buffer> <silent> <nowait> mA :<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6232 nnoremap <buffer> <silent> <nowait> mb :<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6233 nnoremap <buffer> <silent> <nowait> mB :<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6234 nnoremap <buffer> <silent> <nowait> mc :<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6235 nnoremap <buffer> <silent> <nowait> md :<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6236 nnoremap <buffer> <silent> <nowait> me :<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6237 nnoremap <buffer> <silent> <nowait> mf :<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6238 nnoremap <buffer> <silent> <nowait> mF :<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6239 nnoremap <buffer> <silent> <nowait> mg :<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6240 nnoremap <buffer> <silent> <nowait> mh :<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6241 nnoremap <buffer> <silent> <nowait> mm :<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6242 nnoremap <buffer> <silent> <nowait> mp :<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6243 nnoremap <buffer> <silent> <nowait> mr :<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6244 nnoremap <buffer> <silent> <nowait> ms :<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6245 nnoremap <buffer> <silent> <nowait> mT :<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6246 nnoremap <buffer> <silent> <nowait> mt :<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6247 nnoremap <buffer> <silent> <nowait> mu :<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6248 nnoremap <buffer> <silent> <nowait> mv :<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6249 nnoremap <buffer> <silent> <nowait> mx :<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6250 nnoremap <buffer> <silent> <nowait> mX :<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6251 nnoremap <buffer> <silent> <nowait> mz :<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6252 nnoremap <buffer> <silent> <nowait> O :<c-u>call <SID>NetrwObtain(0)<cr>
6253 nnoremap <buffer> <silent> <nowait> o :call <SID>NetrwSplit(0)<cr>
6254 nnoremap <buffer> <silent> <nowait> p :<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1,1))<cr>
6255 nnoremap <buffer> <silent> <nowait> P :<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6256 nnoremap <buffer> <silent> <nowait> qb :<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6257 nnoremap <buffer> <silent> <nowait> qf :<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6258 nnoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6259 nnoremap <buffer> <silent> <nowait> qL :<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6260 nnoremap <buffer> <silent> <nowait> r :<c-u>let g:netrw_sort_direction= (g:netrw_sort_direction =~# 'n')? 'r' : 'n'<bar>exe "norm! 0"<bar>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,'./',0))<cr>
6261 nnoremap <buffer> <silent> <nowait> s :call <SID>NetrwSortStyle(0)<cr>
6262 nnoremap <buffer> <silent> <nowait> S :<c-u>call <SID>NetSortSequence(0)<cr>
6263 nnoremap <buffer> <silent> <nowait> Tb :<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6264 nnoremap <buffer> <silent> <nowait> t :call <SID>NetrwSplit(1)<cr>
6265 nnoremap <buffer> <silent> <nowait> Th :<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6266 nnoremap <buffer> <silent> <nowait> u :<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6267 nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6268 nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(2)<cr>
6269 nnoremap <buffer> <silent> <nowait> x :<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord(),1),1)<cr>
6270 nmap <buffer> <nowait> gx x
6271 if !hasmapto('<Plug>NetrwHideEdit')
6272 nmap <buffer> <c-h> <Plug>NetrwHideEdit
6273 endif
6274 nnoremap <buffer> <silent> <Plug>NetrwHideEdit :call <SID>NetrwHideEdit(0)<cr>
6275 if !hasmapto('<Plug>NetrwRefresh')
6276 nmap <buffer> <c-l> <Plug>NetrwRefresh
6277 endif
6278 if !hasmapto('<Plug>NetrwTreeSqueeze')
6279 nmap <buffer> <silent> <nowait> <s-cr> <Plug>NetrwTreeSqueeze
6280 endif
6281 nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze :call <SID>TreeSqueezeDir(0)<cr>
6282
6283 let mapsafepath = escape(s:path, s:netrw_map_escape)
6284 let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6285
6286 nnoremap <buffer> <silent> <Plug>NetrwRefresh :call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./',0))<cr>
6287 if g:netrw_mousemaps == 1
6288 nmap <buffer> <leftmouse> <Plug>NetrwLeftmouse
6289 nno <buffer> <silent> <Plug>NetrwLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwLeftmouse(0)<cr>
6290 nmap <buffer> <c-leftmouse> <Plug>NetrwCLeftmouse
6291 nno <buffer> <silent> <Plug>NetrwCLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwCLeftmouse(0)<cr>
6292 nmap <buffer> <s-leftmouse> <Plug>NetrwSLeftmouse
6293 nno <buffer> <silent> <Plug>NetrwSLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwSLeftmouse(0)<cr>
6294 nmap <buffer> <s-leftdrag> <Plug>NetrwSLeftdrag
6295 nno <buffer> <silent> <Plug>NetrwSLeftdrag :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwSLeftdrag(0)<cr>
6296 nmap <middlemouse> <Plug>NetrwMiddlemouse
6297 nno <buffer> <silent> <middlemouse> <Plug>NetrwMiddlemouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwPrevWinOpen(0)<cr>
6298 nmap <buffer> <2-leftmouse> <Plug>Netrw2Leftmouse
6299 nmap <buffer> <silent> <Plug>Netrw2Leftmouse -
6300 imap <buffer> <leftmouse> <Plug>ILeftmouse
6301 imap <buffer> <middlemouse> <Plug>IMiddlemouse
6302 imap <buffer> <s-leftmouse> <Plug>ISLeftmouse
6303 exe 'nnoremap <buffer> <silent> <rightmouse> :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6304 exe 'vnoremap <buffer> <silent> <rightmouse> :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6305 endif
6306 exe 'nnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6307 exe 'nnoremap <buffer> <silent> <nowait> d :call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6308 exe 'nnoremap <buffer> <silent> <nowait> D :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6309 exe 'nnoremap <buffer> <silent> <nowait> R :call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6310 exe 'vnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6311 exe 'vnoremap <buffer> <silent> <nowait> D :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6312 exe 'vnoremap <buffer> <silent> <nowait> R :call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6313 nnoremap <buffer> <F1> :he netrw-quickhelp<cr>
6314
6315 " support user-specified maps
6316 call netrw#UserMaps(0)
6317 endif " }}}3
6318 endfun
6319
6320 " ---------------------------------------------------------------------
6321 " s:NetrwCommands: set up commands {{{2
6322 " If -buffer, the command is only available from within netrw buffers
6323 " Otherwise, the command is available from any window, so long as netrw
6324 " has been used at least once in the session.
6325 fun! s:NetrwCommands(islocal)
6326 " call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6327
6328 com! -nargs=* -complete=file -bang NetrwMB call s:NetrwBookmark(<bang>0,<f-args>)
6329 com! -nargs=* NetrwC call s:NetrwSetChgwin(<q-args>)
6330 com! Rexplore if exists("w:netrw_rexlocal")|call s:NetrwRexplore(w:netrw_rexlocal,exists("w:netrw_rexdir")? w:netrw_rexdir : ".")|else|call netrw#ErrorMsg(s:WARNING,"win#".winnr()." not a former netrw window",79)|endif
6331 if a:islocal
6332 com! -buffer -nargs=+ -complete=file MF call s:NetrwMarkFiles(1,<f-args>)
6333 else
6334 com! -buffer -nargs=+ -complete=file MF call s:NetrwMarkFiles(0,<f-args>)
6335 endif
6336 com! -buffer -nargs=? -complete=file MT call s:NetrwMarkTarget(<q-args>)
6337
6338 " call Dret("s:NetrwCommands")
6339 endfun
6340
6341 " ---------------------------------------------------------------------
6342 " s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6343 " glob()ing only works with local files
6344 fun! s:NetrwMarkFiles(islocal,...)
6345 " call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6346 let curdir = s:NetrwGetCurdir(a:islocal)
6347 let i = 1
6348 while i <= a:0
6349 if a:islocal
6350 if v:version > 704 || (v:version == 704 && has("patch656"))
6351 let mffiles= glob(a:{i},0,1,1)
6352 else
6353 let mffiles= glob(a:{i},0,1)
6354 endif
6355 else
6356 let mffiles= [a:{i}]
6357 endif
6358 " call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6359 for mffile in mffiles
6360 " call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6361 call s:NetrwMarkFile(a:islocal,mffile)
6362 endfor
6363 let i= i + 1
6364 endwhile
6365 " call Dret("s:NetrwMarkFiles")
6366 endfun
6367
6368 " ---------------------------------------------------------------------
6369 " s:NetrwMarkTarget: implements :MT (mark target) {{{2
6370 fun! s:NetrwMarkTarget(...)
6371 if a:0 == 0 || (a:0 == 1 && a:1 == "")
6372 let curdir = s:NetrwGetCurdir(1)
6373 let tgt = b:netrw_curdir
6374 else
6375 let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6376 let tgt = a:1
6377 endif
6378 let s:netrwmftgt = tgt
6379 let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6380 let curislocal = b:netrw_curdir !~ '^\a\{3,}://'
6381 let svpos = winsaveview()
6382 call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./',0))
6383 call winrestview(svpos)
6384 endfun
6385
6386 " ---------------------------------------------------------------------
6387 " s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6388 " mark and unmark files. If a markfile list exists,
6389 " then the rename and delete functions will use it instead
6390 " of whatever may happen to be under the cursor at that
6391 " moment. When the mouse and gui are available,
6392 " shift-leftmouse may also be used to mark files.
6393 "
6394 " Creates two lists
6395 " s:netrwmarkfilelist -- holds complete paths to all marked files
6396 " s:netrwmarkfilelist_# -- holds list of marked files in current-buffer's directory (#==bufnr())
6397 "
6398 " Creates a marked file match string
6399 " s:netrwmarfilemtch_# -- used with 2match to display marked files
6400 "
6401 " Creates a buffer version of islocal
6402 " b:netrw_islocal
6403 fun! s:NetrwMarkFile(islocal,fname)
6404 " call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6405 " call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6406
6407 " sanity check
6408 if empty(a:fname)
6409 " call Dret("s:NetrwMarkFile : empty fname")
6410 return
6411 endif
6412 let curdir = s:NetrwGetCurdir(a:islocal)
6413
6414 let ykeep = @@
6415 let curbufnr= bufnr("%")
6416 let leader= '\%(^\|\s\)\zs'
6417 if a:fname =~ '\a$'
6418 let trailer = '\>[@=|\/\*]\=\ze\%( \|\t\|$\)'
6419 else
6420 let trailer = '[@=|\/\*]\=\ze\%( \|\t\|$\)'
6421 endif
6422
6423 if exists("s:netrwmarkfilelist_".curbufnr)
6424 " markfile list pre-exists
6425 " call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6426 " call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6427 " call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6428 let b:netrw_islocal= a:islocal
6429
6430 if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6431 " append filename to buffer's markfilelist
6432 " call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6433 call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6434 let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
6435
6436 else
6437 " remove filename from buffer's markfilelist
6438 " call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6439 call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6440 if s:netrwmarkfilelist_{curbufnr} == []
6441 " local markfilelist is empty; remove it entirely
6442 " call Decho("markfile list now empty",'~'.expand("<slnum>"))
6443 call s:NetrwUnmarkList(curbufnr,curdir)
6444 else
6445 " rebuild match list to display markings correctly
6446 " call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6447 let s:netrwmarkfilemtch_{curbufnr}= ""
6448 let first = 1
6449 for fname in s:netrwmarkfilelist_{curbufnr}
6450 if first
6451 let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6452 else
6453 let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6454 endif
6455 let first= 0
6456 endfor
6457 " call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6458 endif
6459 endif
6460
6461 else
6462 " initialize new markfilelist
6463 " call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6464
6465 " call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6466 let s:netrwmarkfilelist_{curbufnr}= []
6467 call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6468 " call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6469
6470 " build initial markfile matching pattern
6471 if a:fname =~ '/$'
6472 let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6473 else
6474 let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6475 endif
6476 " call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6477 endif
6478
6479 " handle global markfilelist
6480 if exists("s:netrwmarkfilelist")
6481 let dname= s:ComposePath(b:netrw_curdir,a:fname)
6482 if index(s:netrwmarkfilelist,dname) == -1
6483 " append new filename to global markfilelist
6484 call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6485 " call Decho("append filename<".a:fname."> to global s:markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6486 else
6487 " remove new filename from global markfilelist
6488 " call Decho("remove new filename from global s:markfilelist",'~'.expand("<slnum>"))
6489 " call Decho("..filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6490 call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6491 " call Decho("..ending s:netrwmarkfilelist <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6492 if s:netrwmarkfilelist == []
6493 " call Decho("s:netrwmarkfilelist is empty; unlet it",'~'.expand("<slnum>"))
6494 unlet s:netrwmarkfilelist
6495 endif
6496 endif
6497 else
6498 " initialize new global-directory markfilelist
6499 let s:netrwmarkfilelist= []
6500 call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6501 " call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6502 endif
6503
6504 " set up 2match'ing to netrwmarkfilemtch_# list
6505 if has("syntax") && exists("g:syntax_on") && g:syntax_on
6506 if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6507 " " call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6508 if exists("g:did_drchip_netrwlist_syntax")
6509 exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6510 endif
6511 else
6512 " " call Decho("2match none",'~'.expand("<slnum>"))
6513 2match none
6514 endif
6515 endif
6516 let @@= ykeep
6517 " call Decho("s:netrwmarkfilelist[".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : "")."] (avail in all buffers)",'~'.expand("<slnum>"))
6518 " call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist")."> (buf#".curbufnr."list)")
6519 endfun
6520
6521 " ---------------------------------------------------------------------
6522 " s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6523 " mA: move the argument list to marked file list (tomflist=1)
6524 " Uses the global marked file list
6525 fun! s:NetrwMarkFileArgList(islocal,tomflist)
6526 let svpos = winsaveview()
6527 let curdir = s:NetrwGetCurdir(a:islocal)
6528 let curbufnr = bufnr("%")
6529
6530 if a:tomflist
6531 " mA: move argument list to marked file list
6532 while argc()
6533 let fname= argv(0)
6534 exe "argdel ".fnameescape(fname)
6535 call s:NetrwMarkFile(a:islocal,fname)
6536 endwhile
6537
6538 else
6539 " ma: move marked file list to argument list
6540 if exists("s:netrwmarkfilelist")
6541
6542 " for every filename in the marked list
6543 for fname in s:netrwmarkfilelist
6544 exe "argadd ".fnameescape(fname)
6545 endfor " for every file in the marked list
6546
6547 " unmark list and refresh
6548 call s:NetrwUnmarkList(curbufnr,curdir)
6549 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
6550 NetrwKeepj call winrestview(svpos)
6551 endif
6552 endif
6553 endfun
6554
6555 " ---------------------------------------------------------------------
6556 " s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6557 " compress/decompress files using the programs
6558 " in g:netrw_compress and g:netrw_uncompress,
6559 " using g:netrw_compress_suffix to know which to
6560 " do. By default:
6561 " g:netrw_compress = "gzip"
6562 " g:netrw_decompress = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6563 fun! s:NetrwMarkFileCompress(islocal)
6564 let svpos = winsaveview()
6565 let curdir = s:NetrwGetCurdir(a:islocal)
6566 let curbufnr = bufnr("%")
6567
6568 " sanity check
6569 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6570 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6571 return
6572 endif
6573
6574 if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6575
6576 " for every filename in the marked list
6577 for fname in s:netrwmarkfilelist_{curbufnr}
6578 let sfx= substitute(fname,'^.\{-}\(\.[[:alnum:]]\+\)$','\1','')
6579 if exists("g:netrw_decompress['".sfx."']")
6580 " fname has a suffix indicating that its compressed; apply associated decompression routine
6581 let exe= g:netrw_decompress[sfx]
6582 let exe= netrw#WinPath(exe)
6583 if a:islocal
6584 if g:netrw_keepdir
6585 let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6586 endif
6587 call system(exe." ".fname)
6588 if v:shell_error
6589 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6590 endif
6591 else
6592 let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6593 NetrwKeepj call s:RemoteSystem(exe." ".fname)
6594 endif
6595
6596 endif
6597 unlet sfx
6598
6599 if exists("exe")
6600 unlet exe
6601 elseif a:islocal
6602 " fname not a compressed file, so compress it
6603 call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
6604 if v:shell_error
6605 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_compress<".g:netrw_compress."> to something that works",104)
6606 endif
6607 else
6608 " fname not a compressed file, so compress it
6609 NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
6610 endif
6611 endfor " for every file in the marked list
6612
6613 call s:NetrwUnmarkList(curbufnr,curdir)
6614 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
6615 NetrwKeepj call winrestview(svpos)
6616 endif
6617 endfun
6618
6619 " ---------------------------------------------------------------------
6620 " s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
6621 " If no marked files, then set up directory as the
6622 " target. Currently does not support copying entire
6623 " directories. Uses the local-buffer marked file list.
6624 " Returns 1=success (used by NetrwMarkFileMove())
6625 " 0=failure
6626 fun! s:NetrwMarkFileCopy(islocal,...)
6627 " call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
6628
6629 let curdir = s:NetrwGetCurdir(a:islocal)
6630 let curbufnr = bufnr("%")
6631 if b:netrw_curdir !~ '/$'
6632 if !exists("b:netrw_curdir")
6633 let b:netrw_curdir= curdir
6634 endif
6635 let b:netrw_curdir= b:netrw_curdir."/"
6636 endif
6637
6638 " sanity check
6639 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6640 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6641 " call Dret("s:NetrwMarkFileCopy")
6642 return
6643 endif
6644 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6645
6646 if !exists("s:netrwmftgt")
6647 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
6648 " call Dret("s:NetrwMarkFileCopy 0")
6649 return 0
6650 endif
6651 " call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
6652
6653 if a:islocal && s:netrwmftgt_islocal
6654 " Copy marked files, local directory to local directory
6655 " call Decho("copy from local to local",'~'.expand("<slnum>"))
6656 if !executable(g:netrw_localcopycmd)
6657 call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
6658 " call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
6659 return
6660 endif
6661
6662 " copy marked files while within the same directory (ie. allow renaming)
6663 if s:StripTrailingSlash(simplify(s:netrwmftgt)) == s:StripTrailingSlash(simplify(b:netrw_curdir))
6664 if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
6665 " only one marked file
6666 " call Decho("case: only one marked file",'~'.expand("<slnum>"))
6667 let args = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
6668 let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
6669 elseif a:0 == 1
6670 " call Decho("case: handling one input argument",'~'.expand("<slnum>"))
6671 " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
6672 let args = s:ShellEscape(b:netrw_curdir.a:1)
6673 let oldname = a:1
6674 else
6675 " copy multiple marked files inside the same directory
6676 " call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
6677 let s:recursive= 1
6678 for oldname in s:netrwmarkfilelist_{bufnr("%")}
6679 let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
6680 if ret == 0
6681 break
6682 endif
6683 endfor
6684 unlet s:recursive
6685 call s:NetrwUnmarkList(curbufnr,curdir)
6686 " call Dret("s:NetrwMarkFileCopy ".ret)
6687 return ret
6688 endif
6689
6690 call inputsave()
6691 let newname= input("Copy ".oldname." to : ",oldname,"file")
6692 call inputrestore()
6693 if newname == ""
6694 " call Dret("s:NetrwMarkFileCopy 0")
6695 return 0
6696 endif
6697 let args= s:ShellEscape(oldname)
6698 let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
6699 else
6700 let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
6701 let tgt = s:ShellEscape(s:netrwmftgt)
6702 endif
6703 if !g:netrw_cygwin && has("win32")
6704 let args= substitute(args,'/','\\','g')
6705 let tgt = substitute(tgt, '/','\\','g')
6706 endif
6707 if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
6708 if tgt =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
6709 if args =~ '//'|let args= substitute(args,'//','/','g')|endif
6710 if tgt =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
6711 " call Decho("args <".args.">",'~'.expand("<slnum>"))
6712 " call Decho("tgt <".tgt.">",'~'.expand("<slnum>"))
6713 if isdirectory(s:NetrwFile(args))
6714 " call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
6715 let copycmd= g:netrw_localcopydircmd
6716 " call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
6717 if !g:netrw_cygwin && has("win32")
6718 " window's xcopy doesn't copy a directory to a target properly. Instead, it copies a directory's
6719 " contents to a target. One must append the source directory name to the target to get xcopy to
6720 " do the right thing.
6721 let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
6722 " call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
6723 endif
6724 else
6725 let copycmd= g:netrw_localcopycmd
6726 endif
6727 if g:netrw_localcopycmd =~ '\s'
6728 let copycmd = substitute(copycmd,'\s.*$','','')
6729 let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
6730 let copycmd = netrw#WinPath(copycmd).copycmdargs
6731 else
6732 let copycmd = netrw#WinPath(copycmd)
6733 endif
6734 " call Decho("args <".args.">",'~'.expand("<slnum>"))
6735 " call Decho("tgt <".tgt.">",'~'.expand("<slnum>"))
6736 " call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
6737 " call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
6738 call system(copycmd.g:netrw_localcopycmdopt." '".args."' '".tgt."'")
6739 if v:shell_error != 0
6740 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && g:netrw_keepdir
6741 call netrw#ErrorMsg(s:ERROR,"copy failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-cd)",101)
6742 else
6743 call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
6744 endif
6745 " call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
6746 return 0
6747 endif
6748
6749 elseif a:islocal && !s:netrwmftgt_islocal
6750 " Copy marked files, local directory to remote directory
6751 " call Decho("copy from local to remote",'~'.expand("<slnum>"))
6752 NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6753
6754 elseif !a:islocal && s:netrwmftgt_islocal
6755 " Copy marked files, remote directory to local directory
6756 " call Decho("copy from remote to local",'~'.expand("<slnum>"))
6757 NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6758
6759 elseif !a:islocal && !s:netrwmftgt_islocal
6760 " Copy marked files, remote directory to remote directory
6761 " call Decho("copy from remote to remote",'~'.expand("<slnum>"))
6762 let curdir = getcwd()
6763 let tmpdir = s:GetTempfile("")
6764 if tmpdir !~ '/'
6765 let tmpdir= curdir."/".tmpdir
6766 endif
6767 if exists("*mkdir")
6768 call mkdir(tmpdir)
6769 else
6770 call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(tmpdir,1))
6771 if v:shell_error != 0
6772 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6773 " call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
6774 return
6775 endif
6776 endif
6777 if isdirectory(s:NetrwFile(tmpdir))
6778 if s:NetrwLcd(tmpdir)
6779 " call Dret("s:NetrwMarkFileCopy : lcd failure")
6780 return
6781 endif
6782 NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
6783 let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
6784 NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
6785 if getcwd() == tmpdir
6786 for fname in s:netrwmarkfilelist_{bufnr('%')}
6787 NetrwKeepj call s:NetrwDelete(fname)
6788 endfor
6789 if s:NetrwLcd(curdir)
6790 " call Dret("s:NetrwMarkFileCopy : lcd failure")
6791 return
6792 endif
6793 if delete(tmpdir,"d")
6794 call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
6795 endif
6796 else
6797 if s:NetrwLcd(curdir)
6798 " call Dret("s:NetrwMarkFileCopy : lcd failure")
6799 return
6800 endif
6801 endif
6802 endif
6803 endif
6804
6805 " -------
6806 " cleanup
6807 " -------
6808 " call Decho("cleanup",'~'.expand("<slnum>"))
6809 " remove markings from local buffer
6810 call s:NetrwUnmarkList(curbufnr,curdir) " remove markings from local buffer
6811 " call Decho(" g:netrw_fastbrowse =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
6812 " call Decho(" s:netrwmftgt =".s:netrwmftgt,'~'.expand("<slnum>"))
6813 " call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
6814 " call Decho(" curdir =".curdir,'~'.expand("<slnum>"))
6815 " call Decho(" a:islocal =".a:islocal,'~'.expand("<slnum>"))
6816 " call Decho(" curbufnr =".curbufnr,'~'.expand("<slnum>"))
6817 if exists("s:recursive")
6818 " call Decho(" s:recursive =".s:recursive,'~'.expand("<slnum>"))
6819 else
6820 " call Decho(" s:recursive =n/a",'~'.expand("<slnum>"))
6821 endif
6822 " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
6823 if g:netrw_fastbrowse <= 1
6824 NetrwKeepj call s:LocalBrowseRefresh()
6825 else
6826 " refresh local and targets for fast browsing
6827 if !exists("s:recursive")
6828 " remove markings from local buffer
6829 " call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
6830 NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
6831 endif
6832
6833 " refresh buffers
6834 if s:netrwmftgt_islocal
6835 " call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
6836 NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
6837 endif
6838 if a:islocal && s:netrwmftgt != curdir
6839 " call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
6840 NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
6841 endif
6842 endif
6843
6844 " call Dret("s:NetrwMarkFileCopy 1")
6845 return 1
6846 endfun
6847
6848 " ---------------------------------------------------------------------
6849 " s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
6850 " invoke vim's diff mode on the marked files.
6851 " Either two or three files can be so handled.
6852 " Uses the global marked file list.
6853 fun! s:NetrwMarkFileDiff(islocal)
6854 " call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6855 let curbufnr= bufnr("%")
6856
6857 " sanity check
6858 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6859 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6860 " call Dret("s:NetrwMarkFileDiff")
6861 return
6862 endif
6863 let curdir= s:NetrwGetCurdir(a:islocal)
6864 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6865
6866 if exists("s:netrwmarkfilelist_{".curbufnr."}")
6867 let cnt = 0
6868 for fname in s:netrwmarkfilelist
6869 let cnt= cnt + 1
6870 if cnt == 1
6871 " call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
6872 exe "NetrwKeepj e ".fnameescape(fname)
6873 diffthis
6874 elseif cnt == 2 || cnt == 3
6875 below vsplit
6876 " call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
6877 exe "NetrwKeepj e ".fnameescape(fname)
6878 diffthis
6879 else
6880 break
6881 endif
6882 endfor
6883 call s:NetrwUnmarkList(curbufnr,curdir)
6884 endif
6885
6886 " call Dret("s:NetrwMarkFileDiff")
6887 endfun
6888
6889 " ---------------------------------------------------------------------
6890 " s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
6891 " Uses global markfilelist
6892 fun! s:NetrwMarkFileEdit(islocal)
6893 " call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
6894
6895 let curdir = s:NetrwGetCurdir(a:islocal)
6896 let curbufnr = bufnr("%")
6897
6898 " sanity check
6899 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6900 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6901 " call Dret("s:NetrwMarkFileEdit")
6902 return
6903 endif
6904 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6905
6906 if exists("s:netrwmarkfilelist_{curbufnr}")
6907 call s:SetRexDir(a:islocal,curdir)
6908 let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
6909 " unmark markedfile list
6910 " call s:NetrwUnmarkList(curbufnr,curdir)
6911 call s:NetrwUnmarkAll()
6912 " call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
6913 exe "sil args ".flist
6914 endif
6915 echo "(use :bn, :bp to navigate files; :Rex to return)"
6916
6917 " call Dret("s:NetrwMarkFileEdit")
6918 endfun
6919
6920 " ---------------------------------------------------------------------
6921 " s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
6922 fun! s:NetrwMarkFileQFEL(islocal,qfel)
6923 " call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
6924 call s:NetrwUnmarkAll()
6925 let curbufnr= bufnr("%")
6926
6927 if !empty(a:qfel)
6928 for entry in a:qfel
6929 let bufnmbr= entry["bufnr"]
6930 " call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
6931 if !exists("s:netrwmarkfilelist_{curbufnr}")
6932 " call Decho("case: no marked file list",'~'.expand("<slnum>"))
6933 call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
6934 elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
6935 " s:NetrwMarkFile will remove duplicate entries from the marked file list.
6936 " So, this test lets two or more hits on the same pattern to be ignored.
6937 " call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
6938 call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
6939 else
6940 " call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
6941 endif
6942 endfor
6943 echo "(use me to edit marked files)"
6944 else
6945 call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
6946 endif
6947
6948 " call Dret("s:NetrwMarkFileQFEL")
6949 endfun
6950
6951 " ---------------------------------------------------------------------
6952 " s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
6953 " mx enbloc=0: Uses the local marked-file list, applies command to each file individually
6954 " mX enbloc=1: Uses the global marked-file list, applies command to entire list
6955 fun! s:NetrwMarkFileExe(islocal,enbloc)
6956 let svpos = winsaveview()
6957 let curdir = s:NetrwGetCurdir(a:islocal)
6958 let curbufnr = bufnr("%")
6959
6960 if a:enbloc == 0
6961 " individually apply command to files, one at a time
6962 " sanity check
6963 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6964 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6965 return
6966 endif
6967
6968 if exists("s:netrwmarkfilelist_{curbufnr}")
6969 " get the command
6970 call inputsave()
6971 let cmd= input("Enter command: ","","file")
6972 call inputrestore()
6973 if cmd == ""
6974 return
6975 endif
6976
6977 " apply command to marked files, individually. Substitute: filename -> %
6978 " If no %, then append a space and the filename to the command
6979 for fname in s:netrwmarkfilelist_{curbufnr}
6980 if a:islocal
6981 if g:netrw_keepdir
6982 let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
6983 endif
6984 else
6985 let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
6986 endif
6987 if cmd =~ '%'
6988 let xcmd= substitute(cmd,'%',fname,'g')
6989 else
6990 let xcmd= cmd.' '.fname
6991 endif
6992 if a:islocal
6993 let ret= system(xcmd)
6994 else
6995 let ret= s:RemoteSystem(xcmd)
6996 endif
6997 if v:shell_error < 0
6998 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
6999 break
7000 else
7001 if ret !=# ''
7002 echo "\n"
7003 " skip trailing new line
7004 echo ret[0:-2]
7005 else
7006 echo ret
7007 endif
7008 endif
7009 endfor
7010
7011 " unmark marked file list
7012 call s:NetrwUnmarkList(curbufnr,curdir)
7013
7014 " refresh the listing
7015 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7016 NetrwKeepj call winrestview(svpos)
7017 else
7018 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7019 endif
7020
7021 else " apply command to global list of files, en bloc
7022
7023 call inputsave()
7024 let cmd= input("Enter command: ","","file")
7025 call inputrestore()
7026 if cmd == ""
7027 return
7028 endif
7029 if cmd =~ '%'
7030 let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7031 else
7032 let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7033 endif
7034 if a:islocal
7035 call system(cmd)
7036 if v:shell_error < 0
7037 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7038 endif
7039 else
7040 let ret= s:RemoteSystem(cmd)
7041 endif
7042 call s:NetrwUnmarkAll()
7043
7044 " refresh the listing
7045 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7046 NetrwKeepj call winrestview(svpos)
7047
7048 endif
7049 endfun
7050
7051 " ---------------------------------------------------------------------
7052 " s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7053 " as the marked file(s) (toggles suffix presence)
7054 " Uses the local marked file list.
7055 fun! s:NetrwMarkHideSfx(islocal)
7056 let svpos = winsaveview()
7057 let curbufnr = bufnr("%")
7058
7059 " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7060 if exists("s:netrwmarkfilelist_{curbufnr}")
7061
7062 for fname in s:netrwmarkfilelist_{curbufnr}
7063 " construct suffix pattern
7064 if fname =~ '\.'
7065 let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7066 else
7067 let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7068 endif
7069 " determine if its in the hiding list or not
7070 let inhidelist= 0
7071 if g:netrw_list_hide != ""
7072 let itemnum = 0
7073 let hidelist= split(g:netrw_list_hide,',')
7074 for hidepat in hidelist
7075 if sfxpat == hidepat
7076 let inhidelist= 1
7077 break
7078 endif
7079 let itemnum= itemnum + 1
7080 endfor
7081 endif
7082 if inhidelist
7083 " remove sfxpat from list
7084 call remove(hidelist,itemnum)
7085 let g:netrw_list_hide= join(hidelist,",")
7086 elseif g:netrw_list_hide != ""
7087 " append sfxpat to non-empty list
7088 let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7089 else
7090 " set hiding list to sfxpat
7091 let g:netrw_list_hide= sfxpat
7092 endif
7093 endfor
7094
7095 " refresh the listing
7096 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7097 NetrwKeepj call winrestview(svpos)
7098 else
7099 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7100 endif
7101 endfun
7102
7103 " ---------------------------------------------------------------------
7104 " s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7105 " Uses the local marked-file list.
7106 fun! s:NetrwMarkFileVimCmd(islocal)
7107 let svpos = winsaveview()
7108 let curdir = s:NetrwGetCurdir(a:islocal)
7109 let curbufnr = bufnr("%")
7110
7111 " sanity check
7112 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7113 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7114 return
7115 endif
7116
7117 if exists("s:netrwmarkfilelist_{curbufnr}")
7118 " get the command
7119 call inputsave()
7120 let cmd= input("Enter vim command: ","","file")
7121 call inputrestore()
7122 if cmd == ""
7123 return
7124 endif
7125
7126 " apply command to marked files. Substitute: filename -> %
7127 " If no %, then append a space and the filename to the command
7128 for fname in s:netrwmarkfilelist_{curbufnr}
7129 if a:islocal
7130 1split
7131 exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7132 exe cmd
7133 exe "sil! keepalt wq!"
7134 else
7135 echo "sorry, \"mv\" not supported yet for remote files"
7136 endif
7137 endfor
7138
7139 " unmark marked file list
7140 call s:NetrwUnmarkList(curbufnr,curdir)
7141
7142 " refresh the listing
7143 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7144 NetrwKeepj call winrestview(svpos)
7145 else
7146 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7147 endif
7148 endfun
7149
7150 " ---------------------------------------------------------------------
7151 " s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7152 " as the marked file(s) (toggles suffix presence)
7153 " Uses the local marked file list.
7154 fun! s:NetrwMarkHideSfx(islocal)
7155 let svpos = winsaveview()
7156 let curbufnr = bufnr("%")
7157
7158 " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7159 if exists("s:netrwmarkfilelist_{curbufnr}")
7160
7161 for fname in s:netrwmarkfilelist_{curbufnr}
7162 " construct suffix pattern
7163 if fname =~ '\.'
7164 let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7165 else
7166 let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7167 endif
7168 " determine if its in the hiding list or not
7169 let inhidelist= 0
7170 if g:netrw_list_hide != ""
7171 let itemnum = 0
7172 let hidelist= split(g:netrw_list_hide,',')
7173 for hidepat in hidelist
7174 if sfxpat == hidepat
7175 let inhidelist= 1
7176 break
7177 endif
7178 let itemnum= itemnum + 1
7179 endfor
7180 endif
7181 if inhidelist
7182 " remove sfxpat from list
7183 call remove(hidelist,itemnum)
7184 let g:netrw_list_hide= join(hidelist,",")
7185 elseif g:netrw_list_hide != ""
7186 " append sfxpat to non-empty list
7187 let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7188 else
7189 " set hiding list to sfxpat
7190 let g:netrw_list_hide= sfxpat
7191 endif
7192 endfor
7193
7194 " refresh the listing
7195 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7196 NetrwKeepj call winrestview(svpos)
7197 else
7198 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7199 endif
7200 endfun
7201
7202 " ---------------------------------------------------------------------
7203 " s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7204 " Uses the global markfilelist
7205 fun! s:NetrwMarkFileGrep(islocal)
7206 " call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7207 let svpos = winsaveview()
7208 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7209 let curbufnr = bufnr("%")
7210 let curdir = s:NetrwGetCurdir(a:islocal)
7211
7212 if exists("s:netrwmarkfilelist")
7213 " call Decho("using s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7214 let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7215 " call Decho("keeping copy of s:netrwmarkfilelist in function-local variable,'~'.expand("<slnum>"))"
7216 call s:NetrwUnmarkAll()
7217 else
7218 " call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7219 let netrwmarkfilelist= "*"
7220 endif
7221
7222 " ask user for pattern
7223 " call Decho("ask user for search pattern",'~'.expand("<slnum>"))
7224 call inputsave()
7225 let pat= input("Enter pattern: ","")
7226 call inputrestore()
7227 let patbang = ""
7228 if pat =~ '^!'
7229 let patbang = "!"
7230 let pat = strpart(pat,2)
7231 endif
7232 if pat =~ '^\i'
7233 let pat = escape(pat,'/')
7234 let pat = '/'.pat.'/'
7235 else
7236 let nonisi = pat[0]
7237 endif
7238
7239 " use vimgrep for both local and remote
7240 " call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007241 try
Luca Saccarolac363ca12024-12-19 20:16:18 +01007242 exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7243 catch /^Vim\%((\a\+)\)\=:E480/
7244 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7245 " call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7246 return
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007247 endtry
Luca Saccarolac363ca12024-12-19 20:16:18 +01007248 echo "(use :cn, :cp to navigate, :Rex to return)"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007249
Luca Saccarolac363ca12024-12-19 20:16:18 +01007250 2match none
7251 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7252 NetrwKeepj call winrestview(svpos)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007253
Luca Saccarolac363ca12024-12-19 20:16:18 +01007254 if exists("nonisi")
7255 " original, user-supplied pattern did not begin with a character from isident
7256 " call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7257 if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7258 call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7259 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00007260 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00007261
Luca Saccarolac363ca12024-12-19 20:16:18 +01007262 " call Dret("s:NetrwMarkFileGrep")
7263 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00007264
Luca Saccarolac363ca12024-12-19 20:16:18 +01007265 " ---------------------------------------------------------------------
7266 " s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7267 " uses the global marked file list
7268 " s:netrwmfloc= 0: target directory is remote
7269 " = 1: target directory is local
7270 fun! s:NetrwMarkFileMove(islocal)
7271 " call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7272 let curdir = s:NetrwGetCurdir(a:islocal)
7273 let curbufnr = bufnr("%")
Bram Moolenaar446cb832008-06-24 21:56:24 +00007274
Luca Saccarolac363ca12024-12-19 20:16:18 +01007275 " sanity check
7276 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7277 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7278 " call Dret("s:NetrwMarkFileMove")
7279 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00007280 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01007281 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7282
7283 if !exists("s:netrwmftgt")
7284 NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7285 " call Dret("s:NetrwMarkFileCopy 0")
7286 return 0
Bram Moolenaar46973992017-12-14 19:56:46 +01007287 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01007288 " call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02007289
Luca Saccarolac363ca12024-12-19 20:16:18 +01007290 if a:islocal && s:netrwmftgt_islocal
7291 " move: local -> local
7292 " call Decho("move from local to local",'~'.expand("<slnum>"))
7293 " call Decho("local to local move",'~'.expand("<slnum>"))
7294 if !executable(g:netrw_localmovecmd)
7295 call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7296 " call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7297 return
7298 endif
7299 let tgt = s:ShellEscape(s:netrwmftgt)
7300 " call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7301 if !g:netrw_cygwin && has("win32")
7302 let tgt= substitute(tgt, '/','\\','g')
7303 " call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7304 if g:netrw_localmovecmd =~ '\s'
7305 let movecmd = substitute(g:netrw_localmovecmd,'\s.*$','','')
7306 let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7307 let movecmd = netrw#WinPath(movecmd).movecmdargs
7308 " call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7309 else
7310 let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7311 " call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7312 endif
7313 else
7314 let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7315 " call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7316 endif
7317 for fname in s:netrwmarkfilelist_{bufnr("%")}
7318 if g:netrw_keepdir
7319 " Jul 19, 2022: fixing file move when g:netrw_keepdir is 1
7320 let fname= b:netrw_curdir."/".fname
7321 endif
7322 if !g:netrw_cygwin && has("win32")
7323 let fname= substitute(fname,'/','\\','g')
7324 endif
7325 " call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7326 let ret= system(movecmd.g:netrw_localmovecmdopt." ".s:ShellEscape(fname)." ".tgt)
7327 if v:shell_error != 0
7328 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7329 call netrw#ErrorMsg(s:ERROR,"move failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-cd)",100)
7330 else
7331 call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7332 endif
7333 break
7334 endif
7335 endfor
Bram Moolenaarff034192013-04-24 18:51:19 +02007336
Luca Saccarolac363ca12024-12-19 20:16:18 +01007337 elseif a:islocal && !s:netrwmftgt_islocal
7338 " move: local -> remote
7339 " call Decho("move from local to remote",'~'.expand("<slnum>"))
7340 " call Decho("copy",'~'.expand("<slnum>"))
7341 let mflist= s:netrwmarkfilelist_{bufnr("%")}
7342 NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7343 " call Decho("remove",'~'.expand("<slnum>"))
7344 for fname in mflist
7345 let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7346 let ok = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7347 endfor
7348 unlet mflist
Bram Moolenaarff034192013-04-24 18:51:19 +02007349
Luca Saccarolac363ca12024-12-19 20:16:18 +01007350 elseif !a:islocal && s:netrwmftgt_islocal
7351 " move: remote -> local
7352 " call Decho("move from remote to local",'~'.expand("<slnum>"))
7353 " call Decho("copy",'~'.expand("<slnum>"))
7354 let mflist= s:netrwmarkfilelist_{bufnr("%")}
7355 NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7356 " call Decho("remove",'~'.expand("<slnum>"))
7357 for fname in mflist
7358 let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7359 let ok = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7360 endfor
7361 unlet mflist
Bram Moolenaar446cb832008-06-24 21:56:24 +00007362
Luca Saccarolac363ca12024-12-19 20:16:18 +01007363 elseif !a:islocal && !s:netrwmftgt_islocal
7364 " move: remote -> remote
7365 " call Decho("move from remote to remote",'~'.expand("<slnum>"))
7366 " call Decho("copy",'~'.expand("<slnum>"))
7367 let mflist= s:netrwmarkfilelist_{bufnr("%")}
7368 NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7369 " call Decho("remove",'~'.expand("<slnum>"))
7370 for fname in mflist
7371 let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7372 let ok = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7373 endfor
7374 unlet mflist
Bram Moolenaare6ae6222013-05-21 21:01:10 +02007375 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +02007376
Luca Saccarolac363ca12024-12-19 20:16:18 +01007377 " -------
7378 " cleanup
7379 " -------
7380 " call Decho("cleanup",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00007381
Luca Saccarolac363ca12024-12-19 20:16:18 +01007382 " remove markings from local buffer
7383 call s:NetrwUnmarkList(curbufnr,curdir) " remove markings from local buffer
Bram Moolenaar446cb832008-06-24 21:56:24 +00007384
Luca Saccarolac363ca12024-12-19 20:16:18 +01007385 " refresh buffers
7386 if !s:netrwmftgt_islocal
7387 " call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7388 NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007389 endif
7390 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01007391 " call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7392 NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007393 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01007394 if g:netrw_fastbrowse <= 1
7395 " call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7396 NetrwKeepj call s:LocalBrowseRefresh()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007397 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00007398
Luca Saccarolac363ca12024-12-19 20:16:18 +01007399 " call Dret("s:NetrwMarkFileMove")
7400 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00007401
Luca Saccarolac363ca12024-12-19 20:16:18 +01007402 " ---------------------------------------------------------------------
7403 " s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7404 " using the hardcopy command. Local marked-file list only.
7405 fun! s:NetrwMarkFilePrint(islocal)
7406 " call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7407 let curbufnr= bufnr("%")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007408
Luca Saccarolac363ca12024-12-19 20:16:18 +01007409 " sanity check
7410 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7411 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7412 " call Dret("s:NetrwMarkFilePrint")
7413 return
7414 endif
7415 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7416 let curdir= s:NetrwGetCurdir(a:islocal)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007417
Luca Saccarolac363ca12024-12-19 20:16:18 +01007418 if exists("s:netrwmarkfilelist_{curbufnr}")
7419 let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7420 call s:NetrwUnmarkList(curbufnr,curdir)
7421 for fname in netrwmarkfilelist
7422 if a:islocal
7423 if g:netrw_keepdir
7424 let fname= s:ComposePath(curdir,fname)
7425 endif
7426 else
7427 let fname= curdir.fname
7428 endif
7429 1split
7430 " the autocmds will handle both local and remote files
7431 " call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7432 exe "sil NetrwKeepj e ".fnameescape(fname)
7433 " call Decho("hardcopy",'~'.expand("<slnum>"))
7434 hardcopy
7435 q
7436 endfor
7437 2match none
7438 endif
7439 " call Dret("s:NetrwMarkFilePrint")
7440 endfun
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007441
Luca Saccarolac363ca12024-12-19 20:16:18 +01007442 " ---------------------------------------------------------------------
7443 " s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7444 " files when given a regexp (for which a prompt is
7445 " issued) (matches to name of files).
7446 fun! s:NetrwMarkFileRegexp(islocal)
7447 " call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01007448
Luca Saccarolac363ca12024-12-19 20:16:18 +01007449 " get the regular expression
7450 call inputsave()
7451 let regexp= input("Enter regexp: ","","file")
7452 call inputrestore()
Bram Moolenaar446cb832008-06-24 21:56:24 +00007453
Luca Saccarolac363ca12024-12-19 20:16:18 +01007454 if a:islocal
7455 let curdir= s:NetrwGetCurdir(a:islocal)
7456 " call Decho("curdir<".fnameescape(curdir).">")
7457 " get the matching list of files using local glob()
7458 " call Decho("handle local regexp",'~'.expand("<slnum>"))
7459 let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7460 if v:version > 704 || (v:version == 704 && has("patch656"))
7461 let filelist= glob(s:ComposePath(dirname,regexp),0,1,1)
7462 else
7463 let files = glob(s:ComposePath(dirname,regexp),0,0)
7464 let filelist= split(files,"\n")
7465 endif
7466 " call Decho("files<".string(filelist).">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00007467
Luca Saccarolac363ca12024-12-19 20:16:18 +01007468 " mark the list of files
7469 for fname in filelist
7470 if fname =~ '^'.fnameescape(curdir)
7471 " call Decho("fname<".substitute(fname,'^'.fnameescape(curdir).'/','','').">",'~'.expand("<slnum>"))
7472 NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^'.fnameescape(curdir).'/','',''))
7473 else
7474 " call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7475 NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7476 endif
7477 endfor
Bram Moolenaar446cb832008-06-24 21:56:24 +00007478
Luca Saccarolac363ca12024-12-19 20:16:18 +01007479 else
7480 " call Decho("handle remote regexp",'~'.expand("<slnum>"))
7481
7482 " convert displayed listing into a filelist
7483 let eikeep = &ei
7484 let areg = @a
7485 sil NetrwKeepj %y a
7486 setl ei=all ma
7487 " call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7488 1split
7489 NetrwKeepj call s:NetrwEnew()
7490 NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
7491 sil NetrwKeepj norm! "ap
7492 NetrwKeepj 2
7493 let bannercnt= search('^" =====','W')
7494 exe "sil NetrwKeepj 1,".bannercnt."d"
7495 setl bt=nofile
7496 if g:netrw_liststyle == s:LONGLIST
7497 sil NetrwKeepj %s/\s\{2,}\S.*$//e
7498 call histdel("/",-1)
7499 elseif g:netrw_liststyle == s:WIDELIST
7500 sil NetrwKeepj %s/\s\{2,}/\r/ge
7501 call histdel("/",-1)
7502 elseif g:netrw_liststyle == s:TREELIST
7503 exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7504 sil! NetrwKeepj g/^ .*$/d
7505 call histdel("/",-1)
7506 call histdel("/",-1)
7507 endif
7508 " convert regexp into the more usual glob-style format
7509 let regexp= substitute(regexp,'\*','.*','g')
7510 " call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7511 exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7512 call histdel("/",-1)
7513 let filelist= getline(1,line("$"))
7514 q!
7515 for filename in filelist
7516 NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7517 endfor
7518 unlet filelist
7519 let @a = areg
7520 let &ei = eikeep
7521 endif
7522 echo " (use me to edit marked files)"
7523
7524 " call Dret("s:NetrwMarkFileRegexp")
7525 endfun
7526
7527 " ---------------------------------------------------------------------
7528 " s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7529 " Uses the local marked file list.
7530 fun! s:NetrwMarkFileSource(islocal)
7531 " call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7532 let curbufnr= bufnr("%")
7533
7534 " sanity check
7535 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7536 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7537 " call Dret("s:NetrwMarkFileSource")
7538 return
7539 endif
7540 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7541 let curdir= s:NetrwGetCurdir(a:islocal)
7542
7543 if exists("s:netrwmarkfilelist_{curbufnr}")
7544 let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7545 call s:NetrwUnmarkList(curbufnr,curdir)
7546 for fname in netrwmarkfilelist
7547 if a:islocal
7548 if g:netrw_keepdir
7549 let fname= s:ComposePath(curdir,fname)
7550 endif
7551 else
7552 let fname= curdir.fname
7553 endif
7554 " the autocmds will handle sourcing both local and remote files
7555 " call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7556 exe "so ".fnameescape(fname)
7557 endfor
7558 2match none
7559 endif
7560 " call Dret("s:NetrwMarkFileSource")
7561 endfun
7562
7563 " ---------------------------------------------------------------------
7564 " s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
7565 " Uses the global markfilelist
7566 fun! s:NetrwMarkFileTag(islocal)
7567 let svpos = winsaveview()
7568 let curdir = s:NetrwGetCurdir(a:islocal)
7569 let curbufnr = bufnr("%")
7570
7571 " sanity check
7572 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7573 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7574 return
7575 endif
7576
7577 if exists("s:netrwmarkfilelist")
7578 let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
7579 call s:NetrwUnmarkAll()
7580
7581 if a:islocal
7582
7583 call system(g:netrw_ctags." ".netrwmarkfilelist)
7584 if v:shell_error
7585 call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
7586 endif
7587
7588 else
7589 let cmd = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
7590 call netrw#Obtain(a:islocal,"tags")
7591 let curdir= b:netrw_curdir
7592 1split
7593 NetrwKeepj e tags
7594 let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
7595 exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
7596 call histdel("/",-1)
7597 wq!
7598 endif
7599 2match none
7600 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7601 call winrestview(svpos)
7602 endif
7603 endfun
7604
7605 " ---------------------------------------------------------------------
7606 " s:NetrwMarkFileTgt: (invoked by mt) This function sets up a marked file target {{{2
7607 " Sets up two variables,
7608 " s:netrwmftgt : holds the target directory
7609 " s:netrwmftgt_islocal : 0=target directory is remote
7610 " 1=target directory is local
7611 fun! s:NetrwMarkFileTgt(islocal)
7612 let svpos = winsaveview()
7613 let curdir = s:NetrwGetCurdir(a:islocal)
7614 let hadtgt = exists("s:netrwmftgt")
7615 if !exists("w:netrw_bannercnt")
7616 let w:netrw_bannercnt= b:netrw_bannercnt
7617 endif
7618
7619 " set up target
7620 if line(".") < w:netrw_bannercnt
7621 " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
7622 if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
7623 unlet s:netrwmftgt s:netrwmftgt_islocal
7624 if g:netrw_fastbrowse <= 1
7625 call s:LocalBrowseRefresh()
7626 endif
7627 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7628 call winrestview(svpos)
7629 return
7630 else
7631 let s:netrwmftgt= b:netrw_curdir
7632 endif
7633
7634 else
7635 " get word under cursor.
7636 " * If directory, use it for the target.
7637 " * If file, use b:netrw_curdir for the target
7638 let curword= s:NetrwGetWord()
7639 let tgtdir = s:ComposePath(curdir,curword)
7640 if a:islocal && isdirectory(s:NetrwFile(tgtdir))
7641 let s:netrwmftgt = tgtdir
7642 elseif !a:islocal && tgtdir =~ '/$'
7643 let s:netrwmftgt = tgtdir
7644 else
7645 let s:netrwmftgt = curdir
7646 endif
7647 endif
7648 if a:islocal
7649 " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
7650 let s:netrwmftgt= simplify(s:netrwmftgt)
7651 endif
7652 if g:netrw_cygwin
7653 let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
7654 let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
7655 endif
7656 let s:netrwmftgt_islocal= a:islocal
7657
7658 " need to do refresh so that the banner will be updated
7659 " s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
7660 if g:netrw_fastbrowse <= 1
7661 call s:LocalBrowseRefresh()
7662 endif
7663 " call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7664 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7665 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop,0))
7666 else
7667 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7668 endif
7669 call winrestview(svpos)
7670 if !hadtgt
7671 sil! NetrwKeepj norm! j
7672 endif
7673 endfun
7674
7675 " ---------------------------------------------------------------------
7676 " s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
7677 fun! s:NetrwGetCurdir(islocal)
7678 " call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
7679
7680 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7681 let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
7682 " call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
7683 elseif !exists("b:netrw_curdir")
7684 let b:netrw_curdir= getcwd()
7685 " call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
7686 endif
7687
7688 " call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>"))
7689 if b:netrw_curdir !~ '\<\a\{3,}://'
7690 let curdir= b:netrw_curdir
7691 " call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
7692 if g:netrw_keepdir == 0
7693 call s:NetrwLcd(curdir)
7694 endif
7695 endif
7696
7697 " call Dret("s:NetrwGetCurdir <".curdir.">")
7698 return b:netrw_curdir
7699 endfun
7700
7701 " ---------------------------------------------------------------------
7702 " s:NetrwOpenFile: query user for a filename and open it {{{2
7703 fun! s:NetrwOpenFile(islocal)
7704 " call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
7705 let ykeep= @@
7706 call inputsave()
7707 let fname= input("Enter filename: ")
7708 call inputrestore()
7709 " call Decho("(s:NetrwOpenFile) fname<".fname.">",'~'.expand("<slnum>"))
7710
7711 " determine if Lexplore is in use
7712 if exists("t:netrw_lexbufnr")
7713 " check if t:netrw_lexbufnr refers to a netrw window
7714 " call Decho("(s:netrwOpenFile) ..t:netrw_lexbufnr=".t:netrw_lexbufnr,'~'.expand("<slnum>"))
7715 let lexwinnr = bufwinnr(t:netrw_lexbufnr)
7716 if lexwinnr != -1 && exists("g:netrw_chgwin") && g:netrw_chgwin != -1
7717 " call Decho("(s:netrwOpenFile) ..Lexplore in use",'~'.expand("<slnum>"))
7718 exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
7719 exe "NetrwKeepj e ".fnameescape(fname)
7720 let @@= ykeep
7721 " call Dret("s:NetrwOpenFile : creating a file with Lexplore mode")
7722 endif
7723 endif
7724
7725 " Does the filename contain a path?
7726 if fname !~ '[/\\]'
7727 if exists("b:netrw_curdir")
7728 if exists("g:netrw_quiet")
7729 let netrw_quiet_keep = g:netrw_quiet
7730 endif
7731 let g:netrw_quiet = 1
7732 " save position for benefit of Rexplore
7733 let s:rexposn_{bufnr("%")}= winsaveview()
7734 " call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
7735 if b:netrw_curdir =~ '/$'
7736 exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
7737 else
7738 exe "e ".fnameescape(b:netrw_curdir."/".fname)
7739 endif
7740 if exists("netrw_quiet_keep")
7741 let g:netrw_quiet= netrw_quiet_keep
7742 else
7743 unlet g:netrw_quiet
7744 endif
7745 endif
7746 else
7747 exe "NetrwKeepj e ".fnameescape(fname)
7748 endif
7749 let @@= ykeep
7750 " call Dret("s:NetrwOpenFile")
7751 endfun
7752
7753 " ---------------------------------------------------------------------
7754 " netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
7755 " For the mapping to this function be made via
7756 " netrwPlugin, you'll need to have had
7757 " g:netrw_usetab set to non-zero.
7758 fun! netrw#Shrink()
7759 " call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
7760 let curwin = winnr()
7761 let wiwkeep = &wiw
7762 set wiw=1
7763
7764 if &ft == "netrw"
7765 if winwidth(0) > g:netrw_wiw
7766 let t:netrw_winwidth= winwidth(0)
7767 exe "vert resize ".g:netrw_wiw
7768 wincmd l
7769 if winnr() == curwin
7770 wincmd h
7771 endif
7772 " call Decho("vert resize 0",'~'.expand("<slnum>"))
7773 else
7774 exe "vert resize ".t:netrw_winwidth
7775 " call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7776 endif
7777
7778 elseif exists("t:netrw_lexbufnr")
7779 exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
7780 if winwidth(bufwinnr(t:netrw_lexbufnr)) > g:netrw_wiw
7781 let t:netrw_winwidth= winwidth(0)
7782 exe "vert resize ".g:netrw_wiw
7783 wincmd l
7784 if winnr() == curwin
7785 wincmd h
7786 endif
7787 " call Decho("vert resize 0",'~'.expand("<slnum>"))
7788 elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
7789 exe "vert resize ".t:netrw_winwidth
7790 " call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7791 else
7792 call netrw#Lexplore(0,0)
7793 endif
7794
7795 else
7796 call netrw#Lexplore(0,0)
7797 endif
7798 let wiw= wiwkeep
7799
7800 " call Dret("netrw#Shrink")
7801 endfun
7802
7803 " ---------------------------------------------------------------------
7804 " s:NetSortSequence: allows user to edit the sorting sequence {{{2
7805 fun! s:NetSortSequence(islocal)
7806 let ykeep= @@
7807 let svpos= winsaveview()
7808 call inputsave()
7809 let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
7810 call inputrestore()
7811
7812 " refresh the listing
7813 let g:netrw_sort_sequence= newsortseq
7814 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7815 NetrwKeepj call winrestview(svpos)
7816 let @@= ykeep
7817 endfun
7818
7819 " ---------------------------------------------------------------------
7820 " s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
7821 " User access provided by the <mF> mapping. (see :help netrw-mF)
7822 " Used by many MarkFile functions.
7823 fun! s:NetrwUnmarkList(curbufnr,curdir)
7824 " call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
7825
7826 " remove all files in local marked-file list from global list
7827 if exists("s:netrwmarkfilelist")
7828 for mfile in s:netrwmarkfilelist_{a:curbufnr}
7829 let dfile = s:ComposePath(a:curdir,mfile) " prepend directory to mfile
7830 let idx = index(s:netrwmarkfilelist,dfile) " get index in list of dfile
7831 call remove(s:netrwmarkfilelist,idx) " remove from global list
7832 endfor
7833 if s:netrwmarkfilelist == []
7834 unlet s:netrwmarkfilelist
7835 endif
7836
7837 " getting rid of the local marked-file lists is easy
7838 unlet s:netrwmarkfilelist_{a:curbufnr}
7839 endif
7840 if exists("s:netrwmarkfilemtch_{a:curbufnr}")
7841 unlet s:netrwmarkfilemtch_{a:curbufnr}
7842 endif
7843 2match none
7844 " call Dret("s:NetrwUnmarkList")
7845 endfun
7846
7847 " ---------------------------------------------------------------------
7848 " s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
7849 fun! s:NetrwUnmarkAll()
7850 " call Dfunc("s:NetrwUnmarkAll()")
7851 if exists("s:netrwmarkfilelist")
7852 unlet s:netrwmarkfilelist
7853 endif
7854 sil call s:NetrwUnmarkAll2()
7855 2match none
7856 " call Dret("s:NetrwUnmarkAll")
7857 endfun
7858
7859 " ---------------------------------------------------------------------
7860 " s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
7861 fun! s:NetrwUnmarkAll2()
7862 " call Dfunc("s:NetrwUnmarkAll2()")
7863 redir => netrwmarkfilelist_let
7864 let
7865 redir END
7866 let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n') " convert let string into a let list
7867 call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
7868 call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')") " remove what the entries are equal to
7869 for flist in netrwmarkfilelist_list
7870 let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
7871 unlet s:netrwmarkfilelist_{curbufnr}
7872 unlet s:netrwmarkfilemtch_{curbufnr}
Bram Moolenaar446cb832008-06-24 21:56:24 +00007873 endfor
Luca Saccarolac363ca12024-12-19 20:16:18 +01007874 " call Dret("s:NetrwUnmarkAll2")
7875 endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00007876
Luca Saccarolac363ca12024-12-19 20:16:18 +01007877 " ---------------------------------------------------------------------
7878 " s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
7879 "
7880 " Marked files are in two types of lists:
7881 " s:netrwmarkfilelist -- holds complete paths to all marked files
7882 " s:netrwmarkfilelist_# -- holds list of marked files in current-buffer's directory (#==bufnr())
7883 "
7884 " Marked files suitable for use with 2match are in:
7885 " s:netrwmarkfilemtch_# -- used with 2match to display marked files
7886 fun! s:NetrwUnMarkFile(islocal)
7887 let svpos = winsaveview()
7888 let curbufnr = bufnr("%")
Bram Moolenaar446cb832008-06-24 21:56:24 +00007889
Luca Saccarolac363ca12024-12-19 20:16:18 +01007890 " unmark marked file list
7891 " (although I expect s:NetrwUpload() to do it, I'm just making sure)
7892 if exists("s:netrwmarkfilelist")
7893 " " call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
7894 unlet s:netrwmarkfilelist
7895 endif
Bram Moolenaar15146672011-10-20 22:22:38 +02007896
Luca Saccarolac363ca12024-12-19 20:16:18 +01007897 let ibuf= 1
7898 while ibuf < bufnr("$")
7899 if exists("s:netrwmarkfilelist_".ibuf)
7900 unlet s:netrwmarkfilelist_{ibuf}
7901 unlet s:netrwmarkfilemtch_{ibuf}
7902 endif
7903 let ibuf = ibuf + 1
7904 endwhile
7905 2match none
Bram Moolenaarff034192013-04-24 18:51:19 +02007906
Luca Saccarolac363ca12024-12-19 20:16:18 +01007907 " call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7908 call winrestview(svpos)
7909 endfun
Bram Moolenaar15146672011-10-20 22:22:38 +02007910
Luca Saccarolac363ca12024-12-19 20:16:18 +01007911 " ---------------------------------------------------------------------
7912 " s:NetrwMenu: generates the menu for gvim and netrw {{{2
7913 fun! s:NetrwMenu(domenu)
7914
7915 if !exists("g:NetrwMenuPriority")
7916 let g:NetrwMenuPriority= 80
7917 endif
7918
7919 if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
7920 " call Dfunc("NetrwMenu(domenu=".a:domenu.")")
7921
7922 if !exists("s:netrw_menu_enabled") && a:domenu
7923 " call Decho("initialize menu",'~'.expand("<slnum>"))
7924 let s:netrw_menu_enabled= 1
7925 exe 'sil! menu '.g:NetrwMenuPriority.'.1 '.g:NetrwTopLvlMenu.'Help<tab><F1> <F1>'
7926 exe 'sil! menu '.g:NetrwMenuPriority.'.5 '.g:NetrwTopLvlMenu.'-Sep1- :'
7927 exe 'sil! menu '.g:NetrwMenuPriority.'.6 '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>- -'
7928 exe 'sil! menu '.g:NetrwMenuPriority.'.7 '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x x'
7929 if g:netrw_dirhistmax > 0
7930 exe 'sil! menu '.g:NetrwMenuPriority.'.8.1 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb mb'
7931 exe 'sil! menu '.g:NetrwMenuPriority.'.8.4 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u u'
7932 exe 'sil! menu '.g:NetrwMenuPriority.'.8.5 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U U'
7933 exe 'sil! menu '.g:NetrwMenuPriority.'.8.6 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb qb'
7934 else
7935 exe 'sil! menu '.g:NetrwMenuPriority.'.8 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History :echo "(disabled)"'."\<cr>"
7936 endif
7937 exe 'sil! menu '.g:NetrwMenuPriority.'.9.1 '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o o'
7938 exe 'sil! menu '.g:NetrwMenuPriority.'.9.2 '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v v'
7939 exe 'sil! menu '.g:NetrwMenuPriority.'.9.3 '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t t'
7940 exe 'sil! menu '.g:NetrwMenuPriority.'.9.4 '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p p'
7941 exe 'sil! menu '.g:NetrwMenuPriority.'.9.5 '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'." \<c-h>'"
7942 exe 'sil! menu '.g:NetrwMenuPriority.'.9.6 '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S S'
7943 exe 'sil! menu '.g:NetrwMenuPriority.'.9.7 '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh gh"
7944 exe 'sil! menu '.g:NetrwMenuPriority.'.9.8 '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l> \<c-l>"
7945 exe 'sil! menu '.g:NetrwMenuPriority.'.9.9 '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings '.":NetrwSettings\<cr>"
7946 exe 'sil! menu '.g:NetrwMenuPriority.'.10 '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D D'
7947 exe 'sil! menu '.g:NetrwMenuPriority.'.11.1 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>% %'
7948 exe 'sil! menu '.g:NetrwMenuPriority.'.11.1 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr> '."\<cr>"
7949 exe 'sil! menu '.g:NetrwMenuPriority.'.11.2 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p p'
7950 exe 'sil! menu '.g:NetrwMenuPriority.'.11.3 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P P'
7951 exe 'sil! menu '.g:NetrwMenuPriority.'.11.4 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o o'
7952 exe 'sil! menu '.g:NetrwMenuPriority.'.11.5 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t t'
7953 exe 'sil! menu '.g:NetrwMenuPriority.'.11.5 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v v'
7954 exe 'sil! menu '.g:NetrwMenuPriority.'.12.1 '.g:NetrwTopLvlMenu.'Explore.Directory\ Name :Explore '
7955 exe 'sil! menu '.g:NetrwMenuPriority.'.12.2 '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */ :Explore */'
7956 exe 'sil! menu '.g:NetrwMenuPriority.'.12.2 '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/ :Explore **/'
7957 exe 'sil! menu '.g:NetrwMenuPriority.'.12.3 '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *// :Explore *//'
7958 exe 'sil! menu '.g:NetrwMenuPriority.'.12.4 '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **// :Explore **//'
7959 exe 'sil! menu '.g:NetrwMenuPriority.'.12.4 '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore :Nexplore<cr>'
7960 exe 'sil! menu '.g:NetrwMenuPriority.'.12.4 '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore :Pexplore<cr>'
7961 exe 'sil! menu '.g:NetrwMenuPriority.'.13 '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d d'
7962 exe 'sil! menu '.g:NetrwMenuPriority.'.14.1 '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf mf'
7963 exe 'sil! menu '.g:NetrwMenuPriority.'.14.2 '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr mr'
7964 exe 'sil! menu '.g:NetrwMenuPriority.'.14.3 '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a a'
7965 exe 'sil! menu '.g:NetrwMenuPriority.'.14.4 '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc mc'
7966 exe 'sil! menu '.g:NetrwMenuPriority.'.14.5 '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D D'
7967 exe 'sil! menu '.g:NetrwMenuPriority.'.14.6 '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md md'
7968 exe 'sil! menu '.g:NetrwMenuPriority.'.14.7 '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me me'
7969 exe 'sil! menu '.g:NetrwMenuPriority.'.14.8 '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx mx'
7970 exe 'sil! menu '.g:NetrwMenuPriority.'.14.9 '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm mm'
7971 exe 'sil! menu '.g:NetrwMenuPriority.'.14.10 '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O O'
7972 exe 'sil! menu '.g:NetrwMenuPriority.'.14.11 '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp mp'
7973 exe 'sil! menu '.g:NetrwMenuPriority.'.14.12 '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R R'
7974 exe 'sil! menu '.g:NetrwMenuPriority.'.14.13 '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt mt'
7975 exe 'sil! menu '.g:NetrwMenuPriority.'.14.14 '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT mT'
7976 exe 'sil! menu '.g:NetrwMenuPriority.'.14.15 '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz mz'
7977 exe 'sil! menu '.g:NetrwMenuPriority.'.15 '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O O'
7978 exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i :let w:netrw_liststyle=0<cr><c-L>'
7979 exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i :let w:netrw_liststyle=1<cr><c-L>'
7980 exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i :let w:netrw_liststyle=2<cr><c-L>'
7981 exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i :let w:netrw_liststyle=3<cr><c-L>'
7982 exe 'sil! menu '.g:NetrwMenuPriority.'.16.2.1 '.g:NetrwTopLvlMenu.'Style.Normal-Hide-Show.Show\ All<tab>a :let g:netrw_hide=0<cr><c-L>'
7983 exe 'sil! menu '.g:NetrwMenuPriority.'.16.2.3 '.g:NetrwTopLvlMenu.'Style.Normal-Hide-Show.Normal<tab>a :let g:netrw_hide=1<cr><c-L>'
7984 exe 'sil! menu '.g:NetrwMenuPriority.'.16.2.2 '.g:NetrwTopLvlMenu.'Style.Normal-Hide-Show.Hidden\ Only<tab>a :let g:netrw_hide=2<cr><c-L>'
7985 exe 'sil! menu '.g:NetrwMenuPriority.'.16.3 '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r r"
7986 exe 'sil! menu '.g:NetrwMenuPriority.'.16.4.1 '.g:NetrwTopLvlMenu.'Style.Sorting\ Method.Name<tab>s :let g:netrw_sort_by="name"<cr><c-L>'
7987 exe 'sil! menu '.g:NetrwMenuPriority.'.16.4.2 '.g:NetrwTopLvlMenu.'Style.Sorting\ Method.Time<tab>s :let g:netrw_sort_by="time"<cr><c-L>'
7988 exe 'sil! menu '.g:NetrwMenuPriority.'.16.4.3 '.g:NetrwTopLvlMenu.'Style.Sorting\ Method.Size<tab>s :let g:netrw_sort_by="size"<cr><c-L>'
7989 exe 'sil! menu '.g:NetrwMenuPriority.'.16.4.3 '.g:NetrwTopLvlMenu.'Style.Sorting\ Method.Exten<tab>s :let g:netrw_sort_by="exten"<cr><c-L>'
7990 exe 'sil! menu '.g:NetrwMenuPriority.'.17 '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R R'
7991 exe 'sil! menu '.g:NetrwMenuPriority.'.18 '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c c'
7992 let s:netrw_menucnt= 28
7993 call s:NetrwBookmarkMenu() " provide some history! uses priorities 2,3, reserves 4, 8.2.x
7994 call s:NetrwTgtMenu() " let bookmarks and history be easy targets
7995
7996 elseif !a:domenu
7997 let s:netrwcnt = 0
7998 let curwin = winnr()
7999 windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8000 exe curwin."wincmd w"
8001
8002 if s:netrwcnt <= 1
8003 " call Decho("clear menus",'~'.expand("<slnum>"))
8004 exe 'sil! unmenu '.g:NetrwTopLvlMenu
8005 " call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8006 sil! unlet s:netrw_menu_enabled
8007 endif
8008 endif
8009 " call Dret("NetrwMenu")
8010 return
8011 endif
8012
8013 endfun
8014
8015 " ---------------------------------------------------------------------
8016 " s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8017 " Used by the O maps (as <SID>NetrwObtain())
8018 fun! s:NetrwObtain(islocal)
8019 " call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8020
8021 let ykeep= @@
8022 if exists("s:netrwmarkfilelist_{bufnr('%')}")
8023 let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8024 call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8025 call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
Bram Moolenaar15146672011-10-20 22:22:38 +02008026 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008027 call netrw#Obtain(a:islocal,s:NetrwGetWord())
Bram Moolenaar15146672011-10-20 22:22:38 +02008028 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02008029 let @@= ykeep
Bram Moolenaar89a9c152021-08-29 21:55:35 +02008030
Luca Saccarolac363ca12024-12-19 20:16:18 +01008031 " call Dret("NetrwObtain")
8032 endfun
8033
8034 " ---------------------------------------------------------------------
8035 " s:NetrwPrevWinOpen: open file/directory in previous window. {{{2
8036 " If there's only one window, then the window will first be split.
8037 " Returns:
8038 " choice = 0 : didn't have to choose
8039 " choice = 1 : saved modified file in window first
8040 " choice = 2 : didn't save modified file, opened window
8041 " choice = 3 : cancel open
8042 fun! s:NetrwPrevWinOpen(islocal)
8043 let ykeep= @@
8044 " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8045 let curdir = b:netrw_curdir
8046
8047 " get last window number and the word currently under the cursor
8048 let origwin = winnr()
8049 let lastwinnr = winnr("$")
8050 let curword = s:NetrwGetWord()
8051 let choice = 0
8052 let s:prevwinopen= 1 " lets s:NetrwTreeDir() know that NetrwPrevWinOpen called it (s:NetrwTreeDir() will unlet s:prevwinopen)
8053 let s:treedir = s:NetrwTreeDir(a:islocal)
8054 let curdir = s:treedir
8055
8056 let didsplit = 0
8057 if lastwinnr == 1
8058 " if only one window, open a new one first
8059 " g:netrw_preview=0: preview window shown in a horizontally split window
8060 " g:netrw_preview=1: preview window shown in a vertically split window
8061 if g:netrw_preview
8062 " vertically split preview window
8063 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8064 exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8065 else
8066 " horizontally split preview window
8067 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8068 exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8069 endif
8070 let didsplit = 1
8071
Bram Moolenaarc236c162008-07-13 17:41:49 +00008072 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008073 NetrwKeepj call s:SaveBufVars()
8074 let eikeep= &ei
8075 setl ei=all
8076 wincmd p
Bram Moolenaarc236c162008-07-13 17:41:49 +00008077
Luca Saccarolac363ca12024-12-19 20:16:18 +01008078 if exists("s:lexplore_win") && s:lexplore_win == winnr()
8079 " whoops -- user trying to open file in the Lexplore window.
8080 " Use Lexplore's opening-file window instead.
8081 " exe g:netrw_chgwin."wincmd w"
8082 wincmd p
8083 call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008084 endif
8085
Luca Saccarolac363ca12024-12-19 20:16:18 +01008086 " prevwinnr: the window number of the "prev" window
8087 " prevbufnr: the buffer number of the buffer in the "prev" window
8088 " bnrcnt : the qty of windows open on the "prev" buffer
8089 let prevwinnr = winnr()
8090 let prevbufnr = bufnr("%")
8091 let prevbufname = bufname("%")
8092 let prevmod = &mod
8093 let bnrcnt = 0
8094 NetrwKeepj call s:RestoreBufVars()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008095
Luca Saccarolac363ca12024-12-19 20:16:18 +01008096 " if the previous window's buffer has been changed (ie. its modified flag is set),
8097 " and it doesn't appear in any other extant window, then ask the
8098 " user if s/he wants to abandon modifications therein.
8099 if prevmod
8100 windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
8101 exe prevwinnr."wincmd w"
8102
8103 if bnrcnt == 1 && &hidden == 0
8104 " only one copy of the modified buffer in a window, and
8105 " hidden not set, so overwriting will lose the modified file. Ask first...
8106 let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8107 let &ei= eikeep
8108
8109 if choice == 1
8110 " Yes -- write file & then browse
8111 let v:errmsg= ""
8112 sil w
8113 if v:errmsg != ""
8114 call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8115 exe origwin."wincmd w"
8116 let &ei = eikeep
8117 let @@ = ykeep
8118 return choice
8119 endif
8120
8121 elseif choice == 2
8122 " No -- don't worry about changed file, just browse anyway
8123 echomsg "**note** changes to ".prevbufname." abandoned"
8124
8125 else
8126 " Cancel -- don't do this
8127 exe origwin."wincmd w"
8128 let &ei= eikeep
8129 let @@ = ykeep
8130 return choice
8131 endif
8132 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008133 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008134 let &ei= eikeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00008135 endif
8136
8137 " restore b:netrw_curdir (window split/enew may have lost it)
8138 let b:netrw_curdir= curdir
8139 if a:islocal < 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01008140 if a:islocal
8141 call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword,0))
8142 else
8143 call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword,0))
8144 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008145 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01008146 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00008147 return choice
8148endfun
8149
8150" ---------------------------------------------------------------------
8151" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8152" Always assumed to be local -> remote
8153" call s:NetrwUpload(filename, target)
8154" call s:NetrwUpload(filename, target, fromdirectory)
8155fun! s:NetrwUpload(fname,tgt,...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01008156 " call Dfunc("s:NetrwUpload(fname<".((type(a:fname) == 1)? a:fname : string(a:fname))."> tgt<".a:tgt.">) a:0=".a:0)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008157
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008158 if a:tgt =~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008159 let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008160 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008161 let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008162 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008163 " call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008164
8165 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01008166 let fromdir= a:1
Bram Moolenaar446cb832008-06-24 21:56:24 +00008167 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008168 let fromdir= getcwd()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008169 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008170 " call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008171
8172 if type(a:fname) == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01008173 " handle uploading a single file using NetWrite
8174 " call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8175 1split
8176 " call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8177 exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8178 " call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8179 if a:tgt =~ '/$'
8180 let wfname= substitute(a:fname,'^.*/','','')
8181 " call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8182 exe "w! ".fnameescape(a:tgt.wfname)
8183 else
8184 " call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8185 exe "w ".fnameescape(a:tgt)
8186 " call Decho("done writing local->remote",'~'.expand("<slnum>"))
8187 endif
8188 q!
Bram Moolenaar446cb832008-06-24 21:56:24 +00008189
8190 elseif type(a:fname) == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01008191 " handle uploading a list of files via scp
8192 " call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8193 let curdir= getcwd()
8194 if a:tgt =~ '^scp:'
8195 if s:NetrwLcd(fromdir)
8196 " call Dret("s:NetrwUpload : lcd failure")
8197 return
Bram Moolenaar5b435d62012-04-05 17:33:26 +02008198 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008199 let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8200 let args = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8201 if exists("g:netrw_port") && g:netrw_port != ""
8202 let useport= " ".g:netrw_scpport." ".g:netrw_port
8203 else
8204 let useport= ""
8205 endif
8206 let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8207 let tgt = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8208 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8209 if s:NetrwLcd(curdir)
8210 " call Dret("s:NetrwUpload : lcd failure")
8211 return
8212 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008213
Luca Saccarolac363ca12024-12-19 20:16:18 +01008214 elseif a:tgt =~ '^ftp:'
8215 call s:NetrwMethod(a:tgt)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008216
Luca Saccarolac363ca12024-12-19 20:16:18 +01008217 if b:netrw_method == 2
8218 " handle uploading a list of files via ftp+.netrc
8219 let netrw_fname = b:netrw_fname
8220 sil NetrwKeepj new
8221 " call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008222
Luca Saccarolac363ca12024-12-19 20:16:18 +01008223 NetrwKeepj put =g:netrw_ftpmode
8224 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008225
Luca Saccarolac363ca12024-12-19 20:16:18 +01008226 if exists("g:netrw_ftpextracmd")
8227 NetrwKeepj put =g:netrw_ftpextracmd
8228 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8229 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008230
Luca Saccarolac363ca12024-12-19 20:16:18 +01008231 NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8232 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8233
8234 if tgtdir == ""
8235 let tgtdir= '/'
8236 endif
8237 NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8238 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8239
8240 for fname in a:fname
8241 NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8242 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8243 endfor
8244
8245 if exists("g:netrw_port") && g:netrw_port != ""
8246 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8247 else
8248 " call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8249 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8250 endif
8251 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8252 sil NetrwKeepj g/Local directory now/d
8253 call histdel("/",-1)
8254 if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8255 call netrw#ErrorMsg(s:ERROR,getline(1),14)
8256 else
8257 bw!|q
8258 endif
8259
8260 elseif b:netrw_method == 3
8261 " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8262 let netrw_fname= b:netrw_fname
8263 NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8264 let tmpbufnr= bufnr("%")
8265 setl ff=unix
8266
8267 if exists("g:netrw_port") && g:netrw_port != ""
8268 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
8269 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8270 else
8271 NetrwKeepj put ='open '.g:netrw_machine
8272 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8273 endif
8274
8275 if exists("g:netrw_uid") && g:netrw_uid != ""
8276 if exists("g:netrw_ftp") && g:netrw_ftp == 1
8277 NetrwKeepj put =g:netrw_uid
8278 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8279 if exists("s:netrw_passwd")
8280 NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8281 endif
8282 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8283 elseif exists("s:netrw_passwd")
8284 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8285 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8286 endif
8287 endif
8288
8289 NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8290 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8291
8292 if exists("b:netrw_fname") && b:netrw_fname != ""
8293 NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8294 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8295 endif
8296
8297 if exists("g:netrw_ftpextracmd")
8298 NetrwKeepj put =g:netrw_ftpextracmd
8299 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8300 endif
8301
8302 for fname in a:fname
8303 NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8304 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8305 endfor
8306
8307 " perform ftp:
8308 " -i : turns off interactive prompting from ftp
8309 " -n unix : DON'T use <.netrc>, even though it exists
8310 " -n win32: quit being obnoxious about password
8311 NetrwKeepj norm! 1G"_dd
8312 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8313 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8314 sil NetrwKeepj g/Local directory now/d
8315 call histdel("/",-1)
8316 if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8317 let debugkeep= &debug
8318 setl debug=msg
8319 call netrw#ErrorMsg(s:ERROR,getline(1),15)
8320 let &debug = debugkeep
8321 let mod = 1
8322 else
8323 bw!|q
8324 endif
8325 elseif !exists("b:netrw_method") || b:netrw_method < 0
8326 " call Dret("s:#NetrwUpload : unsupported method")
8327 return
8328 endif
8329 else
8330 call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008331 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008332 endif
8333
Luca Saccarolac363ca12024-12-19 20:16:18 +01008334 " call Dret("s:NetrwUpload")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008335endfun
8336
8337" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02008338" s:NetrwPreview: supports netrw's "p" map {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00008339fun! s:NetrwPreview(path) range
Luca Saccarolac363ca12024-12-19 20:16:18 +01008340 " call Dfunc("NetrwPreview(path<".a:path.">)")
8341 " call Decho("g:netrw_alto =".(exists("g:netrw_alto")? g:netrw_alto : 'n/a'),'~'.expand("<slnum>"))
8342 " call Decho("g:netrw_preview=".(exists("g:netrw_preview")? g:netrw_preview : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +01008343 let ykeep= @@
Bram Moolenaar85850f32019-07-19 22:05:51 +02008344 NetrwKeepj call s:NetrwOptionsSave("s:")
8345 if a:path !~ '^\*\{1,2}/' && a:path !~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008346 NetrwKeepj call s:NetrwOptionsSafe(1)
Bram Moolenaar85850f32019-07-19 22:05:51 +02008347 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008348 NetrwKeepj call s:NetrwOptionsSafe(0)
Bram Moolenaar85850f32019-07-19 22:05:51 +02008349 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008350 if has("quickfix")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008351 " call Decho("has quickfix",'~'.expand("<slnum>"))
8352 if !isdirectory(s:NetrwFile(a:path))
8353 " call Decho("good; not previewing a directory",'~'.expand("<slnum>"))
8354 if g:netrw_preview
8355 " vertical split
8356 let pvhkeep = &pvh
8357 let winsz = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8358 let &pvh = winwidth(0) - winsz
8359 " call Decho("g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily) g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8360 else
8361 " horizontal split
8362 let pvhkeep = &pvh
8363 let winsz = (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8364 let &pvh = winheight(0) - winsz
8365 " call Decho("!g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily) g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8366 endif
8367 " g:netrw_preview g:netrw_alto
8368 " 1 : vert 1: top -- preview window is vertically split off and on the left
8369 " 1 : vert 0: bot -- preview window is vertically split off and on the right
8370 " 0 : 1: top -- preview window is horizontally split off and on the top
8371 " 0 : 0: bot -- preview window is horizontally split off and on the bottom
8372 "
8373 " Note that the file being previewed is already known to not be a directory, hence we can avoid doing a LocalBrowseCheck() check via
8374 " the BufEnter event set up in netrwPlugin.vim
8375 " call Decho("exe ".(g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path),'~'.expand("<slnum>"))
8376 let eikeep = &ei
8377 set ei=BufEnter
8378 exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8379 let &ei= eikeep
8380 " call Decho("winnr($)=".winnr("$"),'~'.expand("<slnum>"))
8381 if exists("pvhkeep")
8382 let &pvh= pvhkeep
8383 endif
8384 elseif !exists("g:netrw_quiet")
8385 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
Bram Moolenaar00a927d2010-05-14 23:24:24 +02008386 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008387 elseif !exists("g:netrw_quiet")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008388 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, to preview your vim needs the quickfix feature compiled in",39)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008389 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02008390 NetrwKeepj call s:NetrwOptionsRestore("s:")
Bram Moolenaar97d62492012-11-15 21:28:22 +01008391 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01008392 " call Dret("NetrwPreview")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008393endfun
8394
8395" ---------------------------------------------------------------------
8396" s:NetrwRefresh: {{{2
8397fun! s:NetrwRefresh(islocal,dirname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01008398 " call Dfunc("s:NetrwRefresh(islocal<".a:islocal.">,dirname=".a:dirname.") g:netrw_hide=".g:netrw_hide." g:netrw_sort_direction=".g:netrw_sort_direction)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008399 " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
Bram Moolenaarff034192013-04-24 18:51:19 +02008400 setl ma noro
Luca Saccarolac363ca12024-12-19 20:16:18 +01008401 " call Decho("setl ma noro",'~'.expand("<slnum>"))
8402 " call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +01008403 let ykeep = @@
Bram Moolenaar85850f32019-07-19 22:05:51 +02008404 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01008405 if !exists("w:netrw_treetop")
8406 if exists("b:netrw_curdir")
8407 let w:netrw_treetop= b:netrw_curdir
8408 else
8409 let w:netrw_treetop= getcwd()
8410 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02008411 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008412 NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
Bram Moolenaar85850f32019-07-19 22:05:51 +02008413 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02008414
8415 " save the cursor position before refresh.
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008416 let screenposn = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +01008417 " call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008418
Luca Saccarolac363ca12024-12-19 20:16:18 +01008419 " call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8420 " call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008421 sil! NetrwKeepj %d _
Bram Moolenaar446cb832008-06-24 21:56:24 +00008422 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01008423 NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008424 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008425 NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008426 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02008427
8428 " restore position
Luca Saccarolac363ca12024-12-19 20:16:18 +01008429 " call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008430 NetrwKeepj call winrestview(screenposn)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008431
8432 " restore file marks
Bram Moolenaar85850f32019-07-19 22:05:51 +02008433 if has("syntax") && exists("g:syntax_on") && g:syntax_on
Luca Saccarolac363ca12024-12-19 20:16:18 +01008434 if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8435 " " call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8436 exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8437 else
8438 " " call Decho("2match none (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8439 2match none
8440 endif
8441 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008442
Luca Saccarolac363ca12024-12-19 20:16:18 +01008443 " restore
Bram Moolenaar97d62492012-11-15 21:28:22 +01008444 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01008445 " call Dret("s:NetrwRefresh")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008446endfun
8447
8448" ---------------------------------------------------------------------
8449" s:NetrwRefreshDir: refreshes a directory by name {{{2
8450" Called by NetrwMarkFileCopy()
Bram Moolenaara6878372014-03-22 21:02:50 +01008451" Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008452fun! s:NetrwRefreshDir(islocal,dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008453 if g:netrw_fastbrowse == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01008454 " slowest mode (keep buffers refreshed, local or remote)
8455 let tgtwin= bufwinnr(a:dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008456
Luca Saccarolac363ca12024-12-19 20:16:18 +01008457 if tgtwin > 0
8458 " tgtwin is being displayed, so refresh it
8459 let curwin= winnr()
8460 exe tgtwin."wincmd w"
8461 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
8462 exe curwin."wincmd w"
Bram Moolenaar446cb832008-06-24 21:56:24 +00008463
Luca Saccarolac363ca12024-12-19 20:16:18 +01008464 elseif bufnr(a:dirname) > 0
8465 let bn= bufnr(a:dirname)
8466 exe "sil keepj bd ".bn
8467 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008468
8469 elseif g:netrw_fastbrowse <= 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01008470 NetrwKeepj call s:LocalBrowseRefresh()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008471 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008472endfun
8473
8474" ---------------------------------------------------------------------
Bram Moolenaar13600302014-05-22 18:26:40 +02008475" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8476" window number to do its editing in.
8477" Supports [count]C where the count, if present, is used to specify
8478" a window to use for editing via the <cr> mapping.
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008479fun! s:NetrwSetChgwin(...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01008480 " call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008481 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01008482 " call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8483 if a:1 == "" " :NetrwC win#
8484 let g:netrw_chgwin= winnr()
8485 else " :NetrwC
8486 let g:netrw_chgwin= a:1
8487 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008488 elseif v:count > 0 " [count]C
Luca Saccarolac363ca12024-12-19 20:16:18 +01008489 let g:netrw_chgwin= v:count
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008490 else " C
Luca Saccarolac363ca12024-12-19 20:16:18 +01008491 let g:netrw_chgwin= winnr()
Bram Moolenaar13600302014-05-22 18:26:40 +02008492 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008493 echo "editing window now set to window#".g:netrw_chgwin
Luca Saccarolac363ca12024-12-19 20:16:18 +01008494 " call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
Bram Moolenaar13600302014-05-22 18:26:40 +02008495endfun
8496
8497" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00008498" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8499" What this function does is to compute a priority for the patterns
8500" in the g:netrw_sort_sequence. It applies a substitute to any
8501" "files" that satisfy each pattern, putting the priority / in
8502" front. An "*" pattern handles the default priority.
8503fun! s:NetrwSetSort()
Luca Saccarolac363ca12024-12-19 20:16:18 +01008504 " call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
Bram Moolenaar97d62492012-11-15 21:28:22 +01008505 let ykeep= @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00008506 if w:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01008507 let seqlist = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008508 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008509 let seqlist = g:netrw_sort_sequence
Bram Moolenaar446cb832008-06-24 21:56:24 +00008510 endif
8511 " sanity check -- insure that * appears somewhere
8512 if seqlist == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008513 let seqlist= '*'
Bram Moolenaar446cb832008-06-24 21:56:24 +00008514 elseif seqlist !~ '\*'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008515 let seqlist= seqlist.',*'
Bram Moolenaar446cb832008-06-24 21:56:24 +00008516 endif
8517 let priority = 1
8518 while seqlist != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008519 if seqlist =~ ','
8520 let seq = substitute(seqlist,',.*$','','e')
8521 let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
8522 else
8523 let seq = seqlist
8524 let seqlist = ""
8525 endif
8526 if priority < 10
8527 let spriority= "00".priority.g:netrw_sepchr
8528 elseif priority < 100
8529 let spriority= "0".priority.g:netrw_sepchr
8530 else
8531 let spriority= priority.g:netrw_sepchr
8532 endif
8533 " call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008534
Luca Saccarolac363ca12024-12-19 20:16:18 +01008535 " sanity check
8536 if w:netrw_bannercnt > line("$")
8537 " apparently no files were left after a Hiding pattern was used
8538 " call Dret("SetSort : no files left after hiding")
8539 return
8540 endif
8541 if seq == '*'
8542 let starpriority= spriority
8543 else
8544 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
8545 call histdel("/",-1)
8546 " sometimes multiple sorting patterns will match the same file or directory.
8547 " The following substitute is intended to remove the excess matches.
8548 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
8549 NetrwKeepj call histdel("/",-1)
8550 endif
8551 let priority = priority + 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00008552 endwhile
8553 if exists("starpriority")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008554 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
8555 NetrwKeepj call histdel("/",-1)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008556 endif
8557
8558 " Following line associated with priority -- items that satisfy a priority
8559 " pattern get prefixed by ###/ which permits easy sorting by priority.
8560 " Sometimes files can satisfy multiple priority patterns -- only the latest
8561 " priority pattern needs to be retained. So, at this point, these excess
8562 " priority prefixes need to be removed, but not directories that happen to
8563 " be just digits themselves.
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008564 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
8565 NetrwKeepj call histdel("/",-1)
Bram Moolenaar97d62492012-11-15 21:28:22 +01008566 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00008567
Luca Saccarolac363ca12024-12-19 20:16:18 +01008568 " call Dret("SetSort")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008569endfun
8570
Bram Moolenaarff034192013-04-24 18:51:19 +02008571" ---------------------------------------------------------------------
8572" s:NetrwSetTgt: sets the target to the specified choice index {{{2
8573" Implements [count]Tb (bookhist<b>)
8574" [count]Th (bookhist<h>)
8575" See :help netrw-qb for how to make the choice.
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008576fun! s:NetrwSetTgt(islocal,bookhist,choice)
Luca Saccarolac363ca12024-12-19 20:16:18 +01008577 " call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
Bram Moolenaarff034192013-04-24 18:51:19 +02008578
8579 if a:bookhist == 'b'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008580 " supports choosing a bookmark as a target using a qb-generated list
8581 let choice= a:choice - 1
8582 if exists("g:netrw_bookmarklist[".choice."]")
8583 call netrw#MakeTgt(g:netrw_bookmarklist[choice])
8584 else
8585 echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
8586 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008587
8588 elseif a:bookhist == 'h'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008589 " supports choosing a history stack entry as a target using a qb-generated list
8590 let choice= (a:choice % g:netrw_dirhistmax) + 1
8591 if exists("g:netrw_dirhist_".choice)
8592 let histentry = g:netrw_dirhist_{choice}
8593 call netrw#MakeTgt(histentry)
8594 else
8595 echomsg "Sorry, history#".a:choice." not available!"
8596 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008597 endif
8598
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008599 " refresh the display
8600 if !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008601 let b:netrw_curdir= getcwd()
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008602 endif
8603 call s:NetrwRefresh(a:islocal,b:netrw_curdir)
8604
Luca Saccarolac363ca12024-12-19 20:16:18 +01008605 " call Dret("s:NetrwSetTgt")
Bram Moolenaarff034192013-04-24 18:51:19 +02008606endfun
8607
Bram Moolenaar446cb832008-06-24 21:56:24 +00008608" =====================================================================
Bram Moolenaar85850f32019-07-19 22:05:51 +02008609" s:NetrwSortStyle: change sorting style (name - time - size - exten) and refresh display {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00008610fun! s:NetrwSortStyle(islocal)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008611 NetrwKeepj call s:NetrwSaveWordPosn()
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008612 let svpos= winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008613
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02008614 let g:netrw_sort_by= (g:netrw_sort_by =~# '^n')? 'time' : (g:netrw_sort_by =~# '^t')? 'size' : (g:netrw_sort_by =~# '^siz')? 'exten' : 'name'
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008615 NetrwKeepj norm! 0
Tom Benham64a536d2024-11-07 21:15:03 +01008616 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008617 NetrwKeepj call winrestview(svpos)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008618endfun
8619
8620" ---------------------------------------------------------------------
8621" s:NetrwSplit: mode {{{2
8622" =0 : net and o
8623" =1 : net and t
8624" =2 : net and v
8625" =3 : local and o
8626" =4 : local and t
8627" =5 : local and v
8628fun! s:NetrwSplit(mode)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008629
Bram Moolenaar97d62492012-11-15 21:28:22 +01008630 let ykeep= @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00008631 call s:SaveWinVars()
8632
8633 if a:mode == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01008634 " remote and o
8635 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8636 if winsz == 0|let winsz= ""|endif
8637 exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8638 let s:didsplit= 1
8639 NetrwKeepj call s:RestoreWinVars()
8640 NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1))
8641 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008642
8643 elseif a:mode == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01008644 " remote and t
8645 let newdir = s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1)
8646 tabnew
8647 let s:didsplit= 1
8648 NetrwKeepj call s:RestoreWinVars()
8649 NetrwKeepj call s:NetrwBrowse(0,newdir)
8650 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008651
8652 elseif a:mode == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01008653 " remote and v
8654 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8655 if winsz == 0|let winsz= ""|endif
8656 exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8657 let s:didsplit= 1
8658 NetrwKeepj call s:RestoreWinVars()
8659 NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1))
8660 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008661
8662 elseif a:mode == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01008663 " local and o
8664 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8665 if winsz == 0|let winsz= ""|endif
8666 exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8667 let s:didsplit= 1
8668 NetrwKeepj call s:RestoreWinVars()
8669 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord(),1))
8670 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008671
8672 elseif a:mode == 4
Luca Saccarolac363ca12024-12-19 20:16:18 +01008673 " local and t
8674 let cursorword = s:NetrwGetWord()
8675 let eikeep = &ei
8676 let netrw_winnr = winnr()
8677 let netrw_line = line(".")
8678 let netrw_col = virtcol(".")
8679 NetrwKeepj norm! H0
8680 let netrw_hline = line(".")
Bram Moolenaara6878372014-03-22 21:02:50 +01008681 setl ei=all
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008682 exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8683 exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
Luca Saccarolac363ca12024-12-19 20:16:18 +01008684 let &ei = eikeep
8685 let netrw_curdir = s:NetrwTreeDir(0)
8686 tabnew
8687 let b:netrw_curdir = netrw_curdir
8688 let s:didsplit = 1
8689 NetrwKeepj call s:RestoreWinVars()
8690 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword,0))
8691 if &ft == "netrw"
8692 setl ei=all
8693 exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8694 exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8695 let &ei= eikeep
8696 endif
8697 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008698
8699 elseif a:mode == 5
Luca Saccarolac363ca12024-12-19 20:16:18 +01008700 " local and v
8701 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8702 if winsz == 0|let winsz= ""|endif
8703 exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8704 let s:didsplit= 1
8705 NetrwKeepj call s:RestoreWinVars()
8706 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord(),1))
8707 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008708
8709 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008710 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008711 endif
8712
Bram Moolenaar97d62492012-11-15 21:28:22 +01008713 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00008714endfun
8715
8716" ---------------------------------------------------------------------
Bram Moolenaarff034192013-04-24 18:51:19 +02008717" s:NetrwTgtMenu: {{{2
8718fun! s:NetrwTgtMenu()
8719 if !exists("s:netrw_menucnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008720 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00008721 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008722 " call Dfunc("s:NetrwTgtMenu()")
Bram Moolenaarff034192013-04-24 18:51:19 +02008723
8724 " the following test assures that gvim is running, has menus available, and has menus enabled.
8725 if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
Luca Saccarolac363ca12024-12-19 20:16:18 +01008726 if exists("g:NetrwTopLvlMenu")
8727 " call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
8728 exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
8729 endif
8730 if !exists("s:netrw_initbookhist")
8731 call s:NetrwBookHistRead()
8732 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008733
Luca Saccarolac363ca12024-12-19 20:16:18 +01008734 " try to cull duplicate entries
8735 let tgtdict={}
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008736
Luca Saccarolac363ca12024-12-19 20:16:18 +01008737 " target bookmarked places
8738 if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
8739 " call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
8740 let cnt= 1
8741 for bmd in g:netrw_bookmarklist
8742 if has_key(tgtdict,bmd)
8743 let cnt= cnt + 1
8744 continue
8745 endif
8746 let tgtdict[bmd]= cnt
8747 let ebmd= escape(bmd,g:netrw_menu_escape)
8748 " show bookmarks for goto menu
8749 " call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
8750 exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd." :call netrw#MakeTgt('".bmd."')\<cr>"
8751 let cnt= cnt + 1
8752 endfor
8753 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008754
Luca Saccarolac363ca12024-12-19 20:16:18 +01008755 " target directory browsing history
8756 if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
8757 " call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
8758 let histcnt = 1
8759 while histcnt <= g:netrw_dirhistmax
8760 let priority = g:netrw_dirhistcnt + histcnt
8761 if exists("g:netrw_dirhist_{histcnt}")
8762 let histentry = g:netrw_dirhist_{histcnt}
8763 if has_key(tgtdict,histentry)
8764 let histcnt = histcnt + 1
8765 continue
8766 endif
8767 let tgtdict[histentry] = histcnt
8768 let ehistentry = escape(histentry,g:netrw_menu_escape)
8769 " call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
8770 exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry." :call netrw#MakeTgt('".histentry."')\<cr>"
8771 endif
8772 let histcnt = histcnt + 1
8773 endwhile
8774 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008775 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008776 " call Dret("s:NetrwTgtMenu")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008777endfun
8778
8779" ---------------------------------------------------------------------
8780" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
8781" (full path directory with trailing slash returned)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008782fun! s:NetrwTreeDir(islocal)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008783
Bram Moolenaar89a9c152021-08-29 21:55:35 +02008784 if exists("s:treedir") && exists("s:prevwinopen")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008785 " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
8786 let treedir= s:treedir
8787 unlet s:treedir
8788 unlet s:prevwinopen
8789 return treedir
Bram Moolenaar8d043172014-01-23 14:24:41 +01008790 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02008791 if exists("s:prevwinopen")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008792 unlet s:prevwinopen
Bram Moolenaar89a9c152021-08-29 21:55:35 +02008793 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008794
Bram Moolenaar8d043172014-01-23 14:24:41 +01008795 if !exists("b:netrw_curdir") || b:netrw_curdir == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008796 let b:netrw_curdir= getcwd()
Bram Moolenaar8d043172014-01-23 14:24:41 +01008797 endif
8798 let treedir = b:netrw_curdir
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008799 let s:treecurpos= winsaveview()
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008800
8801 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Bram Moolenaar5c736222010-01-06 20:54:52 +01008802
Luca Saccarolac363ca12024-12-19 20:16:18 +01008803 " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
8804 let curline= substitute(getline('.'),"\t -->.*$",'','')
8805 if curline =~ '/$'
8806 let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
8807 elseif curline =~ '@$'
8808 let potentialdir= resolve(s:NetrwTreePath(w:netrw_treetop))
8809 else
8810 let treedir= ""
8811 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008812
Luca Saccarolac363ca12024-12-19 20:16:18 +01008813 " detect user attempting to close treeroot
8814 if curline !~ '^'.s:treedepthstring && getline('.') != '..'
8815 " now force a refresh
8816 sil! NetrwKeepj %d _
8817 return b:netrw_curdir
8818 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008819
Luca Saccarolac363ca12024-12-19 20:16:18 +01008820 " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
8821 " if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
8822 " let newdir = w:netrw_treetop.'/'.potentialdir
Christian Brabandt56b7da32024-02-29 17:48:14 +01008823 if a:islocal && curline =~ '@$'
8824 if isdirectory(s:NetrwFile(potentialdir))
Tom Benham64a536d2024-11-07 21:15:03 +01008825 let treedir = potentialdir
Christian Brabandt56b7da32024-02-29 17:48:14 +01008826 let w:netrw_treetop = treedir
8827 endif
8828 else
8829 let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
8830 let treedir = s:NetrwTreePath(w:netrw_treetop)
8831 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008832 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +01008833
8834 " sanity maintenance: keep those //s away...
Bram Moolenaar446cb832008-06-24 21:56:24 +00008835 let treedir= substitute(treedir,'//$','/','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008836 return treedir
8837endfun
8838
8839" ---------------------------------------------------------------------
8840" s:NetrwTreeDisplay: recursive tree display {{{2
8841fun! s:NetrwTreeDisplay(dir,depth)
Tom Benham64a536d2024-11-07 21:15:03 +01008842 " ensure that there are no folds
Bram Moolenaarff034192013-04-24 18:51:19 +02008843 setl nofen
Bram Moolenaar446cb832008-06-24 21:56:24 +00008844
8845 " install ../ and shortdir
8846 if a:depth == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008847 call setline(line("$")+1,'../')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008848 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008849 if a:dir =~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008850 if a:dir == w:netrw_treetop
8851 let shortdir= a:dir
8852 else
8853 let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
8854 endif
8855 call setline(line("$")+1,a:depth.shortdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008856 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008857 let shortdir= substitute(a:dir,'^.*/','','e')
8858 call setline(line("$")+1,a:depth.shortdir.'/')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008859 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008860 " append a / to dir if its missing one
8861 let dir= a:dir
Bram Moolenaar446cb832008-06-24 21:56:24 +00008862
8863 " display subtrees (if any)
Bram Moolenaar8d043172014-01-23 14:24:41 +01008864 let depth= s:treedepthstring.a:depth
Bram Moolenaar446cb832008-06-24 21:56:24 +00008865
Bram Moolenaar85850f32019-07-19 22:05:51 +02008866 " implement g:netrw_hide for tree listings (uses g:netrw_list_hide)
8867 if g:netrw_hide == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01008868 " hide given patterns
8869 let listhide= split(g:netrw_list_hide,',')
8870 for pat in listhide
8871 call filter(w:netrw_treedict[dir],'v:val !~ "'.escape(pat,'\\').'"')
8872 endfor
Bram Moolenaar85850f32019-07-19 22:05:51 +02008873
8874 elseif g:netrw_hide == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01008875 " show given patterns (only)
8876 let listhide= split(g:netrw_list_hide,',')
8877 let entries=[]
8878 for entry in w:netrw_treedict[dir]
8879 for pat in listhide
8880 if entry =~ pat
8881 call add(entries,entry)
8882 break
8883 endif
8884 endfor
Bram Moolenaar85850f32019-07-19 22:05:51 +02008885 endfor
Luca Saccarolac363ca12024-12-19 20:16:18 +01008886 let w:netrw_treedict[dir]= entries
Bram Moolenaar85850f32019-07-19 22:05:51 +02008887 endif
8888 if depth != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008889 " always remove "." and ".." entries when there's depth
8890 call filter(w:netrw_treedict[dir],'v:val !~ "\\.\\.$"')
8891 call filter(w:netrw_treedict[dir],'v:val !~ "\\.\\./$"')
8892 call filter(w:netrw_treedict[dir],'v:val !~ "\\.$"')
8893 call filter(w:netrw_treedict[dir],'v:val !~ "\\./$"')
Bram Moolenaar85850f32019-07-19 22:05:51 +02008894 endif
8895
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008896 for entry in w:netrw_treedict[dir]
Luca Saccarolac363ca12024-12-19 20:16:18 +01008897 if dir =~ '/$'
8898 let direntry= substitute(dir.entry,'[@/]$','','e')
8899 else
8900 let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
8901 endif
8902 if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
8903 NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
8904 elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
8905 NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
8906 elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
8907 NetrwKeepj call s:NetrwTreeDisplay(direntry.'@',depth)
8908 else
8909 sil! NetrwKeepj call setline(line("$")+1,depth.entry)
8910 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008911 endfor
Bram Moolenaar446cb832008-06-24 21:56:24 +00008912endfun
8913
8914" ---------------------------------------------------------------------
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008915" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
8916fun! s:NetrwRefreshTreeDict(dir)
Bram Moolenaar85850f32019-07-19 22:05:51 +02008917 if !exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008918 return
Bram Moolenaar85850f32019-07-19 22:05:51 +02008919 endif
8920
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008921 for entry in w:netrw_treedict[a:dir]
Luca Saccarolac363ca12024-12-19 20:16:18 +01008922 let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008923
Luca Saccarolac363ca12024-12-19 20:16:18 +01008924 if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
8925 NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
8926 let filelist = s:NetrwLocalListingList(direntry,0)
8927 let w:netrw_treedict[direntry] = sort(filelist)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008928
Luca Saccarolac363ca12024-12-19 20:16:18 +01008929 elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
8930 NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
8931 let filelist = s:NetrwLocalListingList(direntry.'/',0)
8932 let w:netrw_treedict[direntry] = sort(filelist)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008933
Luca Saccarolac363ca12024-12-19 20:16:18 +01008934 elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
8935 NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
8936 let liststar = s:NetrwGlob(direntry.'/','*',1)
8937 let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008938
Luca Saccarolac363ca12024-12-19 20:16:18 +01008939 else
8940 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008941 endfor
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008942endfun
8943
8944" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00008945" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008946" Called by s:PerformListing()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008947fun! s:NetrwTreeListing(dirname)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008948 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Bram Moolenaar446cb832008-06-24 21:56:24 +00008949
Luca Saccarolac363ca12024-12-19 20:16:18 +01008950 " update the treetop
8951 if !exists("w:netrw_treetop")
8952 let w:netrw_treetop= a:dirname
8953 let s:netrw_treetop= w:netrw_treetop
8954 " use \V in case the directory contains specials chars like '$' or '~'
8955 elseif (w:netrw_treetop =~ ('^'.'\V'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop))
8956 \ || a:dirname !~ ('^'.'\V'.w:netrw_treetop)
8957 let w:netrw_treetop= a:dirname
8958 let s:netrw_treetop= w:netrw_treetop
8959 endif
8960 if exists("w:netrw_treetop")
8961 let s:netrw_treetop= w:netrw_treetop
8962 else
8963 let w:netrw_treetop= getcwd()
8964 let s:netrw_treetop= w:netrw_treetop
8965 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008966
Luca Saccarolac363ca12024-12-19 20:16:18 +01008967 if !exists("w:netrw_treedict")
8968 " insure that we have a treedict, albeit empty
8969 let w:netrw_treedict= {}
8970 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008971
Luca Saccarolac363ca12024-12-19 20:16:18 +01008972 " update the dictionary for the current directory
8973 exe "sil! NetrwKeepj keepp ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
8974 let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
8975 exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
Bram Moolenaar446cb832008-06-24 21:56:24 +00008976
Luca Saccarolac363ca12024-12-19 20:16:18 +01008977 " if past banner, record word
8978 if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
8979 let fname= expand("<cword>")
8980 else
8981 let fname= ""
8982 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008983
Luca Saccarolac363ca12024-12-19 20:16:18 +01008984 " display from treetop on down
8985 NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
Bram Moolenaar8d043172014-01-23 14:24:41 +01008986
Luca Saccarolac363ca12024-12-19 20:16:18 +01008987 " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
8988 while getline(1) =~ '^\s*$' && byte2line(1) > 0
8989 1d
8990 endwhile
Bram Moolenaar8d043172014-01-23 14:24:41 +01008991
Luca Saccarolac363ca12024-12-19 20:16:18 +01008992 exe "setl ".g:netrw_bufsettings
Bram Moolenaar446cb832008-06-24 21:56:24 +00008993
Luca Saccarolac363ca12024-12-19 20:16:18 +01008994 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00008995 endif
8996endfun
8997
8998" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02008999" s:NetrwTreePath: returns path to current file/directory in tree listing {{{2
Bram Moolenaara6878372014-03-22 21:02:50 +01009000" Normally, treetop is w:netrw_treetop, but a
9001" user of the function ( netrw#SetTreetop() )
9002" wipes that out prior to calling this function
9003fun! s:NetrwTreePath(treetop)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009004 " call Dfunc("s:NetrwTreePath(treetop<".a:treetop.">) line#".line(".")."<".getline(".").">")
Bram Moolenaar85850f32019-07-19 22:05:51 +02009005 if line(".") < w:netrw_bannercnt + 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01009006 let treedir= a:treetop
9007 if treedir !~ '/$'
9008 let treedir= treedir.'/'
9009 endif
9010 " call Dret("s:NetrwTreePath ".treedir." : line#".line(".")." ≤ ".(w:netrw_bannercnt+2))
9011 return treedir
Bram Moolenaar85850f32019-07-19 22:05:51 +02009012 endif
9013
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009014 let svpos = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +01009015 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009016 let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009017 " call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009018 let depth = substitute(depth,'^'.s:treedepthstring,'','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009019 " call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009020 let curline= getline('.')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009021 " call Decho("curline<".curline.'>','~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009022 if curline =~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01009023 " call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9024 let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9025 " call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009026 elseif curline =~ '@\s\+-->'
Luca Saccarolac363ca12024-12-19 20:16:18 +01009027 " call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9028 let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9029 let treedir= substitute(treedir,'@\s\+-->.*$','','e')
9030 " call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009031 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009032 " call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9033 let treedir= ""
Bram Moolenaara6878372014-03-22 21:02:50 +01009034 endif
9035 " construct treedir by searching backwards at correct depth
Luca Saccarolac363ca12024-12-19 20:16:18 +01009036 " call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9037 " call Decho("initial treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009038 while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009039 let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9040 let treedir= dirname.treedir
9041 let depth = substitute(depth,'^'.s:treedepthstring,'','')
9042 " call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009043 endwhile
Luca Saccarolac363ca12024-12-19 20:16:18 +01009044 " call Decho("treedir#1<".treedir.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009045 if a:treetop =~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01009046 let treedir= a:treetop.treedir
Bram Moolenaara6878372014-03-22 21:02:50 +01009047 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009048 let treedir= a:treetop.'/'.treedir
Bram Moolenaara6878372014-03-22 21:02:50 +01009049 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009050 " call Decho("treedir#2<".treedir.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009051 let treedir= substitute(treedir,'//$','/','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009052 " call Decho("treedir#3<".treedir.">",'~'.expand("<slnum>"))
9053 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009054 call winrestview(svpos)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009055 " call Dret("s:NetrwTreePath <".treedir.">")
Bram Moolenaara6878372014-03-22 21:02:50 +01009056 return treedir
9057endfun
9058
9059" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00009060" s:NetrwWideListing: {{{2
9061fun! s:NetrwWideListing()
9062
9063 if w:netrw_liststyle == s:WIDELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01009064 " call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9065 " look for longest filename (cpf=characters per filename)
9066 " cpf: characters per filename
9067 " fpl: filenames per line
9068 " fpc: filenames per column
9069 setl ma noro
9070 let dict={}
9071 " save the unnamed register and register 0-9 and a
9072 let dict.a=[getreg('a'), getregtype('a')]
9073 for i in range(0, 9)
9074 let dict[i] = [getreg(i), getregtype(i)]
9075 endfor
9076 let dict.unnamed = [getreg(''), getregtype('')]
9077 " call Decho("setl ma noro",'~'.expand("<slnum>"))
9078 let b:netrw_cpf= 0
9079 if line("$") >= w:netrw_bannercnt
9080 " determine the maximum filename size; use that to set cpf
9081 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009082 NetrwKeepj call histdel("/",-1)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009083 else
Christian Brabandt62f7b552024-06-23 20:23:40 +02009084 " restore stored registers
9085 call s:RestoreRegister(dict)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009086 " call Dret("NetrwWideListing")
Bram Moolenaar446cb832008-06-24 21:56:24 +00009087 return
Luca Saccarolac363ca12024-12-19 20:16:18 +01009088 endif
9089 " allow for two spaces to separate columns
9090 let b:netrw_cpf= b:netrw_cpf + 2
9091 " call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009092
Luca Saccarolac363ca12024-12-19 20:16:18 +01009093 " determine qty files per line (fpl)
9094 let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9095 if w:netrw_fpl <= 0
Bram Moolenaar446cb832008-06-24 21:56:24 +00009096 let w:netrw_fpl= 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01009097 endif
9098 " call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009099
Luca Saccarolac363ca12024-12-19 20:16:18 +01009100 " make wide display
9101 " fpc: files per column of wide listing
9102 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9103 NetrwKeepj call histdel("/",-1)
9104 let fpc = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9105 let newcolstart = w:netrw_bannercnt + fpc
9106 let newcolend = newcolstart + fpc - 1
9107 " call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9108 if has("clipboard") && g:netrw_clipboard
9109 " call Decho("(s:NetrwWideListing) save @* and @+",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009110 sil! let keepregstar = @*
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009111 sil! let keepregplus = @+
Luca Saccarolac363ca12024-12-19 20:16:18 +01009112 endif
9113 while line("$") >= newcolstart
Bram Moolenaar446cb832008-06-24 21:56:24 +00009114 if newcolend > line("$") | let newcolend= line("$") | endif
9115 let newcolqty= newcolend - newcolstart
9116 exe newcolstart
Bram Moolenaar29634562020-01-09 21:46:04 +01009117 " COMBAK: both of the visual-mode using lines below are problematic vis-a-vis @*
Bram Moolenaar446cb832008-06-24 21:56:24 +00009118 if newcolqty == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01009119 exe "sil! NetrwKeepj norm! 0\<c-v>$h\"ax".w:netrw_bannercnt."G$\"ap"
Bram Moolenaar446cb832008-06-24 21:56:24 +00009120 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009121 exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$h"ax'.w:netrw_bannercnt.'G$"ap'
Bram Moolenaar446cb832008-06-24 21:56:24 +00009122 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009123 exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009124 exe 'sil! NetrwKeepj '.w:netrw_bannercnt
Luca Saccarolac363ca12024-12-19 20:16:18 +01009125 endwhile
9126 if has("clipboard")
9127 " call Decho("(s:NetrwWideListing) restore @* and @+",'~'.expand("<slnum>"))
Bram Moolenaar0c0734d2019-11-26 21:44:46 +01009128 if @* != keepregstar | sil! let @* = keepregstar | endif
9129 if @+ != keepregplus | sil! let @+ = keepregplus | endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009130 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009131 exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9132 NetrwKeepj call histdel("/",-1)
9133 exe 'nno <buffer> <silent> w :call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9134 exe 'nno <buffer> <silent> b :call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9135 " call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9136 exe "setl ".g:netrw_bufsettings
9137 call s:RestoreRegister(dict)
9138 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9139 " call Dret("NetrwWideListing")
9140 return
9141else
9142 if hasmapto("w","n")
9143 sil! nunmap <buffer> w
9144 endif
9145 if hasmapto("b","n")
9146 sil! nunmap <buffer> b
9147 endif
9148endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009149endfun
9150
9151" ---------------------------------------------------------------------
9152" s:PerformListing: {{{2
9153fun! s:PerformListing(islocal)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009154 " call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9155 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9156 " call Decho("settings: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (enter)"." ei<".&ei.">",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02009157 sil! NetrwKeepj %d _
Luca Saccarolac363ca12024-12-19 20:16:18 +01009158 " call DechoBuf(bufnr("%"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009159
Bram Moolenaar15146672011-10-20 22:22:38 +02009160 " set up syntax highlighting {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01009161 " call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009162 sil! setl ft=netrw
Bram Moolenaar15146672011-10-20 22:22:38 +02009163
Bram Moolenaar85850f32019-07-19 22:05:51 +02009164 NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
Bram Moolenaara6878372014-03-22 21:02:50 +01009165 setl noro ma
Luca Saccarolac363ca12024-12-19 20:16:18 +01009166 " call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009167
Luca Saccarolac363ca12024-12-19 20:16:18 +01009168 " if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1 " Decho
9169 " call Decho("Processing your browsing request...",'~'.expand("<slnum>"))
9170 " endif " Decho
Bram Moolenaar446cb832008-06-24 21:56:24 +00009171
Luca Saccarolac363ca12024-12-19 20:16:18 +01009172 " call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009173 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009174 " force a refresh for tree listings
9175 " call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9176 sil! NetrwKeepj %d _
Bram Moolenaar446cb832008-06-24 21:56:24 +00009177 endif
9178
9179 " save current directory on directory history list
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009180 NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009181
9182 " Set up the banner {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +01009183 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009184 " call Decho("--set up banner",'~'.expand("<slnum>"))
9185 NetrwKeepj call setline(1,'" ============================================================================')
9186 if exists("g:netrw_pchk")
9187 " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9188 " failure detections.
9189 NetrwKeepj call setline(2,'" Netrw Directory Listing')
9190 else
9191 NetrwKeepj call setline(2,'" Netrw Directory Listing (netrw '.g:loaded_netrw.')')
9192 endif
9193 if exists("g:netrw_pchk")
9194 let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9195 else
9196 let curdir= b:netrw_curdir
9197 endif
9198 if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9199 NetrwKeepj call setline(3,'" '.substitute(curdir,'/','\\','g'))
9200 else
9201 NetrwKeepj call setline(3,'" '.curdir)
9202 endif
9203 let w:netrw_bannercnt= 3
9204 NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
Bram Moolenaar5c736222010-01-06 20:54:52 +01009205 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009206 " call Decho("--no banner",'~'.expand("<slnum>"))
9207 NetrwKeepj 1
9208 let w:netrw_bannercnt= 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01009209 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009210 " call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9211 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009212
Bram Moolenaar85850f32019-07-19 22:05:51 +02009213 " construct sortby string: [name|time|size|exten] [reversed]
Bram Moolenaar446cb832008-06-24 21:56:24 +00009214 let sortby= g:netrw_sort_by
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02009215 if g:netrw_sort_direction =~# "^r"
Luca Saccarolac363ca12024-12-19 20:16:18 +01009216 let sortby= sortby." reversed"
Bram Moolenaar446cb832008-06-24 21:56:24 +00009217 endif
9218
9219 " Sorted by... {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +01009220 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009221 " call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9222 if g:netrw_sort_by =~# "^n"
9223 " call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9224 " sorted by name (also includes the sorting sequence in the banner)
9225 NetrwKeepj put ='\" Sorted by '.sortby
9226 NetrwKeepj put ='\" Sort sequence: '.g:netrw_sort_sequence
9227 let w:netrw_bannercnt= w:netrw_bannercnt + 2
9228 else
9229 " call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9230 " sorted by time, size, exten
9231 NetrwKeepj put ='\" Sorted by '.sortby
9232 let w:netrw_bannercnt= w:netrw_bannercnt + 1
9233 endif
9234 exe "sil! NetrwKeepj ".w:netrw_bannercnt
9235 " else " Decho
9236 " call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009237 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009238
Bram Moolenaar85850f32019-07-19 22:05:51 +02009239 " show copy/move target, if any {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +01009240 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009241 if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9242 " call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9243 NetrwKeepj put =''
9244 if s:netrwmftgt_islocal
9245 sil! NetrwKeepj call setline(line("."),'" Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9246 else
9247 sil! NetrwKeepj call setline(line("."),'" Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9248 endif
9249 let w:netrw_bannercnt= w:netrw_bannercnt + 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01009250 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009251 " call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +01009252 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009253 exe "sil! NetrwKeepj ".w:netrw_bannercnt
Bram Moolenaar446cb832008-06-24 21:56:24 +00009254 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009255
9256 " Hiding... -or- Showing... {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +01009257 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009258 " call Decho("--handle hiding/showing in banner (g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9259 if g:netrw_list_hide != "" && g:netrw_hide
9260 if g:netrw_hide == 1
9261 NetrwKeepj put ='\" Hiding: '.g:netrw_list_hide
9262 else
9263 NetrwKeepj put ='\" Showing: '.g:netrw_list_hide
9264 endif
9265 let w:netrw_bannercnt= w:netrw_bannercnt + 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01009266 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009267 exe "NetrwKeepj ".w:netrw_bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +01009268
Luca Saccarolac363ca12024-12-19 20:16:18 +01009269 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9270 let quickhelp = g:netrw_quickhelp%len(s:QuickHelp)
9271 " call Decho("quickhelp =".quickhelp,'~'.expand("<slnum>"))
9272 NetrwKeepj put ='\" Quick Help: <F1>:help '.s:QuickHelp[quickhelp]
9273 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9274 NetrwKeepj put ='\" =============================================================================='
9275 let w:netrw_bannercnt= w:netrw_bannercnt + 2
9276 " else " Decho
9277 " call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009278 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009279
9280 " bannercnt should index the line just after the banner
Bram Moolenaar5c736222010-01-06 20:54:52 +01009281 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009282 let w:netrw_bannercnt= w:netrw_bannercnt + 1
9283 exe "sil! NetrwKeepj ".w:netrw_bannercnt
9284 " call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9285 " else " Decho
9286 " call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +01009287 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009288
Bram Moolenaar446cb832008-06-24 21:56:24 +00009289 " get list of files
Luca Saccarolac363ca12024-12-19 20:16:18 +01009290 " call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009291 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01009292 NetrwKeepj call s:LocalListing()
Bram Moolenaar446cb832008-06-24 21:56:24 +00009293 else " remote
Luca Saccarolac363ca12024-12-19 20:16:18 +01009294 NetrwKeepj let badresult= s:NetrwRemoteListing()
9295 if badresult
9296 " call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9297 " call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9298 return
9299 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009300 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009301
9302 " manipulate the directory listing (hide, sort) {{{3
Bram Moolenaar5b435d62012-04-05 17:33:26 +02009303 if !exists("w:netrw_bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009304 let w:netrw_bannercnt= 0
Bram Moolenaar5b435d62012-04-05 17:33:26 +02009305 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009306 " call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9307 " call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9308 " call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009309
Bram Moolenaar5c736222010-01-06 20:54:52 +01009310 if !g:netrw_banner || line("$") >= w:netrw_bannercnt
Luca Saccarolac363ca12024-12-19 20:16:18 +01009311 " call Decho("manipulate directory listing (support hide)",'~'.expand("<slnum>"))
9312 " call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9313 if g:netrw_hide && g:netrw_list_hide != ""
9314 NetrwKeepj call s:NetrwListHide()
Bram Moolenaar446cb832008-06-24 21:56:24 +00009315 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009316 if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9317 " call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009318
Luca Saccarolac363ca12024-12-19 20:16:18 +01009319 if g:netrw_sort_by =~# "^n"
9320 " sort by name
9321 " call Decho("sort by name",'~'.expand("<slnum>"))
9322 NetrwKeepj call s:NetrwSetSort()
9323
9324 if !g:netrw_banner || w:netrw_bannercnt < line("$")
9325 " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9326 if g:netrw_sort_direction =~# 'n'
9327 " name: sort by name of file
9328 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9329 else
9330 " reverse direction sorting
9331 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9332 endif
9333 endif
9334
9335 " remove priority pattern prefix
9336 " call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9337 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9338 NetrwKeepj call histdel("/",-1)
9339
9340 elseif g:netrw_sort_by =~# "^ext"
9341 " exten: sort by extension
9342 " The histdel(...,-1) calls remove the last search from the search history
9343 " call Decho("sort by extension",'~'.expand("<slnum>"))
9344 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9345 NetrwKeepj call histdel("/",-1)
9346 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9347 NetrwKeepj call histdel("/",-1)
9348 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9349 NetrwKeepj call histdel("/",-1)
9350 if !g:netrw_banner || w:netrw_bannercnt < line("$")
9351 " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9352 if g:netrw_sort_direction =~# 'n'
9353 " normal direction sorting
9354 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9355 else
9356 " reverse direction sorting
9357 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9358 endif
9359 endif
9360 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9361 NetrwKeepj call histdel("/",-1)
9362
9363 elseif a:islocal
9364 if !g:netrw_banner || w:netrw_bannercnt < line("$")
9365 " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9366 if g:netrw_sort_direction =~# 'n'
9367 " call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9368 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9369 else
9370 " call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9371 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9372 endif
9373 " call Decho("remove leading digits/ (sorting) information from listing",'~'.expand("<slnum>"))
9374 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9375 NetrwKeepj call histdel("/",-1)
9376 endif
9377 endif
9378
9379 elseif g:netrw_sort_direction =~# 'r'
9380 " call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9381 if !g:netrw_banner || w:netrw_bannercnt < line('$')
9382 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9383 call histdel("/",-1)
9384 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01009385 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009386 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009387 " call Decho("g:netrw_banner=".g:netrw_banner.": banner ".(g:netrw_banner? "enabled" : "suppressed").": (line($)=".line("$")." byte2line(1)=".byte2line(1)." bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009388
9389 " convert to wide/tree listing {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01009390 " call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9391 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#1)",'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009392 NetrwKeepj call s:NetrwWideListing()
Luca Saccarolac363ca12024-12-19 20:16:18 +01009393 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#2)",'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009394 NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009395 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#3)",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009396
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009397 " resolve symbolic links if local and (thin or tree)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009398 if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
Luca Saccarolac363ca12024-12-19 20:16:18 +01009399 " call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9400 sil! keepp g/@$/call s:ShowLink()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009401 endif
9402
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009403 if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009404 " place cursor on the top-left corner of the file listing
9405 " call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9406 exe 'sil! '.w:netrw_bannercnt
9407 sil! NetrwKeepj norm! 0
9408 " call Decho(" tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009409 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009410 " call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9411 " call Decho(" w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9412 " call Decho(" line($)=".line("$"),'~'.expand("<slnum>"))
9413 " call Decho(" g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009414 endif
9415
9416 " record previous current directory
9417 let w:netrw_prvdir= b:netrw_curdir
Luca Saccarolac363ca12024-12-19 20:16:18 +01009418 " call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009419
9420 " save certain window-oriented variables into buffer-oriented variables {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01009421 " call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9422 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#4)",'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009423 NetrwKeepj call s:SetBufWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +01009424 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#5)",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02009425 NetrwKeepj call s:NetrwOptionsRestore("w:")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009426 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#6)",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009427
9428 " set display to netrw display settings
Luca Saccarolac363ca12024-12-19 20:16:18 +01009429 " call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +02009430 exe "setl ".g:netrw_bufsettings
Luca Saccarolac363ca12024-12-19 20:16:18 +01009431 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#7)",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +01009432 if g:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01009433 " call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9434 exe "setl ts=".(g:netrw_maxfilenamelen+1)
Bram Moolenaar97d62492012-11-15 21:28:22 +01009435 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009436 " call Decho("PerformListing buffer:",'~'.expand("<slnum>"))
9437 " call DechoBuf(bufnr("%"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009438
Bram Moolenaar8d043172014-01-23 14:24:41 +01009439 if exists("s:treecurpos")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009440 " call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
9441 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (internal#8)",'~'.expand("<slnum>"))
9442 " call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9443 NetrwKeepj call winrestview(s:treecurpos)
9444 unlet s:treecurpos
Bram Moolenaar446cb832008-06-24 21:56:24 +00009445 endif
9446
Luca Saccarolac363ca12024-12-19 20:16:18 +01009447 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo. " (return)",'~'.expand("<slnum>"))
9448 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9449 " call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
Bram Moolenaar446cb832008-06-24 21:56:24 +00009450endfun
9451
9452" ---------------------------------------------------------------------
9453" s:SetupNetrwStatusLine: {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +00009454fun! s:SetupNetrwStatusLine(statline)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009455 " call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +00009456
9457 if !exists("s:netrw_setup_statline")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009458 let s:netrw_setup_statline= 1
9459 " call Decho("do first-time status line setup",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00009460
Luca Saccarolac363ca12024-12-19 20:16:18 +01009461 if !exists("s:netrw_users_stl")
9462 let s:netrw_users_stl= &stl
Bram Moolenaar9964e462007-05-05 17:54:07 +00009463 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009464 if !exists("s:netrw_users_ls")
9465 let s:netrw_users_ls= &laststatus
9466 endif
9467
9468 " set up User9 highlighting as needed
9469 let dict={}
9470 let dict.a=[getreg('a'), getregtype('a')]
9471 redir @a
9472 try
9473 hi User9
9474 catch /^Vim\%((\a\{3,})\)\=:E411/
9475 if &bg == "dark"
9476 hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
9477 else
9478 hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
9479 endif
9480 endtry
9481 redir END
9482 call s:RestoreRegister(dict)
Bram Moolenaar9964e462007-05-05 17:54:07 +00009483 endif
9484
9485 " set up status line (may use User9 highlighting)
9486 " insure that windows have a statusline
9487 " make sure statusline is displayed
K.Takataa262d3f2024-01-25 04:10:19 +09009488 let &l:stl=a:statline
Bram Moolenaarff034192013-04-24 18:51:19 +02009489 setl laststatus=2
Luca Saccarolac363ca12024-12-19 20:16:18 +01009490 " call Decho("stl=".&stl,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009491 redraw
Bram Moolenaar9964e462007-05-05 17:54:07 +00009492
Luca Saccarolac363ca12024-12-19 20:16:18 +01009493 " call Dret("SetupNetrwStatusLine : stl=".&stl)
Bram Moolenaar9964e462007-05-05 17:54:07 +00009494endfun
9495
Bram Moolenaar85850f32019-07-19 22:05:51 +02009496" =========================================
9497" Remote Directory Browsing Support: {{{1
9498" =========================================
Bram Moolenaar9964e462007-05-05 17:54:07 +00009499
9500" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01009501" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
9502" This function assumes that a long listing will be received. Size, time,
9503" and reverse sorts will be requested of the server but not otherwise
9504" enforced here.
9505fun! s:NetrwRemoteFtpCmd(path,listcmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009506 " call Dfunc("NetrwRemoteFtpCmd(path<".a:path."> listcmd<".a:listcmd.">) w:netrw_method=".(exists("w:netrw_method")? w:netrw_method : (exists("b:netrw_method")? b:netrw_method : "???")))
9507 " call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009508 " sanity check: {{{3
9509 if !exists("w:netrw_method")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009510 if exists("b:netrw_method")
9511 let w:netrw_method= b:netrw_method
9512 else
9513 call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
9514 " call Dret("NetrwRemoteFtpCmd")
9515 return
9516 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009517 endif
9518
Luca Saccarolac363ca12024-12-19 20:16:18 +01009519 " WinXX ftp uses unix style input, so set ff to unix " {{{3
Bram Moolenaara6878372014-03-22 21:02:50 +01009520 let ffkeep= &ff
9521 setl ma ff=unix noro
Luca Saccarolac363ca12024-12-19 20:16:18 +01009522 " call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009523
Luca Saccarolac363ca12024-12-19 20:16:18 +01009524 " clear off any older non-banner lines " {{{3
Bram Moolenaara6878372014-03-22 21:02:50 +01009525 " note that w:netrw_bannercnt indexes the line after the banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009526 " call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _ (clear off old non-banner lines)",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009527 exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
Bram Moolenaara6878372014-03-22 21:02:50 +01009528
9529 ".........................................
Luca Saccarolac363ca12024-12-19 20:16:18 +01009530 if w:netrw_method == 2 || w:netrw_method == 5 " {{{3
9531 " ftp + <.netrc>: Method #2
9532 if a:path != ""
9533 NetrwKeepj put ='cd \"'.a:path.'\"'
9534 endif
9535 if exists("g:netrw_ftpextracmd")
9536 NetrwKeepj put =g:netrw_ftpextracmd
9537 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9538 endif
9539 NetrwKeepj call setline(line("$")+1,a:listcmd)
9540 " exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9541 if exists("g:netrw_port") && g:netrw_port != ""
9542 " call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1),'~'.expand("<slnum>"))
9543 exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1)
9544 else
9545 " call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
9546 exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
9547 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009548
Luca Saccarolac363ca12024-12-19 20:16:18 +01009549 ".........................................
9550 elseif w:netrw_method == 3 " {{{3
9551 " ftp + machine,id,passwd,filename: Method #3
Bram Moolenaara6878372014-03-22 21:02:50 +01009552 setl ff=unix
9553 if exists("g:netrw_port") && g:netrw_port != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01009554 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
Bram Moolenaara6878372014-03-22 21:02:50 +01009555 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009556 NetrwKeepj put ='open '.g:netrw_machine
Bram Moolenaara6878372014-03-22 21:02:50 +01009557 endif
9558
9559 " handle userid and password
9560 let host= substitute(g:netrw_machine,'\..*$','','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009561 " call Decho("host<".host.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009562 if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009563 call NetUserPass("ftp:".host)
Bram Moolenaara6878372014-03-22 21:02:50 +01009564 endif
9565 if exists("g:netrw_uid") && g:netrw_uid != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01009566 if exists("g:netrw_ftp") && g:netrw_ftp == 1
9567 NetrwKeepj put =g:netrw_uid
9568 if exists("s:netrw_passwd") && s:netrw_passwd != ""
9569 NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
9570 endif
9571 elseif exists("s:netrw_passwd")
9572 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
Bram Moolenaara6878372014-03-22 21:02:50 +01009573 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009574 endif
9575
Luca Saccarolac363ca12024-12-19 20:16:18 +01009576 if a:path != ""
9577 NetrwKeepj put ='cd \"'.a:path.'\"'
9578 endif
9579 if exists("g:netrw_ftpextracmd")
9580 NetrwKeepj put =g:netrw_ftpextracmd
9581 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9582 endif
9583 NetrwKeepj call setline(line("$")+1,a:listcmd)
Bram Moolenaara6878372014-03-22 21:02:50 +01009584
Luca Saccarolac363ca12024-12-19 20:16:18 +01009585 " perform ftp:
9586 " -i : turns off interactive prompting from ftp
9587 " -n unix : DON'T use <.netrc>, even though it exists
9588 " -n win32: quit being obnoxious about password
9589 if exists("w:netrw_bannercnt")
9590 " exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9591 call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
9592 " else " Decho
9593 " call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
9594 " g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
9595 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009596
Luca Saccarolac363ca12024-12-19 20:16:18 +01009597 ".........................................
9598 elseif w:netrw_method == 9 " {{{3
9599 " sftp username@machine: Method #9
9600 " s:netrw_sftp_cmd
9601 setl ff=unix
Bram Moolenaara6878372014-03-22 21:02:50 +01009602
Luca Saccarolac363ca12024-12-19 20:16:18 +01009603 " restore settings
9604 let &l:ff= ffkeep
9605 " call Dret("NetrwRemoteFtpCmd")
9606 return
Bram Moolenaara6878372014-03-22 21:02:50 +01009607
Luca Saccarolac363ca12024-12-19 20:16:18 +01009608 ".........................................
9609 else " {{{3
9610 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
Bram Moolenaara6878372014-03-22 21:02:50 +01009611 endif
9612
9613 " cleanup for Windows " {{{3
Nir Lichtman1e34b952024-05-08 19:19:34 +02009614 if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009615 sil! NetrwKeepj %s/\r$//e
9616 NetrwKeepj call histdel("/",-1)
Bram Moolenaara6878372014-03-22 21:02:50 +01009617 endif
9618 if a:listcmd == "dir"
Luca Saccarolac363ca12024-12-19 20:16:18 +01009619 " infer directory/link based on the file permission string
9620 sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
9621 sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009622 NetrwKeepj call histdel("/",-1)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009623 NetrwKeepj call histdel("/",-1)
9624 if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9625 exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
9626 NetrwKeepj call histdel("/",-1)
9627 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009628 endif
9629
9630 " ftp's listing doesn't seem to include ./ or ../ " {{{3
9631 if !search('^\.\/$\|\s\.\/$','wn')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009632 exe 'NetrwKeepj '.w:netrw_bannercnt
9633 NetrwKeepj put ='./'
Bram Moolenaara6878372014-03-22 21:02:50 +01009634 endif
9635 if !search('^\.\.\/$\|\s\.\.\/$','wn')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009636 exe 'NetrwKeepj '.w:netrw_bannercnt
9637 NetrwKeepj put ='../'
Bram Moolenaara6878372014-03-22 21:02:50 +01009638 endif
9639
9640 " restore settings " {{{3
K.Takataa262d3f2024-01-25 04:10:19 +09009641 let &l:ff= ffkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01009642 " call Dret("NetrwRemoteFtpCmd")
Bram Moolenaara6878372014-03-22 21:02:50 +01009643endfun
9644
9645" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00009646" s:NetrwRemoteListing: {{{2
9647fun! s:NetrwRemoteListing()
Luca Saccarolac363ca12024-12-19 20:16:18 +01009648 " call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
Bram Moolenaar69a7cb42004-06-20 12:51:53 +00009649
Bram Moolenaara6878372014-03-22 21:02:50 +01009650 if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009651 let w:netrw_bannercnt= s:bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +01009652 endif
9653 if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009654 let w:netrw_bannercnt= b:bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +01009655 endif
9656
Bram Moolenaar446cb832008-06-24 21:56:24 +00009657 call s:RemotePathAnalysis(b:netrw_curdir)
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00009658
Bram Moolenaar446cb832008-06-24 21:56:24 +00009659 " sanity check:
9660 if exists("b:netrw_method") && b:netrw_method =~ '[235]'
Luca Saccarolac363ca12024-12-19 20:16:18 +01009661 " call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
9662 if !executable("ftp")
9663 " call Decho("ftp is not executable",'~'.expand("<slnum>"))
9664 if !exists("g:netrw_quiet")
9665 call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
9666 endif
9667 call s:NetrwOptionsRestore("w:")
9668 " call Dret("s:NetrwRemoteListing -1")
9669 return -1
Bram Moolenaar446cb832008-06-24 21:56:24 +00009670 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009671
Bram Moolenaar8d043172014-01-23 14:24:41 +01009672 elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
Luca Saccarolac363ca12024-12-19 20:16:18 +01009673 " call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
9674 if !exists("g:netrw_quiet")
9675 if g:netrw_list_cmd == ""
9676 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your g:netrw_list_cmd is empty; perhaps ".g:netrw_ssh_cmd." is not executable on your system",47)
9677 else
9678 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
9679 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009680 endif
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00009681
Luca Saccarolac363ca12024-12-19 20:16:18 +01009682 NetrwKeepj call s:NetrwOptionsRestore("w:")
9683 " call Dret("s:NetrwRemoteListing -1")
9684 return -1
Bram Moolenaar446cb832008-06-24 21:56:24 +00009685 endif " (remote handling sanity check)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009686 " call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00009687
Bram Moolenaar446cb832008-06-24 21:56:24 +00009688 if exists("b:netrw_method")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009689 " call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
9690 let w:netrw_method= b:netrw_method
Bram Moolenaar446cb832008-06-24 21:56:24 +00009691 endif
9692
Bram Moolenaar13600302014-05-22 18:26:40 +02009693 if s:method == "ftp"
Luca Saccarolac363ca12024-12-19 20:16:18 +01009694 " use ftp to get remote file listing {{{3
9695 " call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
9696 let s:method = "ftp"
9697 let listcmd = g:netrw_ftp_list_cmd
9698 if g:netrw_sort_by =~# '^t'
9699 let listcmd= g:netrw_ftp_timelist_cmd
9700 elseif g:netrw_sort_by =~# '^s'
9701 let listcmd= g:netrw_ftp_sizelist_cmd
Bram Moolenaara6878372014-03-22 21:02:50 +01009702 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009703 " call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
9704 call s:NetrwRemoteFtpCmd(s:path,listcmd)
9705 " exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
Bram Moolenaara6878372014-03-22 21:02:50 +01009706
Luca Saccarolac363ca12024-12-19 20:16:18 +01009707 " report on missing file or directory messages
9708 if search('[Nn]o such file or directory\|Failed to change directory')
9709 let mesg= getline(".")
9710 if exists("w:netrw_bannercnt")
9711 setl ma
9712 exe w:netrw_bannercnt.",$d _"
9713 setl noma
9714 endif
9715 NetrwKeepj call s:NetrwOptionsRestore("w:")
9716 call netrw#ErrorMsg(s:WARNING,mesg,96)
9717 " call Dret("s:NetrwRemoteListing : -1")
9718 return -1
9719 endif
9720
9721 if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9722 " shorten the listing
9723 " call Decho("generate short listing",'~'.expand("<slnum>"))
9724 exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
9725
9726 " cleanup
9727 if g:netrw_ftp_browse_reject != ""
9728 exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
9729 NetrwKeepj call histdel("/",-1)
9730 endif
9731 sil! NetrwKeepj %s/\r$//e
9732 NetrwKeepj call histdel("/",-1)
9733
9734 " if there's no ../ listed, then put ../ in
9735 let line1= line(".")
9736 exe "sil! NetrwKeepj ".w:netrw_bannercnt
9737 let line2= search('\.\.\/\%(\s\|$\)','cnW')
9738 " call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9739 if line2 == 0
9740 " call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
9741 sil! NetrwKeepj put='../'
9742 endif
9743 exe "sil! NetrwKeepj ".line1
9744 sil! NetrwKeepj norm! 0
9745
9746 " call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
9747 if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9748 " call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
9749 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
9750 NetrwKeepj call histdel("/",-1)
9751 else " normal ftp cleanup
9752 " call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
9753 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
9754 exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
9755 exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
9756 NetrwKeepj call histdel("/",-1)
9757 NetrwKeepj call histdel("/",-1)
9758 NetrwKeepj call histdel("/",-1)
9759 endif
9760 endif
9761
9762 else
9763 " use ssh to get remote file listing {{{3
9764 " call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
9765 let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
9766 " call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
9767 if g:netrw_scp_cmd =~ '^pscp'
9768 " call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
9769 exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
9770 " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
9771 sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
9772 sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
9773 sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
9774 NetrwKeepj call histdel("/",-1)
9775 NetrwKeepj call histdel("/",-1)
9776 NetrwKeepj call histdel("/",-1)
9777 if g:netrw_liststyle != s:LONGLIST
9778 sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
9779 NetrwKeepj call histdel("/",-1)
9780 endif
9781 else
9782 if s:path == ""
9783 " call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
9784 exe "NetrwKeepj keepalt r! ".listcmd
9785 else
9786 " call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
9787 exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
9788 " call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
9789 endif
9790 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009791
9792 " cleanup
Luca Saccarolac363ca12024-12-19 20:16:18 +01009793 if g:netrw_ssh_browse_reject != ""
9794 " call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
9795 exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
9796 NetrwKeepj call histdel("/",-1)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009797 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009798 endif
9799
9800 if w:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01009801 " do a long listing; these substitutions need to be done prior to sorting {{{3
9802 " call Decho("fix long listing:",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009803
Luca Saccarolac363ca12024-12-19 20:16:18 +01009804 if s:method == "ftp"
9805 " cleanup
9806 exe "sil! NetrwKeepj ".w:netrw_bannercnt
9807 while getline('.') =~# g:netrw_ftp_browse_reject
9808 sil! NetrwKeepj d
9809 endwhile
9810 " if there's no ../ listed, then put ../ in
9811 let line1= line(".")
9812 sil! NetrwKeepj 1
9813 sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
9814 let line2= line(".")
9815 if line2 == 0
9816 if b:netrw_curdir != '/'
9817 exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
9818 endif
9819 endif
9820 exe "sil! NetrwKeepj ".line1
9821 sil! NetrwKeepj norm! 0
Bram Moolenaar446cb832008-06-24 21:56:24 +00009822 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009823
Luca Saccarolac363ca12024-12-19 20:16:18 +01009824 if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9825 " call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
9826 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+\)\(\w.*\)$/\2\t\1/'
9827 elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
9828 " call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9829 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
9830 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
9831 exe 'sil NetrwKeepj '.w:netrw_bannercnt
9832 NetrwKeepj call histdel("/",-1)
9833 NetrwKeepj call histdel("/",-1)
9834 NetrwKeepj call histdel("/",-1)
9835 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009836 endif
9837
Luca Saccarolac363ca12024-12-19 20:16:18 +01009838 " if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
9839 " exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
9840 " endif " Decho
Bram Moolenaara6878372014-03-22 21:02:50 +01009841
Luca Saccarolac363ca12024-12-19 20:16:18 +01009842 " call Dret("s:NetrwRemoteListing 0")
Bram Moolenaara6878372014-03-22 21:02:50 +01009843 return 0
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00009844endfun
9845
Bram Moolenaar446cb832008-06-24 21:56:24 +00009846" ---------------------------------------------------------------------
9847" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
9848fun! s:NetrwRemoteRm(usrhost,path) range
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009849 let svpos= winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +00009850
9851 let all= 0
9852 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009853 " remove all marked files
9854 for fname in s:netrwmarkfilelist_{bufnr("%")}
9855 let ok= s:NetrwRemoteRmFile(a:path,fname,all)
9856 if ok =~# 'q\%[uit]'
9857 break
9858 elseif ok =~# 'a\%[ll]'
9859 let all= 1
9860 endif
9861 endfor
9862 call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009863
9864 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009865 " remove files specified by range
Bram Moolenaar446cb832008-06-24 21:56:24 +00009866
Luca Saccarolac363ca12024-12-19 20:16:18 +01009867 " preparation for removing multiple files/directories
9868 let keepsol = &l:sol
9869 setl nosol
9870 let ctr = a:firstline
Bram Moolenaar446cb832008-06-24 21:56:24 +00009871
Luca Saccarolac363ca12024-12-19 20:16:18 +01009872 " remove multiple files and directories
9873 while ctr <= a:lastline
9874 exe "NetrwKeepj ".ctr
9875 let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
9876 if ok =~# 'q\%[uit]'
9877 break
9878 elseif ok =~# 'a\%[ll]'
9879 let all= 1
9880 endif
9881 let ctr= ctr + 1
9882 endwhile
9883 let &l:sol = keepsol
Bram Moolenaar446cb832008-06-24 21:56:24 +00009884 endif
9885
9886 " refresh the (remote) directory listing
Tom Benham64a536d2024-11-07 21:15:03 +01009887 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009888 NetrwKeepj call winrestview(svpos)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009889endfun
9890
9891" ---------------------------------------------------------------------
9892" s:NetrwRemoteRmFile: {{{2
9893fun! s:NetrwRemoteRmFile(path,rmfile,all)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009894 " call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009895
9896 let all= a:all
9897 let ok = ""
9898
9899 if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009900 " attempt to remove file
9901 " call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
9902 if !all
9903 echohl Statement
9904 " call Decho("case all=0:",'~'.expand("<slnum>"))
9905 call inputsave()
9906 let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
9907 call inputrestore()
9908 echohl NONE
9909 if ok == ""
9910 let ok="no"
9911 endif
9912 let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
9913 if ok =~# 'a\%[ll]'
9914 let all= 1
9915 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009916 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009917
Luca Saccarolac363ca12024-12-19 20:16:18 +01009918 if all || ok =~# 'y\%[es]' || ok == ""
9919 " call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
9920 if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9921 " call Decho("case ftp:",'~'.expand("<slnum>"))
9922 let path= a:path
9923 if path =~ '^\a\{3,}://'
9924 let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
9925 endif
9926 sil! NetrwKeepj .,$d _
9927 call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
Bram Moolenaar446cb832008-06-24 21:56:24 +00009928 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009929 " call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
9930 let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
9931 " call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
9932 if !exists("b:netrw_curdir")
9933 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
9934 let ok="q"
9935 else
9936 let remotedir= substitute(b:netrw_curdir,'^.\{-}//[^/]\+/\(.*\)$','\1','')
9937 " call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
9938 " call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
9939 " call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
9940 if remotedir != ""
9941 let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
9942 else
9943 let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
9944 endif
9945 " call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
9946 let ret= system(netrw_rm_cmd)
9947 if v:shell_error != 0
9948 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
9949 call netrw#ErrorMsg(s:ERROR,"remove failed; perhaps due to vim's current directory<".getcwd()."> not matching netrw's (".b:netrw_curdir.") (see :help netrw-cd)",102)
9950 else
9951 call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
9952 endif
9953 elseif ret != 0
9954 call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
9955 endif
9956 " call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9957 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009958 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009959 elseif ok =~# 'q\%[uit]'
9960 " call Decho("ok==".ok,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009961 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009962
9963 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009964 " attempt to remove directory
9965 " call Decho("attempt to remove directory",'~'.expand("<slnum>"))
9966 if !all
9967 call inputsave()
9968 let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
9969 call inputrestore()
9970 if ok == ""
9971 let ok="no"
Bram Moolenaar446cb832008-06-24 21:56:24 +00009972 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009973 let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
9974 if ok =~# 'a\%[ll]'
9975 let all= 1
9976 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009977 endif
9978
Luca Saccarolac363ca12024-12-19 20:16:18 +01009979 if all || ok =~# 'y\%[es]' || ok == ""
9980 if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9981 NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
9982 else
9983 let rmfile = substitute(a:path.a:rmfile,'/$','','')
9984 let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
9985 " call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
9986 let ret= system(netrw_rmdir_cmd)
9987 " call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9988
9989 if v:shell_error != 0
9990 " call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
9991 let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
9992 " call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
9993 let ret= system(netrw_rmf_cmd)
9994 " call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9995
9996 if v:shell_error != 0 && !exists("g:netrw_quiet")
9997 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
9998 endif
9999 endif
10000 endif
10001
10002 elseif ok =~# 'q\%[uit]'
10003 " call Decho("ok==".ok,'~'.expand("<slnum>"))
10004 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010005 endif
10006
Luca Saccarolac363ca12024-12-19 20:16:18 +010010007 " call Dret("s:NetrwRemoteRmFile ".ok)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010008 return ok
10009endfun
10010
10011" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000010012" s:NetrwRemoteRename: rename a remote file or directory {{{2
10013fun! s:NetrwRemoteRename(usrhost,path) range
Bram Moolenaar446cb832008-06-24 21:56:24 +000010014
10015 " preparation for removing multiple files/directories
Bram Moolenaare0fa3742016-02-20 15:47:01 +010010016 let svpos = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +010010017 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010018 let ctr = a:firstline
10019 let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10020
10021 " rename files given by the markfilelist
10022 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010023 for oldname in s:netrwmarkfilelist_{bufnr("%")}
10024 if exists("subfrom")
10025 let newname= substitute(oldname,subfrom,subto,'')
10026 else
10027 call inputsave()
10028 let newname= input("Moving ".oldname." to : ",oldname)
10029 call inputrestore()
10030 if newname =~ '^s/'
10031 let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10032 let subto = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10033 let newname = substitute(oldname,subfrom,subto,'')
10034 endif
10035 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010036
Luca Saccarolac363ca12024-12-19 20:16:18 +010010037 if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10038 NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10039 else
10040 let oldname= s:ShellEscape(a:path.oldname)
10041 let newname= s:ShellEscape(a:path.newname)
10042 let ret = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10043 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010044
Luca Saccarolac363ca12024-12-19 20:16:18 +010010045 endfor
10046 call s:NetrwUnMarkFile(1)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010047
10048 else
10049
Luca Saccarolac363ca12024-12-19 20:16:18 +010010050 " attempt to rename files/directories
10051 let keepsol= &l:sol
10052 setl nosol
10053 while ctr <= a:lastline
10054 exe "NetrwKeepj ".ctr
Bram Moolenaar446cb832008-06-24 21:56:24 +000010055
Luca Saccarolac363ca12024-12-19 20:16:18 +010010056 let oldname= s:NetrwGetWord()
Bram Moolenaar446cb832008-06-24 21:56:24 +000010057
Luca Saccarolac363ca12024-12-19 20:16:18 +010010058 call inputsave()
10059 let newname= input("Moving ".oldname." to : ",oldname)
10060 call inputrestore()
Bram Moolenaar446cb832008-06-24 21:56:24 +000010061
Luca Saccarolac363ca12024-12-19 20:16:18 +010010062 if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10063 call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10064 else
10065 let oldname= s:ShellEscape(a:path.oldname)
10066 let newname= s:ShellEscape(a:path.newname)
10067 let ret = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10068 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010069
Luca Saccarolac363ca12024-12-19 20:16:18 +010010070 let ctr= ctr + 1
10071 endwhile
10072 let &l:sol= keepsol
Bram Moolenaar446cb832008-06-24 21:56:24 +000010073 endif
10074
10075 " refresh the directory
Tom Benham64a536d2024-11-07 21:15:03 +010010076 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010010077 NetrwKeepj call winrestview(svpos)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010078endfun
10079
Bram Moolenaar85850f32019-07-19 22:05:51 +020010080" ==========================================
Bram Moolenaar446cb832008-06-24 21:56:24 +000010081" Local Directory Browsing Support: {{{1
10082" ==========================================
10083
10084" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +020010085" netrw#FileUrlEdit: handles editing file://* files {{{2
Bram Moolenaar97d62492012-11-15 21:28:22 +010010086" Should accept: file://localhost/etc/fstab
10087" file:///etc/fstab
10088" file:///c:/WINDOWS/clock.avi
10089" file:///c|/WINDOWS/clock.avi
10090" file://localhost/c:/WINDOWS/clock.avi
10091" file://localhost/c|/WINDOWS/clock.avi
10092" file://c:/foo.txt
10093" file:///c:/foo.txt
10094" and %XX (where X is [0-9a-fA-F] is converted into a character with the given hexadecimal value
Bram Moolenaar85850f32019-07-19 22:05:51 +020010095fun! netrw#FileUrlEdit(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010096 " call Dfunc("netrw#FileUrlEdit(fname<".a:fname.">)")
Bram Moolenaar97d62492012-11-15 21:28:22 +010010097 let fname = a:fname
10098 if fname =~ '^file://localhost/'
Luca Saccarolac363ca12024-12-19 20:16:18 +010010099 " call Decho('converting file://localhost/ -to- file:///','~'.expand("<slnum>"))
10100 let fname= substitute(fname,'^file://localhost/','file:///','')
10101 " call Decho("fname<".fname.">",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010102 endif
Nir Lichtman1e34b952024-05-08 19:19:34 +020010103 if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010104 if fname =~ '^file:///\=\a[|:]/'
10105 " call Decho('converting file:///\a|/ -to- file://\a:/','~'.expand("<slnum>"))
10106 let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10107 " call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10108 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010109 endif
10110 let fname2396 = netrw#RFC2396(fname)
10111 let fname2396e= fnameescape(fname2396)
10112 let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
Nir Lichtman1e34b952024-05-08 19:19:34 +020010113 if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010114 " call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10115 if plainfname =~ '^/\+\a:'
10116 " call Decho('removing leading "/"s','~'.expand("<slnum>"))
10117 let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10118 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010119 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +020010120
Luca Saccarolac363ca12024-12-19 20:16:18 +010010121 " call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10122 " call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010123 exe "sil doau BufReadPre ".fname2396e
Bram Moolenaar85850f32019-07-19 22:05:51 +020010124 exe 'NetrwKeepj keepalt edit '.plainfname
10125 exe 'sil! NetrwKeepj keepalt bdelete '.fnameescape(a:fname)
10126
Luca Saccarolac363ca12024-12-19 20:16:18 +010010127 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10128 " call Dret("netrw#FileUrlEdit")
Bram Moolenaar97d62492012-11-15 21:28:22 +010010129 exe "sil doau BufReadPost ".fname2396e
10130endfun
10131
10132" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000010133" netrw#LocalBrowseCheck: {{{2
10134fun! netrw#LocalBrowseCheck(dirname)
Bram Moolenaar89a9c152021-08-29 21:55:35 +020010135 " This function is called by netrwPlugin.vim's s:LocalBrowseCheck(), s:NetrwRexplore(),
Bram Moolenaar85850f32019-07-19 22:05:51 +020010136 " and by <cr> when atop a listed file/directory (via a buffer-local map)
10137 "
10138 " unfortunate interaction -- split window debugging can't be used here, must use
10139 " D-echoRemOn or D-echoTabOn as the BufEnter event triggers
10140 " another call to LocalBrowseCheck() when attempts to write
10141 " to the DBG buffer are made.
10142 "
Bram Moolenaar446cb832008-06-24 21:56:24 +000010143 " The &ft == "netrw" test was installed because the BufEnter event
10144 " would hit when re-entering netrw windows, creating unexpected
10145 " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010146 " call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">)")
10147 " call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>"))
10148 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
Bram Moolenaar71badf92023-04-22 22:40:14 +010010149 " getting E930: Cannot use :redir inside execute
Luca Saccarolac363ca12024-12-19 20:16:18 +010010150 "" call Dredir("ls!","netrw#LocalBrowseCheck")
10151 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10152 " call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +010010153
Bram Moolenaar97d62492012-11-15 21:28:22 +010010154 let ykeep= @@
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010155 if isdirectory(s:NetrwFile(a:dirname))
Luca Saccarolac363ca12024-12-19 20:16:18 +010010156 " call Decho("is-directory ft<".&ft."> b:netrw_curdir<".(exists("b:netrw_curdir")? b:netrw_curdir : " doesn't exist")."> dirname<".a:dirname.">"." line($)=".line("$")." ft<".&ft."> g:netrw_fastbrowse=".g:netrw_fastbrowse,'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010157
Luca Saccarolac363ca12024-12-19 20:16:18 +010010158 if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10159 " call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10160 " call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10161 sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +010010162
Luca Saccarolac363ca12024-12-19 20:16:18 +010010163 elseif &ft == "netrw" && line("$") == 1
10164 " call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10165 sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +010010166
Luca Saccarolac363ca12024-12-19 20:16:18 +010010167 elseif exists("s:treeforceredraw")
10168 " call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10169 unlet s:treeforceredraw
10170 sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10171 endif
10172 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10173 " call Dret("netrw#LocalBrowseCheck")
10174 return
Bram Moolenaar446cb832008-06-24 21:56:24 +000010175 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +010010176
Bram Moolenaar85850f32019-07-19 22:05:51 +020010177 " The following code wipes out currently unused netrw buffers
Bram Moolenaar97d62492012-11-15 21:28:22 +010010178 " IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10179 " AND IF the listing style is not a tree listing
10180 if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010010181 " call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10182 let ibuf = 1
10183 let buflast = bufnr("$")
10184 while ibuf <= buflast
10185 if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10186 exe "sil! keepj keepalt ".ibuf."bw!"
10187 endif
10188 let ibuf= ibuf + 1
10189 endwhile
Bram Moolenaar97d62492012-11-15 21:28:22 +010010190 endif
10191 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +010010192 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
10193 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010194 " not a directory, ignore it
Luca Saccarolac363ca12024-12-19 20:16:18 +010010195 " call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
Bram Moolenaar446cb832008-06-24 21:56:24 +000010196endfun
10197
10198" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +010010199" s:LocalBrowseRefresh: this function is called after a user has {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +000010200" performed any shell command. The idea is to cause all local-browsing
10201" buffers to be refreshed after a user has executed some shell command,
10202" on the chance that s/he removed/created a file/directory with it.
Bram Moolenaara6878372014-03-22 21:02:50 +010010203fun! s:LocalBrowseRefresh()
Bram Moolenaar446cb832008-06-24 21:56:24 +000010204 " determine which buffers currently reside in a tab
10205 if !exists("s:netrw_browselist")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010206 return
Bram Moolenaar446cb832008-06-24 21:56:24 +000010207 endif
10208 if !exists("w:netrw_bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010209 return
Bram Moolenaar446cb832008-06-24 21:56:24 +000010210 endif
Christian Brabandtfbd72d22023-12-19 20:22:18 +010010211 if !empty(getcmdwintype())
10212 " cannot move away from cmdline window, see :h E11
10213 return
10214 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010010215 if exists("s:netrw_events") && s:netrw_events == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010010216 " s:LocalFastBrowser gets called (indirectly) from a
10217 let s:netrw_events= 2
10218 return
Bram Moolenaar5c736222010-01-06 20:54:52 +010010219 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010220 let itab = 1
10221 let buftablist = []
Bram Moolenaar97d62492012-11-15 21:28:22 +010010222 let ykeep = @@
Bram Moolenaar446cb832008-06-24 21:56:24 +000010223 while itab <= tabpagenr("$")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010224 let buftablist = buftablist + tabpagebuflist()
10225 let itab = itab + 1
10226 sil! tabn
Bram Moolenaar446cb832008-06-24 21:56:24 +000010227 endwhile
Bram Moolenaar446cb832008-06-24 21:56:24 +000010228 " GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10229 " | refresh any netrw window
10230 " | wipe out any non-displaying netrw buffer
Bram Moolenaar85850f32019-07-19 22:05:51 +020010231 let curwinid = win_getid(winnr())
Bram Moolenaar446cb832008-06-24 21:56:24 +000010232 let ibl = 0
10233 for ibuf in s:netrw_browselist
Luca Saccarolac363ca12024-12-19 20:16:18 +010010234 if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10235 " wipe out any non-displaying netrw buffer
10236 " (ibuf not shown in a current window AND
10237 " ibuf not in any tab)
10238 exe "sil! keepj bd ".fnameescape(ibuf)
10239 call remove(s:netrw_browselist,ibl)
10240 continue
10241 elseif index(tabpagebuflist(),ibuf) != -1
10242 " refresh any netrw buffer
10243 exe bufwinnr(ibuf)."wincmd w"
10244 if getline(".") =~# 'Quick Help'
10245 " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10246 " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10247 let g:netrw_quickhelp= g:netrw_quickhelp - 1
10248 endif
10249 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10250 NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10251 endif
10252 NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
Bram Moolenaara6878372014-03-22 21:02:50 +010010253 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010254 let ibl= ibl + 1
Bram Moolenaar446cb832008-06-24 21:56:24 +000010255 endfor
Bram Moolenaar85850f32019-07-19 22:05:51 +020010256 call win_gotoid(curwinid)
Bram Moolenaar97d62492012-11-15 21:28:22 +010010257 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +000010258endfun
10259
10260" ---------------------------------------------------------------------
Bram Moolenaar97d62492012-11-15 21:28:22 +010010261" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10262"
10263" g:netrw_ Directory Is
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010264" fastbrowse Local Remote
Bram Moolenaar97d62492012-11-15 21:28:22 +010010265" slow 0 D D D=Deleting a buffer implies it will not be re-used (slow)
10266" med 1 D H H=Hiding a buffer implies it may be re-used (fast)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010267" fast 2 H H
Bram Moolenaar97d62492012-11-15 21:28:22 +010010268"
10269" Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10270" Hiding a buffer means that it will be re-used when examined, hence "fast".
Bram Moolenaara6878372014-03-22 21:02:50 +010010271" (re-using a buffer may not be as accurate)
10272"
Bram Moolenaar89a9c152021-08-29 21:55:35 +020010273" s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds with medium-speed or fast browsing
Bram Moolenaara6878372014-03-22 21:02:50 +010010274" =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10275" BufEnter may be first event, then a FocusGained event. Ignore the first FocusGained event.
10276" If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10277" =2: autocmds installed (doesn't ignore any FocusGained events)
Bram Moolenaar97d62492012-11-15 21:28:22 +010010278fun! s:LocalFastBrowser()
Bram Moolenaar97d62492012-11-15 21:28:22 +010010279
10280 " initialize browselist, a list of buffer numbers that the local browser has used
10281 if !exists("s:netrw_browselist")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010282 let s:netrw_browselist= []
Bram Moolenaar97d62492012-11-15 21:28:22 +010010283 endif
10284
10285 " append current buffer to fastbrowse list
10286 if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
Luca Saccarolac363ca12024-12-19 20:16:18 +010010287 call add(s:netrw_browselist,bufnr("%"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010288 endif
10289
10290 " enable autocmd events to handle refreshing/removing local browser buffers
10291 " If local browse buffer is currently showing: refresh it
10292 " If local browse buffer is currently hidden : wipe it
10293 " g:netrw_fastbrowse=0 : slow speed, never re-use directory listing
10294 " =1 : medium speed, re-use directory listing for remote only
10295 " =2 : fast speed, always re-use directory listing when possible
Bram Moolenaara6878372014-03-22 21:02:50 +010010296 if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010297 let s:netrw_events= 1
10298 augroup AuNetrwEvent
10299 au!
10300 if has("win32")
10301 au ShellCmdPost * call s:LocalBrowseRefresh()
10302 else
10303 au ShellCmdPost,FocusGained * call s:LocalBrowseRefresh()
10304 endif
10305 augroup END
Bram Moolenaar97d62492012-11-15 21:28:22 +010010306
Luca Saccarolac363ca12024-12-19 20:16:18 +010010307 " user must have changed fastbrowse to its fast setting, so remove
10308 " the associated autocmd events
Bram Moolenaara6878372014-03-22 21:02:50 +010010309 elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010310 unlet s:netrw_events
10311 augroup AuNetrwEvent
10312 au!
10313 augroup END
10314 augroup! AuNetrwEvent
Bram Moolenaar97d62492012-11-15 21:28:22 +010010315 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010316endfun
10317
Tom Benham64a536d2024-11-07 21:15:03 +010010318fun! s:NetrwLocalListingList(dirname,setmaxfilenamelen)
Bram Moolenaara6878372014-03-22 21:02:50 +010010319 " get the list of files contained in the current directory
Tom Benham64a536d2024-11-07 21:15:03 +010010320 let dirname = a:dirname
10321 let dirnamelen = strlen(dirname)
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020010322 let filelist = s:NetrwGlob(dirname,"*",0)
10323 let filelist = filelist + s:NetrwGlob(dirname,".*",0)
Bram Moolenaara6878372014-03-22 21:02:50 +010010324
Nir Lichtman1e34b952024-05-08 19:19:34 +020010325 if g:netrw_cygwin == 0 && has("win32")
Tom Benham64a536d2024-11-07 21:15:03 +010010326 elseif index(filelist,'..') == -1 && dirname !~ '/'
Bram Moolenaara6878372014-03-22 21:02:50 +010010327 " include ../ in the glob() entry if its missing
Luca Saccarolac363ca12024-12-19 20:16:18 +010010328 let filelist= filelist+[s:ComposePath(dirname,"../")]
Bram Moolenaara6878372014-03-22 21:02:50 +010010329 endif
10330
Tom Benham64a536d2024-11-07 21:15:03 +010010331 if a:setmaxfilenamelen && get(g:, 'netrw_dynamic_maxfilenamelen', 0)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010332 let filelistcopy = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10333 let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
Bram Moolenaara6878372014-03-22 21:02:50 +010010334 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010010335
Tom Benham64a536d2024-11-07 21:15:03 +010010336 let resultfilelist = []
Bram Moolenaara6878372014-03-22 21:02:50 +010010337 for filename in filelist
Bram Moolenaara6878372014-03-22 21:02:50 +010010338
Luca Saccarolac363ca12024-12-19 20:16:18 +010010339 if getftype(filename) == "link"
10340 " indicate a symbolic link
10341 let pfile= filename."@"
Bram Moolenaara6878372014-03-22 21:02:50 +010010342
Luca Saccarolac363ca12024-12-19 20:16:18 +010010343 elseif getftype(filename) == "socket"
10344 " indicate a socket
10345 let pfile= filename."="
Bram Moolenaara6878372014-03-22 21:02:50 +010010346
Luca Saccarolac363ca12024-12-19 20:16:18 +010010347 elseif getftype(filename) == "fifo"
10348 " indicate a fifo
10349 let pfile= filename."|"
Bram Moolenaara6878372014-03-22 21:02:50 +010010350
Luca Saccarolac363ca12024-12-19 20:16:18 +010010351 elseif isdirectory(s:NetrwFile(filename))
10352 " indicate a directory
10353 let pfile= filename."/"
Bram Moolenaara6878372014-03-22 21:02:50 +010010354
Luca Saccarolac363ca12024-12-19 20:16:18 +010010355 elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10356 if has("win32")
10357 if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10358 " indicate an executable
10359 let pfile= filename."*"
10360 else
10361 " normal file
10362 let pfile= filename
10363 endif
10364 elseif executable(filename)
10365 " indicate an executable
10366 let pfile= filename."*"
10367 else
10368 " normal file
10369 let pfile= filename
10370 endif
10371
10372 else
Bram Moolenaara6878372014-03-22 21:02:50 +010010373 " normal file
10374 let pfile= filename
Luca Saccarolac363ca12024-12-19 20:16:18 +010010375 endif
10376
10377 if pfile =~ '//$'
10378 let pfile= substitute(pfile,'//$','/','e')
10379 endif
10380 let pfile= strpart(pfile,dirnamelen)
10381 let pfile= substitute(pfile,'^[/\\]','','e')
10382
10383 if w:netrw_liststyle == s:LONGLIST
10384 let longfile = printf("%-".g:netrw_maxfilenamelen."S",pfile)
10385 let sz = getfsize(filename)
10386 let szlen = 15 - (strdisplaywidth(longfile) - g:netrw_maxfilenamelen)
10387 let szlen = (szlen > 0) ? szlen : 0
10388
10389 if g:netrw_sizestyle =~# "[hH]"
10390 let sz= s:NetrwHumanReadable(sz)
10391 endif
10392 let fsz = printf("%".szlen."S",sz)
10393 let pfile= longfile." ".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
10394 endif
10395
10396 if g:netrw_sort_by =~# "^t"
10397 " sort by time (handles time up to 1 quintillion seconds, US)
10398 " Decorate listing by prepending a timestamp/ . Sorting will then be done based on time.
10399 let t = getftime(filename)
10400 let ft = printf("%018d",t)
10401 let ftpfile= ft.'/'.pfile
10402 let resultfilelist += [ftpfile]
10403
10404 elseif g:netrw_sort_by =~ "^s"
10405 " sort by size (handles file sizes up to 1 quintillion bytes, US)
10406 let sz = getfsize(filename)
10407 let fsz = printf("%018d",sz)
10408 let fszpfile= fsz.'/'.pfile
10409 let resultfilelist += [fszpfile]
10410
Bram Moolenaara6878372014-03-22 21:02:50 +010010411 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010412 " sort by name
10413 let resultfilelist += [pfile]
Bram Moolenaara6878372014-03-22 21:02:50 +010010414 endif
Tom Benham64a536d2024-11-07 21:15:03 +010010415 endfor
10416
10417 return resultfilelist
10418endfun
10419
10420" ---------------------------------------------------------------------
10421" s:LocalListing: does the job of "ls" for local directories {{{2
10422fun! s:LocalListing()
10423
10424 let filelist = s:NetrwLocalListingList(b:netrw_curdir, 1)
10425 for filename in filelist
10426 sil! NetrwKeepj put =filename
Bram Moolenaara6878372014-03-22 21:02:50 +010010427 endfor
10428
10429 " cleanup any windows mess at end-of-line
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010430 sil! NetrwKeepj g/^$/d
10431 sil! NetrwKeepj %s/\r$//e
Bram Moolenaara6878372014-03-22 21:02:50 +010010432 call histdel("/",-1)
Bram Moolenaara6878372014-03-22 21:02:50 +010010433 exe "setl ts=".(g:netrw_maxfilenamelen+1)
Bram Moolenaara6878372014-03-22 21:02:50 +010010434endfun
10435
10436" ---------------------------------------------------------------------
Bram Moolenaar97d62492012-11-15 21:28:22 +010010437" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
10438fun! s:NetrwLocalExecute(cmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010439 " call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
Bram Moolenaar97d62492012-11-15 21:28:22 +010010440 let ykeep= @@
10441 " sanity check
10442 if !executable(a:cmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010443 call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
10444 let @@= ykeep
10445 " call Dret("s:NetrwLocalExecute")
10446 return
Bram Moolenaar97d62492012-11-15 21:28:22 +010010447 endif
10448
10449 let optargs= input(":!".a:cmd,"","file")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010450 " call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010451 let result= system(a:cmd.optargs)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010452 " call Decho("result,'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010453
10454 " strip any ansi escape sequences off
10455 let result = substitute(result,"\e\\[[0-9;]*m","","g")
10456
10457 " show user the result(s)
10458 echomsg result
10459 let @@= ykeep
10460
Luca Saccarolac363ca12024-12-19 20:16:18 +010010461 " call Dret("s:NetrwLocalExecute")
Bram Moolenaar97d62492012-11-15 21:28:22 +010010462endfun
10463
10464" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010465" s:NetrwLocalRename: rename a local file or directory {{{2
Bram Moolenaar97d62492012-11-15 21:28:22 +010010466fun! s:NetrwLocalRename(path) range
Bram Moolenaar97d62492012-11-15 21:28:22 +010010467
KSR-Yasudab52e7ac2023-12-12 01:11:43 +090010468 if !exists("w:netrw_bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010469 let w:netrw_bannercnt= b:netrw_bannercnt
KSR-Yasudab52e7ac2023-12-12 01:11:43 +090010470 endif
10471
Bram Moolenaar97d62492012-11-15 21:28:22 +010010472 " preparation for removing multiple files/directories
Bram Moolenaar29634562020-01-09 21:46:04 +010010473 let ykeep = @@
10474 let ctr = a:firstline
10475 let svpos = winsaveview()
10476 let all = 0
Bram Moolenaar97d62492012-11-15 21:28:22 +010010477
10478 " rename files given by the markfilelist
10479 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010480 for oldname in s:netrwmarkfilelist_{bufnr("%")}
10481 if exists("subfrom")
10482 let newname= substitute(oldname,subfrom,subto,'')
10483 else
10484 call inputsave()
10485 let newname= input("Moving ".oldname." to : ",oldname,"file")
10486 call inputrestore()
10487 if newname =~ ''
10488 " two ctrl-x's : ignore all of string preceding the ctrl-x's
10489 let newname = substitute(newname,'^.*','','')
10490 elseif newname =~ ''
10491 " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
10492 let newname = substitute(newname,'[^/]*','','')
10493 endif
10494 if newname =~ '^s/'
10495 let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10496 let subto = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10497 let newname = substitute(oldname,subfrom,subto,'')
10498 endif
10499 endif
10500 if !all && filereadable(newname)
10501 call inputsave()
10502 let response= input("File<".newname."> already exists; do you want to overwrite it? (y/all/n) ")
10503 call inputrestore()
10504 if response == "all"
10505 let all= 1
10506 elseif response != "y" && response != "yes"
10507 " refresh the directory
10508 NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
10509 NetrwKeepj call winrestview(svpos)
10510 let @@= ykeep
10511 return
10512 endif
10513 endif
10514 call rename(oldname,newname)
10515 endfor
10516 call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010517
Bram Moolenaar97d62492012-11-15 21:28:22 +010010518 else
10519
Luca Saccarolac363ca12024-12-19 20:16:18 +010010520 " attempt to rename files/directories
10521 while ctr <= a:lastline
10522 exe "NetrwKeepj ".ctr
Bram Moolenaar97d62492012-11-15 21:28:22 +010010523
Luca Saccarolac363ca12024-12-19 20:16:18 +010010524 " sanity checks
10525 if line(".") < w:netrw_bannercnt
10526 let ctr= ctr + 1
10527 continue
10528 endif
10529 let curword= s:NetrwGetWord()
10530 if curword == "./" || curword == "../"
10531 let ctr= ctr + 1
10532 continue
10533 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010534
Luca Saccarolac363ca12024-12-19 20:16:18 +010010535 NetrwKeepj norm! 0
10536 let oldname= s:ComposePath(a:path,curword)
Bram Moolenaar97d62492012-11-15 21:28:22 +010010537
Luca Saccarolac363ca12024-12-19 20:16:18 +010010538 call inputsave()
10539 let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
10540 call inputrestore()
Bram Moolenaar97d62492012-11-15 21:28:22 +010010541
Luca Saccarolac363ca12024-12-19 20:16:18 +010010542 call rename(oldname,newname)
10543 let ctr= ctr + 1
10544 endwhile
Bram Moolenaar97d62492012-11-15 21:28:22 +010010545 endif
10546
10547 " refresh the directory
Tom Benham64a536d2024-11-07 21:15:03 +010010548 NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010010549 NetrwKeepj call winrestview(svpos)
Bram Moolenaar97d62492012-11-15 21:28:22 +010010550 let @@= ykeep
Bram Moolenaar97d62492012-11-15 21:28:22 +010010551endfun
10552
10553" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000010554" s:NetrwLocalRm: {{{2
10555fun! s:NetrwLocalRm(path) range
KSR-Yasudab52e7ac2023-12-12 01:11:43 +090010556 if !exists("w:netrw_bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010557 let w:netrw_bannercnt= b:netrw_bannercnt
KSR-Yasudab52e7ac2023-12-12 01:11:43 +090010558 endif
10559
Bram Moolenaar446cb832008-06-24 21:56:24 +000010560 " preparation for removing multiple files/directories
Bram Moolenaar97d62492012-11-15 21:28:22 +010010561 let ykeep = @@
Bram Moolenaar446cb832008-06-24 21:56:24 +000010562 let ret = 0
10563 let all = 0
Bram Moolenaare0fa3742016-02-20 15:47:01 +010010564 let svpos = winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +000010565
10566 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010567 " remove all marked files
10568 for fname in s:netrwmarkfilelist_{bufnr("%")}
10569 let ok= s:NetrwLocalRmFile(a:path,fname,all)
10570 if ok =~# 'q\%[uit]' || ok == "no"
10571 break
10572 elseif ok =~# '^a\%[ll]$'
10573 let all= 1
10574 endif
10575 endfor
10576 call s:NetrwUnMarkFile(1)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010577
10578 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010579 " remove (multiple) files and directories
Bram Moolenaar446cb832008-06-24 21:56:24 +000010580
Luca Saccarolac363ca12024-12-19 20:16:18 +010010581 let keepsol= &l:sol
10582 setl nosol
10583 let ctr = a:firstline
10584 while ctr <= a:lastline
10585 exe "NetrwKeepj ".ctr
Bram Moolenaar446cb832008-06-24 21:56:24 +000010586
Luca Saccarolac363ca12024-12-19 20:16:18 +010010587 " sanity checks
10588 if line(".") < w:netrw_bannercnt
10589 let ctr= ctr + 1
10590 continue
10591 endif
10592 let curword= s:NetrwGetWord()
10593 if curword == "./" || curword == "../"
10594 let ctr= ctr + 1
10595 continue
10596 endif
10597 let ok= s:NetrwLocalRmFile(a:path,curword,all)
10598 if ok =~# 'q\%[uit]' || ok == "no"
10599 break
10600 elseif ok =~# '^a\%[ll]$'
10601 let all= 1
10602 endif
10603 let ctr= ctr + 1
10604 endwhile
10605 let &l:sol= keepsol
Bram Moolenaar446cb832008-06-24 21:56:24 +000010606 endif
10607
10608 " refresh the directory
Bram Moolenaar446cb832008-06-24 21:56:24 +000010609 if bufname("%") != "NetrwMessage"
Luca Saccarolac363ca12024-12-19 20:16:18 +010010610 NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
10611 NetrwKeepj call winrestview(svpos)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010612 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010613 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +000010614endfun
10615
10616" ---------------------------------------------------------------------
10617" s:NetrwLocalRmFile: remove file fname given the path {{{2
10618" Give confirmation prompt unless all==1
10619fun! s:NetrwLocalRmFile(path,fname,all)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010620 " call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010621
Bram Moolenaar446cb832008-06-24 21:56:24 +000010622 let all= a:all
10623 let ok = ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010624 NetrwKeepj norm! 0
Christian Brabandt581d4a72024-07-23 21:14:06 +020010625 let rmfile= s:NetrwFile(s:ComposePath(a:path,escape(a:fname, '\\')))
Luca Saccarolac363ca12024-12-19 20:16:18 +010010626 " call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010627
10628 if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
Luca Saccarolac363ca12024-12-19 20:16:18 +010010629 " attempt to remove file
10630 " call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
10631 if !all
10632 echohl Statement
10633 call inputsave()
10634 let ok= input("Confirm deletion of file <".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10635 call inputrestore()
10636 echohl NONE
10637 if ok == ""
10638 let ok="no"
10639 endif
10640 " call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
10641 let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10642 " call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
10643 if ok =~# '^a\%[ll]$'
10644 let all= 1
10645 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010646 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010647
Luca Saccarolac363ca12024-12-19 20:16:18 +010010648 if all || ok =~# '^y\%[es]$' || ok == ""
10649 let ret= s:NetrwDelete(rmfile)
10650 " call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
10651 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010652
10653 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010654 " attempt to remove directory
10655 if !all
10656 echohl Statement
10657 call inputsave()
10658 let ok= input("Confirm *recursive* deletion of directory <".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10659 call inputrestore()
10660 let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10661 if ok == ""
10662 let ok="no"
10663 endif
10664 if ok =~# '^a\%[ll]$'
10665 let all= 1
10666 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010667 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010668 let rmfile= substitute(rmfile,'[\/]$','','e')
Bram Moolenaar446cb832008-06-24 21:56:24 +000010669
Luca Saccarolac363ca12024-12-19 20:16:18 +010010670 if all || ok =~# '^y\%[es]$' || ok == ""
10671 if delete(rmfile,"rf")
10672 call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
10673 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010674 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010675 endif
10676
Luca Saccarolac363ca12024-12-19 20:16:18 +010010677 " call Dret("s:NetrwLocalRmFile ".ok)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010678 return ok
10679endfun
10680
Bram Moolenaar85850f32019-07-19 22:05:51 +020010681" =====================================================================
Bram Moolenaar9964e462007-05-05 17:54:07 +000010682" Support Functions: {{{1
10683
Bram Moolenaar488c6512005-08-11 20:09:58 +000010684" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +010010685" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
10686" 0: marked file list of current buffer
10687" 1: marked file target
10688fun! netrw#Access(ilist)
10689 if a:ilist == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +010010690 if exists("s:netrwmarkfilelist_".bufnr('%'))
10691 return s:netrwmarkfilelist_{bufnr('%')}
10692 else
10693 return "no-list-buf#".bufnr('%')
10694 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010010695 elseif a:ilist == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010010696 return s:netrwmftgt
Bram Moolenaar85850f32019-07-19 22:05:51 +020010697 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010010698endfun
10699
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010700" ---------------------------------------------------------------------
10701" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
10702fun! netrw#Call(funcname,...)
Bram Moolenaar85850f32019-07-19 22:05:51 +020010703 return call("s:".a:funcname,a:000)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010704endfun
10705
Bram Moolenaara6878372014-03-22 21:02:50 +010010706" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010707" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
10708" I expect this function to be used in
10709" :PChkAssert netrw#Expose("netrwmarkfilelist")
10710" for example.
10711fun! netrw#Expose(varname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010712 " call Dfunc("netrw#Expose(varname<".a:varname.">)")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020010713 if exists("s:".a:varname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010714 exe "let retval= s:".a:varname
10715 " call Decho("retval=".retval,'~'.expand("<slnum>"))
10716 if exists("g:netrw_pchk")
10717 " call Decho("type(g:netrw_pchk=".g:netrw_pchk.")=".type(retval),'~'.expand("<slnum>"))
10718 if type(retval) == 3
10719 let retval = copy(retval)
10720 let i = 0
10721 while i < len(retval)
10722 let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
10723 let i = i + 1
10724 endwhile
10725 endif
10726 " call Dret("netrw#Expose ".string(retval)),'~'.expand("<slnum>"))
10727 return string(retval)
10728 else
10729 " call Decho("g:netrw_pchk doesn't exist",'~'.expand("<slnum>"))
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020010730 endif
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020010731 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010732 " call Decho("s:".a:varname." doesn't exist",'~'.expand("<slnum>"))
10733 let retval= "n/a"
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010734 endif
10735
Luca Saccarolac363ca12024-12-19 20:16:18 +010010736 " call Dret("netrw#Expose ".string(retval))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010737 return retval
10738endfun
10739
10740" ---------------------------------------------------------------------
10741" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
10742fun! netrw#Modify(varname,newvalue)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010743 " call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010744 exe "let s:".a:varname."= ".string(a:newvalue)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010745 " call Dret("netrw#Modify")
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010746endfun
10747
10748" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +010010749" netrw#RFC2396: converts %xx into characters {{{2
10750fun! netrw#RFC2396(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010751 " call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
K.Takata23577652024-01-13 01:30:01 +090010752 let fname = escape(substitute(a:fname,'%\(\x\x\)','\=printf("%c","0x".submatch(1))','ge')," \t")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010753 " call Dret("netrw#RFC2396 ".fname)
Bram Moolenaara6878372014-03-22 21:02:50 +010010754 return fname
10755endfun
10756
10757" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010758" netrw#UserMaps: supports user-specified maps {{{2
10759" see :help function()
10760"
10761" g:Netrw_UserMaps is a List with members such as:
10762" [[keymap sequence, function reference],...]
10763"
10764" The referenced function may return a string,
Luca Saccarolac363ca12024-12-19 20:16:18 +010010765" refresh : refresh the display
10766" -other- : this string will be executed
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010767" or it may return a List of strings.
10768"
10769" Each keymap-sequence will be set up with a nnoremap
Bram Moolenaar85850f32019-07-19 22:05:51 +020010770" to invoke netrw#UserMaps(a:islocal).
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010771" Related functions:
10772" netrw#Expose(varname) -- see s:varname variables
10773" netrw#Modify(varname,newvalue) -- modify value of s:varname variable
10774" netrw#Call(funcname,...) -- call internal netrw function with optional arguments
10775fun! netrw#UserMaps(islocal)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010776 " call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
10777 " call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010778
Luca Saccarolac363ca12024-12-19 20:16:18 +010010779 " set up usermaplist
10780 if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
10781 " call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010782 for umap in g:Netrw_UserMaps
Luca Saccarolac363ca12024-12-19 20:16:18 +010010783 " call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
10784 " call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
10785 " if umap[0] is a string and umap[1] is a string holding a function name
10786 if type(umap[0]) == 1 && type(umap[1]) == 1
10787 " call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
10788 exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010789 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010790 call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
10791 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010792 endfor
Luca Saccarolac363ca12024-12-19 20:16:18 +010010793 endif
10794 " call Dret("netrw#UserMaps")
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010795endfun
10796
10797" ---------------------------------------------------------------------
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010798" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
10799fun! netrw#WinPath(path)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010800 " call Dfunc("netrw#WinPath(path<".a:path.">)")
Nir Lichtman1e34b952024-05-08 19:19:34 +020010801 if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010802 " remove cygdrive prefix, if present
10803 let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
10804 " remove trailing slash (Win95)
10805 let path = substitute(path, '\(\\\|/\)$', '', 'g')
10806 " remove escaped spaces
10807 let path = substitute(path, '\ ', ' ', 'g')
10808 " convert slashes to backslashes
10809 let path = substitute(path, '/', '\', 'g')
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010810 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010811 let path= a:path
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010812 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010813 " call Dret("netrw#WinPath <".path.">")
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010814 return path
10815endfun
10816
10817" ---------------------------------------------------------------------
Travis Sheltone34d0e32024-07-30 21:08:56 +020010818" s:StripTrailingSlash: removes trailing slashes from a path {{{2
10819fun! s:StripTrailingSlash(path)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010820 " remove trailing slash
10821 return substitute(a:path, '[/\\]$', '', 'g')
Travis Sheltone34d0e32024-07-30 21:08:56 +020010822endfun
10823
Travis Sheltone34d0e32024-07-30 21:08:56 +020010824" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +020010825" s:NetrwBadd: adds marked files to buffer list or vice versa {{{2
10826" cb : bl2mf=0 add marked files to buffer list
10827" cB : bl2mf=1 use bufferlist to mark files
10828" (mnemonic: cb = copy (marked files) to buffer list)
10829fun! s:NetrwBadd(islocal,bl2mf)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010830 " " call Dfunc("s:NetrwBadd(islocal=".a:islocal." mf2bl=".mf2bl.")")
Bram Moolenaar85850f32019-07-19 22:05:51 +020010831 if a:bl2mf
Luca Saccarolac363ca12024-12-19 20:16:18 +010010832 " cB: add buffer list to marked files
10833 redir => bufl
Bram Moolenaar85850f32019-07-19 22:05:51 +020010834 ls
Luca Saccarolac363ca12024-12-19 20:16:18 +010010835 redir END
10836 let bufl = map(split(bufl,"\n"),'substitute(v:val,''^.\{-}"\(.*\)".\{-}$'',''\1'','''')')
10837 for fname in bufl
10838 call s:NetrwMarkFile(a:islocal,fname)
10839 endfor
Bram Moolenaar85850f32019-07-19 22:05:51 +020010840 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010841 " cb: add marked files to buffer list
10842 for fname in s:netrwmarkfilelist_{bufnr("%")}
10843 " " call Decho("badd ".fname,'~'.expand("<slnum>"))
10844 exe "badd ".fnameescape(fname)
10845 endfor
10846 let curbufnr = bufnr("%")
10847 let curdir = s:NetrwGetCurdir(a:islocal)
10848 call s:NetrwUnmarkList(curbufnr,curdir) " remove markings from local buffer
Bram Moolenaar85850f32019-07-19 22:05:51 +020010849 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010850 " call Dret("s:NetrwBadd")
Bram Moolenaar85850f32019-07-19 22:05:51 +020010851endfun
10852
10853" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000010854" s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
10855fun! s:ComposePath(base,subdir)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010856 " call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
Bram Moolenaarc236c162008-07-13 17:41:49 +000010857
Bram Moolenaar5b435d62012-04-05 17:33:26 +020010858 if has("amiga")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010859 " call Decho("amiga",'~'.expand("<slnum>"))
10860 let ec = a:base[s:Strlen(a:base)-1]
10861 if ec != '/' && ec != ':'
10862 let ret = a:base."/" . a:subdir
10863 else
10864 let ret = a:base.a:subdir
10865 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +000010866
Luca Saccarolac363ca12024-12-19 20:16:18 +010010867 " COMBAK: test on windows with changing to root directory: :e C:/
Nir Lichtman1e34b952024-05-08 19:19:34 +020010868 elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010869 " call Decho("windows",'~'.expand("<slnum>"))
10870 let ret= a:subdir
Bram Moolenaarc236c162008-07-13 17:41:49 +000010871
Nir Lichtman1e34b952024-05-08 19:19:34 +020010872 elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010873 " call Decho("windows",'~'.expand("<slnum>"))
10874 if a:base =~ '[/\\]$'
10875 let ret= a:base.a:subdir
10876 else
10877 let ret= a:base.'/'.a:subdir
10878 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010010879
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010880 elseif a:base =~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +010010881 " call Decho("remote linux/macos",'~'.expand("<slnum>"))
10882 let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
10883 let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
10884 if a:subdir == '../'
10885 if curpath =~ '[^/]/[^/]\+/$'
10886 let curpath= substitute(curpath,'[^/]\+/$','','')
10887 else
10888 let curpath=""
10889 endif
10890 let ret= urlbase.curpath
Bram Moolenaarc236c162008-07-13 17:41:49 +000010891 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010892 let ret= urlbase.curpath.a:subdir
Bram Moolenaarc236c162008-07-13 17:41:49 +000010893 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010894 " call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
10895 " call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
10896 " call Decho("ret<".ret.">",'~'.expand("<slnum>"))
Bram Moolenaarc236c162008-07-13 17:41:49 +000010897
10898 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010899 " call Decho("local linux/macos",'~'.expand("<slnum>"))
10900 let ret = substitute(a:base."/".a:subdir,"//","/","g")
10901 if a:base =~ '^//'
10902 " keeping initial '//' for the benefit of network share listing support
10903 let ret= '/'.ret
10904 endif
10905 let ret= simplify(ret)
Bram Moolenaarc236c162008-07-13 17:41:49 +000010906 endif
10907
Luca Saccarolac363ca12024-12-19 20:16:18 +010010908 " call Dret("s:ComposePath ".ret)
Bram Moolenaarc236c162008-07-13 17:41:49 +000010909 return ret
10910endfun
10911
10912" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010913" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
10914" Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
10915fun! s:DeleteBookmark(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010916 " call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010917 call s:MergeBookmarks()
10918
10919 if exists("g:netrw_bookmarklist")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010920 let indx= index(g:netrw_bookmarklist,a:fname)
10921 if indx == -1
10922 let indx= 0
10923 while indx < len(g:netrw_bookmarklist)
10924 if g:netrw_bookmarklist[indx] =~ a:fname
10925 call remove(g:netrw_bookmarklist,indx)
10926 let indx= indx - 1
10927 endif
10928 let indx= indx + 1
10929 endwhile
10930 else
10931 " remove exact match
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010932 call remove(g:netrw_bookmarklist,indx)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010933 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010934 endif
10935
Luca Saccarolac363ca12024-12-19 20:16:18 +010010936 " call Dret("s:DeleteBookmark")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010937endfun
10938
10939" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000010940" s:FileReadable: o/s independent filereadable {{{2
10941fun! s:FileReadable(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010942 " call Dfunc("s:FileReadable(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +000010943
10944 if g:netrw_cygwin
Luca Saccarolac363ca12024-12-19 20:16:18 +010010945 let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
Bram Moolenaar9964e462007-05-05 17:54:07 +000010946 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010947 let ret= filereadable(s:NetrwFile(a:fname))
Bram Moolenaar9964e462007-05-05 17:54:07 +000010948 endif
10949
Luca Saccarolac363ca12024-12-19 20:16:18 +010010950 " call Dret("s:FileReadable ".ret)
Bram Moolenaar9964e462007-05-05 17:54:07 +000010951 return ret
10952endfun
10953
10954" ---------------------------------------------------------------------
10955" s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
10956" Places correct suffix on end of temporary filename,
10957" using the suffix provided with fname
10958fun! s:GetTempfile(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010959 " call Dfunc("s:GetTempfile(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +000010960
10961 if !exists("b:netrw_tmpfile")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010962 " get a brand new temporary filename
10963 let tmpfile= tempname()
10964 " call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010965
Luca Saccarolac363ca12024-12-19 20:16:18 +010010966 let tmpfile= substitute(tmpfile,'\','/','ge')
10967 " call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010968
Luca Saccarolac363ca12024-12-19 20:16:18 +010010969 " sanity check -- does the temporary file's directory exist?
10970 if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
10971 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10972 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
10973 " call Dret("s:GetTempfile getcwd<".getcwd().">")
10974 return ""
Bram Moolenaar446cb832008-06-24 21:56:24 +000010975 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010976
10977 " let netrw#NetSource() know about the tmpfile
10978 let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
10979 " call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
10980
10981 " o/s dependencies
10982 if g:netrw_cygwin != 0
10983 let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
10984 elseif has("win32")
10985 if !exists("+shellslash") || !&ssl
10986 let tmpfile = substitute(tmpfile,'/','\','g')
10987 endif
10988 else
10989 let tmpfile = tmpfile
10990 endif
10991 let b:netrw_tmpfile= tmpfile
10992 " call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000010993 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010994 " re-use temporary filename
10995 let tmpfile= b:netrw_tmpfile
10996 " call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000010997 endif
10998
10999 " use fname's suffix for the temporary file
11000 if a:fname != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011001 if a:fname =~ '\.[^./]\+$'
11002 " call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11003 if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11004 let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11005 elseif a:fname =~ '.txz$'
11006 let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11007 else
11008 let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11009 endif
11010 " call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11011 let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11012 " call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11013 let tmpfile .= suffix
11014 " call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11015 let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
Bram Moolenaar9964e462007-05-05 17:54:07 +000011016 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011017 endif
11018
Luca Saccarolac363ca12024-12-19 20:16:18 +010011019 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11020 " call Dret("s:GetTempfile <".tmpfile.">")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011021 return tmpfile
Bram Moolenaar446cb832008-06-24 21:56:24 +000011022endfun
Bram Moolenaar9964e462007-05-05 17:54:07 +000011023
11024" ---------------------------------------------------------------------
11025" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
Bram Moolenaarc236c162008-07-13 17:41:49 +000011026" a correct command for use with a system() call
Bram Moolenaar9964e462007-05-05 17:54:07 +000011027fun! s:MakeSshCmd(sshcmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011028 " call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
Bram Moolenaar13600302014-05-22 18:26:40 +020011029 if s:user == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011030 let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
Bram Moolenaar13600302014-05-22 18:26:40 +020011031 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011032 let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
Bram Moolenaar13600302014-05-22 18:26:40 +020011033 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011034 if exists("g:netrw_port") && g:netrw_port != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011035 let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
Bram Moolenaar9964e462007-05-05 17:54:07 +000011036 elseif exists("s:port") && s:port != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011037 let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
Bram Moolenaar9964e462007-05-05 17:54:07 +000011038 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011039 let sshcmd= substitute(sshcmd,"USEPORT ",'','')
Bram Moolenaar9964e462007-05-05 17:54:07 +000011040 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011041 " call Dret("s:MakeSshCmd <".sshcmd.">")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011042 return sshcmd
11043endfun
11044
11045" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011046" s:MakeBookmark: enters a bookmark into Netrw's bookmark system {{{2
11047fun! s:MakeBookmark(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011048 " call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011049
11050 if !exists("g:netrw_bookmarklist")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011051 let g:netrw_bookmarklist= []
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011052 endif
11053
11054 if index(g:netrw_bookmarklist,a:fname) == -1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011055 " curdir not currently in g:netrw_bookmarklist, so include it
11056 if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11057 call add(g:netrw_bookmarklist,a:fname.'/')
11058 elseif a:fname !~ '/'
11059 call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11060 else
11061 call add(g:netrw_bookmarklist,a:fname)
11062 endif
11063 call sort(g:netrw_bookmarklist)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011064 endif
11065
Luca Saccarolac363ca12024-12-19 20:16:18 +010011066 " call Dret("s:MakeBookmark")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011067endfun
11068
11069" ---------------------------------------------------------------------
11070" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11071fun! s:MergeBookmarks()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011072 " call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011073 " get bookmarks from .netrwbook file
11074 let savefile= s:NetrwHome()."/.netrwbook"
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011075 if filereadable(s:NetrwFile(savefile))
Luca Saccarolac363ca12024-12-19 20:16:18 +010011076 " call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11077 NetrwKeepj call s:NetrwBookHistSave()
11078 " call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11079 NetrwKeepj call delete(savefile)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011080 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011081 " call Dret("s:MergeBookmarks")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011082endfun
11083
11084" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011085" s:NetrwBMShow: {{{2
11086fun! s:NetrwBMShow()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011087 " call Dfunc("s:NetrwBMShow()")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011088 redir => bmshowraw
Luca Saccarolac363ca12024-12-19 20:16:18 +010011089 menu
Bram Moolenaarc236c162008-07-13 17:41:49 +000011090 redir END
11091 let bmshowlist = split(bmshowraw,'\n')
11092 if bmshowlist != []
Luca Saccarolac363ca12024-12-19 20:16:18 +010011093 let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"')
11094 if bmshowfuncs != []
11095 let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11096 if bmshowfunc =~# '^call.*BMShow()'
11097 exe "sil! NetrwKeepj ".bmshowfunc
11098 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +000011099 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000011100 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011101 " call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011102endfun
11103
11104" ---------------------------------------------------------------------
Bram Moolenaaradc21822011-04-01 18:03:16 +020011105" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011106fun! s:NetrwCursor(editfile)
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011107 if !exists("w:netrw_liststyle")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011108 let w:netrw_liststyle= g:netrw_liststyle
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011109 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011110 " call Dfunc("s:NetrwCursor() ft<".&ft."> liststyle=".w:netrw_liststyle." g:netrw_cursor=".g:netrw_cursor." s:netrw_usercuc=".s:netrw_usercuc." s:netrw_usercul=".s:netrw_usercul)
Bram Moolenaaradc21822011-04-01 18:03:16 +020011111
Luca Saccarolac363ca12024-12-19 20:16:18 +010011112 " call Decho("(s:NetrwCursor) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011113
Bram Moolenaaradc21822011-04-01 18:03:16 +020011114 if &ft != "netrw"
Luca Saccarolac363ca12024-12-19 20:16:18 +010011115 " if the current window isn't a netrw directory listing window, then use user cursorline/column
11116 " settings. Affects when netrw is used to read/write a file using scp/ftp/etc.
11117 " call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
Bram Moolenaaradc21822011-04-01 18:03:16 +020011118
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011119 elseif g:netrw_cursor == 8
Luca Saccarolac363ca12024-12-19 20:16:18 +010011120 if w:netrw_liststyle == s:WIDELIST
11121 setl cursorline
11122 setl cursorcolumn
11123 else
11124 setl cursorline
11125 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011126 elseif g:netrw_cursor == 7
11127 setl cursorline
11128 elseif g:netrw_cursor == 6
Luca Saccarolac363ca12024-12-19 20:16:18 +010011129 if w:netrw_liststyle == s:WIDELIST
11130 setl cursorline
11131 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +020011132 elseif g:netrw_cursor == 4
Luca Saccarolac363ca12024-12-19 20:16:18 +010011133 " all styles: cursorline, cursorcolumn
11134 " call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
Bram Moolenaar15146672011-10-20 22:22:38 +020011135 setl cursorline
11136 setl cursorcolumn
Luca Saccarolac363ca12024-12-19 20:16:18 +010011137
11138 elseif g:netrw_cursor == 3
11139 " thin-long-tree: cursorline, user's cursorcolumn
11140 " wide : cursorline, cursorcolumn
11141 if w:netrw_liststyle == s:WIDELIST
11142 " call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11143 setl cursorline
11144 setl cursorcolumn
11145 else
11146 " call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11147 setl cursorline
11148 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +020011149
11150 elseif g:netrw_cursor == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +010011151 " thin-long-tree: cursorline, user's cursorcolumn
11152 " wide : cursorline, user's cursorcolumn
11153 " call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11154 setl cursorline
Bram Moolenaaradc21822011-04-01 18:03:16 +020011155
11156 elseif g:netrw_cursor == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011157 " thin-long-tree: user's cursorline, user's cursorcolumn
11158 " wide : cursorline, user's cursorcolumn
11159 if w:netrw_liststyle == s:WIDELIST
11160 " call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11161 setl cursorline
11162 else
11163 " call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11164 endif
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011165
11166 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011167 " all styles: user's cursorline, user's cursorcolumn
11168 " call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11169 let &l:cursorline = s:netrw_usercul
11170 let &l:cursorcolumn = s:netrw_usercuc
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011171 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +020011172
Luca Saccarolac363ca12024-12-19 20:16:18 +010011173 " call Decho("(s:NetrwCursor) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11174 " call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011175endfun
11176
11177" ---------------------------------------------------------------------
11178" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11179fun! s:RestoreCursorline()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011180 " call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
Bram Moolenaaradc21822011-04-01 18:03:16 +020011181 if exists("s:netrw_usercul")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011182 let &l:cursorline = s:netrw_usercul
Bram Moolenaaradc21822011-04-01 18:03:16 +020011183 endif
11184 if exists("s:netrw_usercuc")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011185 let &l:cursorcolumn = s:netrw_usercuc
Bram Moolenaaradc21822011-04-01 18:03:16 +020011186 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011187 " call Decho("(s:RestoreCursorline) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11188 " call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011189endfun
11190
Christian Brabandt62f7b552024-06-23 20:23:40 +020011191" s:RestoreRegister: restores all registers given in the dict {{{2
11192fun! s:RestoreRegister(dict)
11193 for [key, val] in items(a:dict)
11194 if key == 'unnamed'
11195 let key = ''
11196 endif
11197 call setreg(key, val[0], val[1])
11198 endfor
11199endfun
11200
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011201" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011202" s:NetrwDelete: Deletes a file. {{{2
11203" Uses Steve Hall's idea to insure that Windows paths stay
11204" acceptable. No effect on Unix paths.
11205" Examples of use: let result= s:NetrwDelete(path)
11206fun! s:NetrwDelete(path)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011207 " call Dfunc("s:NetrwDelete(path<".a:path.">)")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011208
Bram Moolenaar5c736222010-01-06 20:54:52 +010011209 let path = netrw#WinPath(a:path)
Nir Lichtman1e34b952024-05-08 19:19:34 +020011210 if !g:netrw_cygwin && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011211 if exists("+shellslash")
11212 let sskeep= &shellslash
11213 setl noshellslash
11214 let result = delete(path)
11215 let &shellslash = sskeep
11216 else
11217 " call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11218 let result= delete(path)
11219 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +000011220 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011221 " call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11222 let result= delete(path)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011223 endif
11224 if result < 0
Luca Saccarolac363ca12024-12-19 20:16:18 +010011225 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011226 endif
11227
Luca Saccarolac363ca12024-12-19 20:16:18 +010011228 " call Dret("s:NetrwDelete ".result)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011229 return result
Bram Moolenaar446cb832008-06-24 21:56:24 +000011230endfun
11231
11232" ---------------------------------------------------------------------
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011233" s:NetrwBufRemover: removes a buffer that: {{{2s
11234" has buffer-id > 1
11235" is unlisted
11236" is unnamed
11237" does not appear in any window
11238fun! s:NetrwBufRemover(bufid)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011239 " call Dfunc("s:NetrwBufRemover(".a:bufid.")")
11240 " call Decho("buf#".a:bufid." ".((a:bufid > 1)? ">" : "≯")." must be >1 for removal","~".expand("<slnum>"))
11241 " call Decho("buf#".a:bufid." is ".(buflisted(a:bufid)? "listed" : "unlisted"),"~".expand("<slnum>"))
11242 " call Decho("buf#".a:bufid." has name <".bufname(a:bufid).">","~".expand("<slnum>"))
11243 " call Decho("buf#".a:bufid." has winid#".bufwinid(a:bufid),"~".expand("<slnum>"))
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011244
yasuda4dbb2662023-10-04 20:50:35 +020011245 if a:bufid > 1 && !buflisted(a:bufid) && bufloaded(a:bufid) && bufname(a:bufid) == "" && bufwinid(a:bufid) == -1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011246 " call Decho("(s:NetrwBufRemover) removing buffer#".a:bufid,"~".expand("<slnum>"))
11247 exe "sil! bd! ".a:bufid
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011248 endif
11249
Luca Saccarolac363ca12024-12-19 20:16:18 +010011250 " call Dret("s:NetrwBufRemover")
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011251endfun
11252
11253" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000011254" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +010011255fun! s:NetrwEnew(...)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011256 " call Dfunc("s:NetrwEnew() a:0=".a:0." win#".winnr()." winnr($)=".winnr("$")." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
11257 " call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011258
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +010011259 " Clean out the last buffer:
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011260 " Check if the last buffer has # > 1, is unlisted, is unnamed, and does not appear in a window
11261 " If so, delete it.
11262 call s:NetrwBufRemover(bufnr("$"))
11263
Bram Moolenaar446cb832008-06-24 21:56:24 +000011264 " grab a function-local-variable copy of buffer variables
Luca Saccarolac363ca12024-12-19 20:16:18 +010011265 " call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011266 if exists("b:netrw_bannercnt") |let netrw_bannercnt = b:netrw_bannercnt |endif
11267 if exists("b:netrw_browser_active") |let netrw_browser_active = b:netrw_browser_active |endif
11268 if exists("b:netrw_cpf") |let netrw_cpf = b:netrw_cpf |endif
11269 if exists("b:netrw_curdir") |let netrw_curdir = b:netrw_curdir |endif
11270 if exists("b:netrw_explore_bufnr") |let netrw_explore_bufnr = b:netrw_explore_bufnr |endif
11271 if exists("b:netrw_explore_indx") |let netrw_explore_indx = b:netrw_explore_indx |endif
11272 if exists("b:netrw_explore_line") |let netrw_explore_line = b:netrw_explore_line |endif
11273 if exists("b:netrw_explore_list") |let netrw_explore_list = b:netrw_explore_list |endif
11274 if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11275 if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11276 if exists("b:netrw_fname") |let netrw_fname = b:netrw_fname |endif
11277 if exists("b:netrw_lastfile") |let netrw_lastfile = b:netrw_lastfile |endif
11278 if exists("b:netrw_liststyle") |let netrw_liststyle = b:netrw_liststyle |endif
11279 if exists("b:netrw_method") |let netrw_method = b:netrw_method |endif
11280 if exists("b:netrw_option") |let netrw_option = b:netrw_option |endif
11281 if exists("b:netrw_prvdir") |let netrw_prvdir = b:netrw_prvdir |endif
11282
Bram Moolenaar85850f32019-07-19 22:05:51 +020011283 NetrwKeepj call s:NetrwOptionsRestore("w:")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011284 " call Decho("generate a buffer with NetrwKeepj enew!",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011285 " when tree listing uses file TreeListing... a new buffer is made.
11286 " Want the old buffer to be unlisted.
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011287 " COMBAK: this causes a problem, see P43
Luca Saccarolac363ca12024-12-19 20:16:18 +010011288 " setl nobl
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +020011289 let netrw_keepdiff= &l:diff
Bram Moolenaar71badf92023-04-22 22:40:14 +010011290 call s:NetrwEditFile("enew!","","")
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +020011291 let &l:diff= netrw_keepdiff
Luca Saccarolac363ca12024-12-19 20:16:18 +010011292 " call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +020011293 NetrwKeepj call s:NetrwOptionsSave("w:")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011294
Bram Moolenaar446cb832008-06-24 21:56:24 +000011295 " copy function-local-variables to buffer variable equivalents
Luca Saccarolac363ca12024-12-19 20:16:18 +010011296 " call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011297 if exists("netrw_bannercnt") |let b:netrw_bannercnt = netrw_bannercnt |endif
11298 if exists("netrw_browser_active") |let b:netrw_browser_active = netrw_browser_active |endif
11299 if exists("netrw_cpf") |let b:netrw_cpf = netrw_cpf |endif
11300 if exists("netrw_curdir") |let b:netrw_curdir = netrw_curdir |endif
11301 if exists("netrw_explore_bufnr") |let b:netrw_explore_bufnr = netrw_explore_bufnr |endif
11302 if exists("netrw_explore_indx") |let b:netrw_explore_indx = netrw_explore_indx |endif
11303 if exists("netrw_explore_line") |let b:netrw_explore_line = netrw_explore_line |endif
11304 if exists("netrw_explore_list") |let b:netrw_explore_list = netrw_explore_list |endif
11305 if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11306 if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11307 if exists("netrw_fname") |let b:netrw_fname = netrw_fname |endif
11308 if exists("netrw_lastfile") |let b:netrw_lastfile = netrw_lastfile |endif
11309 if exists("netrw_liststyle") |let b:netrw_liststyle = netrw_liststyle |endif
11310 if exists("netrw_method") |let b:netrw_method = netrw_method |endif
11311 if exists("netrw_option") |let b:netrw_option = netrw_option |endif
11312 if exists("netrw_prvdir") |let b:netrw_prvdir = netrw_prvdir |endif
11313
Bram Moolenaar5c736222010-01-06 20:54:52 +010011314 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +010011315 let b:netrw_curdir= a:1
11316 if b:netrw_curdir =~ '/$'
11317 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11318 setl nobl
11319 file NetrwTreeListing
11320 setl nobl bt=nowrite bh=hide
11321 nno <silent> <buffer> [ :sil call <SID>TreeListMove('[')<cr>
11322 nno <silent> <buffer> ] :sil call <SID>TreeListMove(']')<cr>
11323 else
11324 call s:NetrwBufRename(b:netrw_curdir)
11325 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010011326 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011327 endif
Bram Moolenaar1d59aa12020-09-19 18:50:13 +020011328 if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011329 let &l:bexpr = "netrw#BalloonHelp()"
Bram Moolenaar1d59aa12020-09-19 18:50:13 +020011330 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011331
Luca Saccarolac363ca12024-12-19 20:16:18 +010011332 " call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011333endfun
11334
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011335" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011336" s:NetrwExe: executes a string using "!" {{{2
11337fun! s:NetrwExe(cmd)
GuyBrushd7745ac2024-11-23 14:13:10 +010011338 if has("win32") && exepath(&shell) !~? '\v[\/]?(cmd|pwsh|powershell)(\.exe)?$' && !g:netrw_cygwin
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011339 let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
11340 set shell& shellcmdflag& shellxquote& shellxescape&
11341 set shellquote& shellpipe& shellredir& shellslash&
Konfekt3d7e5672024-10-27 22:16:49 +010011342 try
Luca Saccarolac363ca12024-12-19 20:16:18 +010011343 exe a:cmd
Konfekt3d7e5672024-10-27 22:16:49 +010011344 finally
11345 let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
11346 endtry
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011347 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011348 exe a:cmd
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011349 endif
Bram Moolenaar29634562020-01-09 21:46:04 +010011350 if v:shell_error
Luca Saccarolac363ca12024-12-19 20:16:18 +010011351 call netrw#ErrorMsg(s:WARNING,"shell signalled an error",106)
Bram Moolenaar29634562020-01-09 21:46:04 +010011352 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011353endfun
11354
11355" ---------------------------------------------------------------------
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011356" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
11357fun! s:NetrwInsureWinVars()
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011358 if !exists("w:netrw_liststyle")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011359 " call Dfunc("s:NetrwInsureWinVars() win#".winnr())
11360 let curbuf = bufnr("%")
11361 let curwin = winnr()
11362 let iwin = 1
11363 while iwin <= winnr("$")
11364 exe iwin."wincmd w"
11365 if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
11366 " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
11367 let winvars= w:
11368 break
11369 endif
11370 let iwin= iwin + 1
11371 endwhile
11372 exe "keepalt ".curwin."wincmd w"
11373 if exists("winvars")
11374 " call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
11375 for k in keys(winvars)
11376 let w:{k}= winvars[k]
11377 endfor
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011378 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011379 " call Dret("s:NetrwInsureWinVars win#".winnr())
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011380 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011381endfun
11382
Bram Moolenaara6878372014-03-22 21:02:50 +010011383" ---------------------------------------------------------------------
11384" s:NetrwLcd: handles changing the (local) directory {{{2
Bram Moolenaar85850f32019-07-19 22:05:51 +020011385" Returns: 0=success
11386" -1=failed
Bram Moolenaara6878372014-03-22 21:02:50 +010011387fun! s:NetrwLcd(newdir)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011388 " call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
11389 " call Decho("changing local directory",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +010011390
Bram Moolenaar85850f32019-07-19 22:05:51 +020011391 let err472= 0
Bram Moolenaara6878372014-03-22 21:02:50 +010011392 try
Luca Saccarolac363ca12024-12-19 20:16:18 +010011393 exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
Bram Moolenaara6878372014-03-22 21:02:50 +010011394 catch /^Vim\%((\a\+)\)\=:E344/
Luca Saccarolac363ca12024-12-19 20:16:18 +010011395 " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
11396 " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
11397 " 'root' (ie. '\'). The share name may start with either backslashes ('\\Foo') or
11398 " forward slashes ('//Foo'), depending on whether backslashes have been converted to
11399 " forward slashes by earlier code; so check for both.
11400 if has("win32") && !g:netrw_cygwin
11401 if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
11402 let dirname = '\'
11403 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
11404 endif
11405 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011406 catch /^Vim\%((\a\+)\)\=:E472/
Luca Saccarolac363ca12024-12-19 20:16:18 +010011407 let err472= 1
Bram Moolenaar85850f32019-07-19 22:05:51 +020011408 endtry
11409
11410 if err472
Luca Saccarolac363ca12024-12-19 20:16:18 +010011411 call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
11412 if exists("w:netrw_prvdir")
11413 let a:newdir= w:netrw_prvdir
11414 else
11415 call s:NetrwOptionsRestore("w:")
11416 " call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
11417 exe "setl ".g:netrw_bufsettings
11418 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11419 let a:newdir= dirname
11420 endif
11421 " call Dret("s:NetrwBrowse -1 : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
11422 return -1
Bram Moolenaar85850f32019-07-19 22:05:51 +020011423 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011424
Luca Saccarolac363ca12024-12-19 20:16:18 +010011425 " call Decho("getcwd <".getcwd().">")
11426 " call Decho("b:netrw_curdir<".b:netrw_curdir.">")
11427 " call Dret("s:NetrwLcd 0")
Bram Moolenaar85850f32019-07-19 22:05:51 +020011428 return 0
Bram Moolenaara6878372014-03-22 21:02:50 +010011429endfun
11430
Bram Moolenaar9964e462007-05-05 17:54:07 +000011431" ------------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011432" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
11433" changed sorting, etc. Also see s:NetrwRestoreWordPosn().
11434fun! s:NetrwSaveWordPosn()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011435 " call Dfunc("NetrwSaveWordPosn()")
Bram Moolenaar446cb832008-06-24 21:56:24 +000011436 let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011437 " call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
Bram Moolenaar446cb832008-06-24 21:56:24 +000011438endfun
11439
11440" ---------------------------------------------------------------------
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011441" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
11442" 1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
11443fun! s:NetrwHumanReadable(sz)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011444 " call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011445
11446 if g:netrw_sizestyle == 'h'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011447 if a:sz >= 1000000000
11448 let sz = printf("%.1f",a:sz/1000000000.0)."g"
11449 elseif a:sz >= 10000000
11450 let sz = printf("%d",a:sz/1000000)."m"
11451 elseif a:sz >= 1000000
11452 let sz = printf("%.1f",a:sz/1000000.0)."m"
11453 elseif a:sz >= 10000
11454 let sz = printf("%d",a:sz/1000)."k"
11455 elseif a:sz >= 1000
11456 let sz = printf("%.1f",a:sz/1000.0)."k"
11457 else
11458 let sz= a:sz
11459 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011460
11461 elseif g:netrw_sizestyle == 'H'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011462 if a:sz >= 1073741824
11463 let sz = printf("%.1f",a:sz/1073741824.0)."G"
11464 elseif a:sz >= 10485760
11465 let sz = printf("%d",a:sz/1048576)."M"
11466 elseif a:sz >= 1048576
11467 let sz = printf("%.1f",a:sz/1048576.0)."M"
11468 elseif a:sz >= 10240
11469 let sz = printf("%d",a:sz/1024)."K"
11470 elseif a:sz >= 1024
11471 let sz = printf("%.1f",a:sz/1024.0)."K"
11472 else
11473 let sz= a:sz
11474 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011475
11476 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011477 let sz= a:sz
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011478 endif
11479
Luca Saccarolac363ca12024-12-19 20:16:18 +010011480 " call Dret("s:NetrwHumanReadable ".sz)
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011481 return sz
11482endfun
11483
11484" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011485" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
11486" changed sorting, etc. Also see s:NetrwSaveWordPosn().
11487fun! s:NetrwRestoreWordPosn()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011488 " call Dfunc("NetrwRestoreWordPosn()")
Bram Moolenaaradc21822011-04-01 18:03:16 +020011489 sil! call search(s:netrw_saveword,'w')
Luca Saccarolac363ca12024-12-19 20:16:18 +010011490 " call Dret("NetrwRestoreWordPosn")
Bram Moolenaar446cb832008-06-24 21:56:24 +000011491endfun
11492
11493" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011494" s:RestoreBufVars: {{{2
11495fun! s:RestoreBufVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011496 " call Dfunc("s:RestoreBufVars()")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011497
11498 if exists("s:netrw_curdir") |let b:netrw_curdir = s:netrw_curdir |endif
11499 if exists("s:netrw_lastfile") |let b:netrw_lastfile = s:netrw_lastfile |endif
11500 if exists("s:netrw_method") |let b:netrw_method = s:netrw_method |endif
11501 if exists("s:netrw_fname") |let b:netrw_fname = s:netrw_fname |endif
11502 if exists("s:netrw_machine") |let b:netrw_machine = s:netrw_machine |endif
11503 if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
11504
Luca Saccarolac363ca12024-12-19 20:16:18 +010011505 " call Dret("s:RestoreBufVars")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011506endfun
11507
11508" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000011509" s:RemotePathAnalysis: {{{2
11510fun! s:RemotePathAnalysis(dirname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011511 " call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011512
Bram Moolenaara6878372014-03-22 21:02:50 +010011513 " method :// user @ machine :port /path
Bram Moolenaar8d043172014-01-23 14:24:41 +010011514 let dirpat = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
Bram Moolenaar9964e462007-05-05 17:54:07 +000011515 let s:method = substitute(a:dirname,dirpat,'\1','')
Bram Moolenaar8d043172014-01-23 14:24:41 +010011516 let s:user = substitute(a:dirname,dirpat,'\3','')
11517 let s:machine = substitute(a:dirname,dirpat,'\4','')
11518 let s:port = substitute(a:dirname,dirpat,'\5','')
11519 let s:path = substitute(a:dirname,dirpat,'\6','')
Bram Moolenaar13600302014-05-22 18:26:40 +020011520 let s:fname = substitute(s:path,'^.*/\ze.','','')
Bram Moolenaara6878372014-03-22 21:02:50 +010011521 if s:machine =~ '@'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011522 let dirpat = '^\(.*\)@\(.\{-}\)$'
11523 let s:user = s:user.'@'.substitute(s:machine,dirpat,'\1','')
11524 let s:machine = substitute(s:machine,dirpat,'\2','')
Bram Moolenaara6878372014-03-22 21:02:50 +010011525 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011526
Luca Saccarolac363ca12024-12-19 20:16:18 +010011527 " call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
11528 " call Decho("set up s:user <".s:user .">",'~'.expand("<slnum>"))
11529 " call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
11530 " call Decho("set up s:port <".s:port.">",'~'.expand("<slnum>"))
11531 " call Decho("set up s:path <".s:path .">",'~'.expand("<slnum>"))
11532 " call Decho("set up s:fname <".s:fname .">",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011533
Luca Saccarolac363ca12024-12-19 20:16:18 +010011534 " call Dret("s:RemotePathAnalysis")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011535endfun
11536
11537" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011538" s:RemoteSystem: runs a command on a remote host using ssh {{{2
11539" Returns status
11540" Runs system() on
11541" [cd REMOTEDIRPATH;] a:cmd
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011542" Note that it doesn't do s:ShellEscape(a:cmd)!
Bram Moolenaarc236c162008-07-13 17:41:49 +000011543fun! s:RemoteSystem(cmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011544 " call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011545 if !executable(g:netrw_ssh_cmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011546 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"g:netrw_ssh_cmd<".g:netrw_ssh_cmd."> is not executable!",52)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011547 elseif !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011548 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011549 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011550 let cmd = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
11551 let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
11552 if remotedir != ""
11553 let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
11554 else
11555 let cmd= cmd.' '
11556 endif
11557 let cmd= cmd.a:cmd
11558 " call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
11559 let ret= system(cmd)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011560 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011561 " call Dret("s:RemoteSystem ".ret)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011562 return ret
Bram Moolenaar9964e462007-05-05 17:54:07 +000011563endfun
11564
11565" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011566" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +000011567fun! s:RestoreWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011568 " call Dfunc("s:RestoreWinVars()")
Bram Moolenaar488c6512005-08-11 20:09:58 +000011569 if exists("s:bannercnt") |let w:netrw_bannercnt = s:bannercnt |unlet s:bannercnt |endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011570 if exists("s:col") |let w:netrw_col = s:col |unlet s:col |endif
11571 if exists("s:curdir") |let w:netrw_curdir = s:curdir |unlet s:curdir |endif
11572 if exists("s:explore_bufnr") |let w:netrw_explore_bufnr = s:explore_bufnr |unlet s:explore_bufnr |endif
11573 if exists("s:explore_indx") |let w:netrw_explore_indx = s:explore_indx |unlet s:explore_indx |endif
11574 if exists("s:explore_line") |let w:netrw_explore_line = s:explore_line |unlet s:explore_line |endif
11575 if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
11576 if exists("s:explore_list") |let w:netrw_explore_list = s:explore_list |unlet s:explore_list |endif
11577 if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
11578 if exists("s:fpl") |let w:netrw_fpl = s:fpl |unlet s:fpl |endif
11579 if exists("s:hline") |let w:netrw_hline = s:hline |unlet s:hline |endif
11580 if exists("s:line") |let w:netrw_line = s:line |unlet s:line |endif
11581 if exists("s:liststyle") |let w:netrw_liststyle = s:liststyle |unlet s:liststyle |endif
Bram Moolenaar488c6512005-08-11 20:09:58 +000011582 if exists("s:method") |let w:netrw_method = s:method |unlet s:method |endif
11583 if exists("s:prvdir") |let w:netrw_prvdir = s:prvdir |unlet s:prvdir |endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011584 if exists("s:treedict") |let w:netrw_treedict = s:treedict |unlet s:treedict |endif
11585 if exists("s:treetop") |let w:netrw_treetop = s:treetop |unlet s:treetop |endif
11586 if exists("s:winnr") |let w:netrw_winnr = s:winnr |unlet s:winnr |endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011587 " call Dret("s:RestoreWinVars")
Bram Moolenaar488c6512005-08-11 20:09:58 +000011588endfun
11589
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011590" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011591" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
11592"
11593" s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
11594" is true) and a command, :Rexplore, which call this function.
11595"
Bram Moolenaar85850f32019-07-19 22:05:51 +020011596" s:netrw_posn is set up by s:NetrwBrowseChgDir()
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011597"
11598" s:rexposn_BUFNR used to save/restore cursor position
Bram Moolenaar446cb832008-06-24 21:56:24 +000011599fun! s:NetrwRexplore(islocal,dirname)
Bram Moolenaarff034192013-04-24 18:51:19 +020011600 if exists("s:netrwdrag")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011601 return
Bram Moolenaarff034192013-04-24 18:51:19 +020011602 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011603 " call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
11604 " call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
11605 " call Decho("ft=".&ft." win#".winnr()." w:netrw_rexfile<".(exists("w:netrw_rexfile")? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +010011606
11607 if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011608 " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
11609 " call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
11610 exe "NetrwKeepj e ".w:netrw_rexfile
11611 unlet w:netrw_rexfile
11612 " call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%")."> (ft=".&ft.")")
11613 return
11614 " else " Decho
11615 " call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
11616 " call Decho("treating as not-netrw-buffer: w:netrw_rexfile<".((exists("w:netrw_rexfile"))? w:netrw_rexfile : 'n/a').">",'~'.expand("<slnum>"))
Bram Moolenaar15146672011-10-20 22:22:38 +020011617 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011618
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011619 " ---------------------------
11620 " :Rex issued while in a file
11621 " ---------------------------
11622
Bram Moolenaara6878372014-03-22 21:02:50 +010011623 " record current file so :Rex can return to it from netrw
11624 let w:netrw_rexfile= expand("%")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011625 " call Decho("set w:netrw_rexfile<".w:netrw_rexfile."> (win#".winnr().")",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +010011626
11627 if !exists("w:netrw_rexlocal")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011628 " call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
11629 return
Bram Moolenaara6878372014-03-22 21:02:50 +010011630 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011631 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
Bram Moolenaaradc21822011-04-01 18:03:16 +020011632 if w:netrw_rexlocal
Luca Saccarolac363ca12024-12-19 20:16:18 +010011633 NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011634 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011635 NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011636 endif
Bram Moolenaar15146672011-10-20 22:22:38 +020011637 if exists("s:initbeval")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011638 setl beval
Bram Moolenaar15146672011-10-20 22:22:38 +020011639 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011640 if exists("s:rexposn_".bufnr("%"))
Luca Saccarolac363ca12024-12-19 20:16:18 +010011641 " call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
11642 " restore position in directory listing
11643 " call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
11644 NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
11645 if exists("s:rexposn_".bufnr('%'))
11646 unlet s:rexposn_{bufnr('%')}
11647 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011648 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011649 " call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000011650 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011651
Bram Moolenaar85850f32019-07-19 22:05:51 +020011652 if has("syntax") && exists("g:syntax_on") && g:syntax_on
Luca Saccarolac363ca12024-12-19 20:16:18 +010011653 if exists("s:explore_match")
11654 exe "2match netrwMarkFile /".s:explore_match."/"
11655 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010011656 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011657
Luca Saccarolac363ca12024-12-19 20:16:18 +010011658 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
11659 " call Dret("s:NetrwRexplore : ft=".&ft)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011660endfun
11661
11662" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +010011663" s:SaveBufVars: save selected b: variables to s: variables {{{2
11664" use s:RestoreBufVars() to restore b: variables from s: variables
Bram Moolenaar9964e462007-05-05 17:54:07 +000011665fun! s:SaveBufVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011666 " call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011667
11668 if exists("b:netrw_curdir") |let s:netrw_curdir = b:netrw_curdir |endif
11669 if exists("b:netrw_lastfile") |let s:netrw_lastfile = b:netrw_lastfile |endif
11670 if exists("b:netrw_method") |let s:netrw_method = b:netrw_method |endif
11671 if exists("b:netrw_fname") |let s:netrw_fname = b:netrw_fname |endif
11672 if exists("b:netrw_machine") |let s:netrw_machine = b:netrw_machine |endif
11673 if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
11674
Luca Saccarolac363ca12024-12-19 20:16:18 +010011675 " call Dret("s:SaveBufVars")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011676endfun
11677
11678" ---------------------------------------------------------------------
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011679" s:SavePosn: saves position associated with current buffer into a dictionary {{{2
11680fun! s:SavePosn(posndict)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011681 " call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011682
Bram Moolenaar85850f32019-07-19 22:05:51 +020011683 if !exists("a:posndict[bufnr('%')]")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011684 let a:posndict[bufnr("%")]= []
Bram Moolenaar85850f32019-07-19 22:05:51 +020011685 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011686 " call Decho("before push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
Bram Moolenaar85850f32019-07-19 22:05:51 +020011687 call add(a:posndict[bufnr("%")],winsaveview())
Luca Saccarolac363ca12024-12-19 20:16:18 +010011688 " call Decho("after push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011689
Luca Saccarolac363ca12024-12-19 20:16:18 +010011690 " call Dret("s:SavePosn posndict")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011691 return a:posndict
11692endfun
11693
11694" ---------------------------------------------------------------------
11695" s:RestorePosn: restores position associated with current buffer using dictionary {{{2
11696fun! s:RestorePosn(posndict)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011697 " call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
Bram Moolenaar85850f32019-07-19 22:05:51 +020011698 if exists("a:posndict")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011699 if has_key(a:posndict,bufnr("%"))
11700 " call Decho("before pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
11701 let posnlen= len(a:posndict[bufnr("%")])
11702 if posnlen > 0
11703 let posnlen= posnlen - 1
11704 " call Decho("restoring posn posndict[".bufnr("%")."][".posnlen."]=".string(a:posndict[bufnr("%")][posnlen]),'~'.expand("<slnum>"))
11705 call winrestview(a:posndict[bufnr("%")][posnlen])
11706 call remove(a:posndict[bufnr("%")],posnlen)
11707 " call Decho("after pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
11708 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +020011709 endif
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011710 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011711 " call Dret("s:RestorePosn")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011712endfun
11713
11714" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011715" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +000011716fun! s:SaveWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011717 " call Dfunc("s:SaveWinVars() win#".winnr())
Bram Moolenaar9964e462007-05-05 17:54:07 +000011718 if exists("w:netrw_bannercnt") |let s:bannercnt = w:netrw_bannercnt |endif
11719 if exists("w:netrw_col") |let s:col = w:netrw_col |endif
11720 if exists("w:netrw_curdir") |let s:curdir = w:netrw_curdir |endif
11721 if exists("w:netrw_explore_bufnr") |let s:explore_bufnr = w:netrw_explore_bufnr |endif
11722 if exists("w:netrw_explore_indx") |let s:explore_indx = w:netrw_explore_indx |endif
11723 if exists("w:netrw_explore_line") |let s:explore_line = w:netrw_explore_line |endif
11724 if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
11725 if exists("w:netrw_explore_list") |let s:explore_list = w:netrw_explore_list |endif
11726 if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
11727 if exists("w:netrw_fpl") |let s:fpl = w:netrw_fpl |endif
11728 if exists("w:netrw_hline") |let s:hline = w:netrw_hline |endif
11729 if exists("w:netrw_line") |let s:line = w:netrw_line |endif
11730 if exists("w:netrw_liststyle") |let s:liststyle = w:netrw_liststyle |endif
11731 if exists("w:netrw_method") |let s:method = w:netrw_method |endif
11732 if exists("w:netrw_prvdir") |let s:prvdir = w:netrw_prvdir |endif
11733 if exists("w:netrw_treedict") |let s:treedict = w:netrw_treedict |endif
11734 if exists("w:netrw_treetop") |let s:treetop = w:netrw_treetop |endif
11735 if exists("w:netrw_winnr") |let s:winnr = w:netrw_winnr |endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011736 " call Dret("s:SaveWinVars")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011737endfun
11738
11739" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011740" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011741" To allow separate windows to have their own activities, such as
11742" Explore **/pattern, several variables have been made window-oriented.
11743" However, when the user splits a browser window (ex: ctrl-w s), these
Bram Moolenaar1afcace2005-11-25 19:54:28 +000011744" variables are not inherited by the new window. SetBufWinVars() and
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011745" UseBufWinVars() get around that.
Bram Moolenaar1afcace2005-11-25 19:54:28 +000011746fun! s:SetBufWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011747 " call Dfunc("s:SetBufWinVars() win#".winnr())
Bram Moolenaar9964e462007-05-05 17:54:07 +000011748 if exists("w:netrw_liststyle") |let b:netrw_liststyle = w:netrw_liststyle |endif
11749 if exists("w:netrw_bannercnt") |let b:netrw_bannercnt = w:netrw_bannercnt |endif
11750 if exists("w:netrw_method") |let b:netrw_method = w:netrw_method |endif
11751 if exists("w:netrw_prvdir") |let b:netrw_prvdir = w:netrw_prvdir |endif
11752 if exists("w:netrw_explore_indx") |let b:netrw_explore_indx = w:netrw_explore_indx |endif
11753 if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
11754 if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
11755 if exists("w:netrw_explore_bufnr") |let b:netrw_explore_bufnr = w:netrw_explore_bufnr |endif
11756 if exists("w:netrw_explore_line") |let b:netrw_explore_line = w:netrw_explore_line |endif
11757 if exists("w:netrw_explore_list") |let b:netrw_explore_list = w:netrw_explore_list |endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011758 " call Dret("s:SetBufWinVars")
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011759endfun
11760
11761" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011762" s:SetRexDir: set directory for :Rexplore {{{2
11763fun! s:SetRexDir(islocal,dirname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011764 " call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011765 let w:netrw_rexdir = a:dirname
11766 let w:netrw_rexlocal = a:islocal
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011767 let s:rexposn_{bufnr("%")} = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011768 " call Decho("setting w:netrw_rexdir =".w:netrw_rexdir,'~'.expand("<slnum>"))
11769 " call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>"))
11770 " call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
11771 " call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>"))
11772 " call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011773endfun
11774
11775" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011776" s:ShowLink: used to modify thin and tree listings to show links {{{2
11777fun! s:ShowLink()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011778 if exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011779 keepp :norm! $?\a
11780 "call histdel("/",-1)
11781 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treetop")
11782 let basedir = s:NetrwTreePath(w:netrw_treetop)
11783 else
11784 let basedir = b:netrw_curdir.'/'
11785 endif
11786 let fname = basedir.s:NetrwGetWord()
11787 let resname = resolve(fname)
11788 if resname =~ '^\M'.basedir
11789 let dirlen = strlen(basedir)
11790 let resname = strpart(resname,dirlen)
11791 endif
11792 let modline = getline(".")."\t --> ".resname
11793 setl noro ma
11794 call setline(".",modline)
11795 setl ro noma nomod
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011796 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011797endfun
11798
11799" ---------------------------------------------------------------------
11800" s:ShowStyle: {{{2
11801fun! s:ShowStyle()
11802 if !exists("w:netrw_liststyle")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011803 let liststyle= g:netrw_liststyle
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011804 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011805 let liststyle= w:netrw_liststyle
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011806 endif
11807 if liststyle == s:THINLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010011808 return s:THINLIST.":thin"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011809 elseif liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010011810 return s:LONGLIST.":long"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011811 elseif liststyle == s:WIDELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010011812 return s:WIDELIST.":wide"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011813 elseif liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010011814 return s:TREELIST.":tree"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011815 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011816 return 'n/a'
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011817 endif
11818endfun
11819
11820" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +010011821" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
11822" Solution from Nicolai Weibull, vim docs (:help strlen()),
11823" Tony Mechelynck, and my own invention.
Bram Moolenaar446cb832008-06-24 21:56:24 +000011824fun! s:Strlen(x)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011825 " "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
Bram Moolenaar8d043172014-01-23 14:24:41 +010011826
11827 if v:version >= 703 && exists("*strdisplaywidth")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011828 let ret= strdisplaywidth(a:x)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011829
Bram Moolenaar8d043172014-01-23 14:24:41 +010011830 elseif type(g:Align_xstrlen) == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011831 " allow user to specify a function to compute the string length (ie. let g:Align_xstrlen="mystrlenfunc")
11832 exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011833
Bram Moolenaar8d043172014-01-23 14:24:41 +010011834 elseif g:Align_xstrlen == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011835 " number of codepoints (Latin a + combining circumflex is two codepoints)
11836 " (comment from TM, solution from NW)
11837 let ret= strlen(substitute(a:x,'.','c','g'))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011838
Bram Moolenaar8d043172014-01-23 14:24:41 +010011839 elseif g:Align_xstrlen == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +010011840 " number of spacing codepoints (Latin a + combining circumflex is one spacing
11841 " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
11842 " (comment from TM, solution from TM)
11843 let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011844
Bram Moolenaar8d043172014-01-23 14:24:41 +010011845 elseif g:Align_xstrlen == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +010011846 " virtual length (counting, for instance, tabs as anything between 1 and
11847 " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
11848 " preceded by lam, one otherwise, etc.)
11849 " (comment from TM, solution from me)
11850 let modkeep= &l:mod
11851 exe "norm! o\<esc>"
11852 call setline(line("."),a:x)
11853 let ret= virtcol("$") - 1
11854 d
11855 NetrwKeepj norm! k
11856 let &l:mod= modkeep
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011857
Bram Moolenaar446cb832008-06-24 21:56:24 +000011858 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011859 " at least give a decent default
Bram Moolenaar8d043172014-01-23 14:24:41 +010011860 let ret= strlen(a:x)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011861 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011862 " "" call Dret("s:Strlen ".ret)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011863 return ret
11864endfun
11865
11866" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011867" s:ShellEscape: shellescape(), or special windows handling {{{2
11868fun! s:ShellEscape(s, ...)
Nir Lichtman1e34b952024-05-08 19:19:34 +020011869 if has('win32') && $SHELL == '' && &shellslash
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011870 return printf('"%s"', substitute(a:s, '"', '""', 'g'))
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +010011871 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011872 let f = a:0 > 0 ? a:1 : 0
11873 return shellescape(a:s, f)
11874endfun
11875
11876" ---------------------------------------------------------------------
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011877" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +000011878fun! s:TreeListMove(dir)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011879 " call Dfunc("s:TreeListMove(dir<".a:dir.">)")
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011880 let curline = getline('.')
11881 let prvline = (line(".") > 1)? getline(line(".")-1) : ''
11882 let nxtline = (line(".") < line("$"))? getline(line(".")+1) : ''
11883 let curindent = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
11884 let indentm1 = substitute(curindent,'^'.s:treedepthstring,'','')
11885 let treedepthchr = substitute(s:treedepthstring,' ','','g')
11886 let stopline = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011887 " call Decho("prvline <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
11888 " call Decho("curline <".curline."> #".line(".") , '~'.expand("<slnum>"))
11889 " call Decho("nxtline <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
11890 " call Decho("curindent<".curindent.">" , '~'.expand("<slnum>"))
11891 " call Decho("indentm1 <".indentm1.">" , '~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011892 " COMBAK : need to handle when on a directory
11893 " COMBAK : need to handle ]] and ][. In general, needs work!!!
Bram Moolenaar446cb832008-06-24 21:56:24 +000011894 if curline !~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011895 if a:dir == '[[' && prvline != ''
11896 NetrwKeepj norm! 0
11897 let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
11898 " call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
11899 elseif a:dir == '[]' && nxtline != ''
11900 NetrwKeepj norm! 0
11901 " call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>"))
11902 let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
11903 if nl != 0
11904 NetrwKeepj norm! k
11905 else
11906 NetrwKeepj norm! G
11907 endif
11908 " call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011909 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000011910 endif
11911
Luca Saccarolac363ca12024-12-19 20:16:18 +010011912 " call Dret("s:TreeListMove")
Bram Moolenaar446cb832008-06-24 21:56:24 +000011913endfun
11914
11915" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011916" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
11917" The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
11918" can't be called except via emenu. But due to locale, that menu line may not be called
11919" Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
11920fun! s:UpdateBuffersMenu()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011921 " call Dfunc("s:UpdateBuffersMenu()")
Bram Moolenaaradc21822011-04-01 18:03:16 +020011922 if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
Luca Saccarolac363ca12024-12-19 20:16:18 +010011923 try
11924 sil emenu Buffers.Refresh\ menu
11925 catch /^Vim\%((\a\+)\)\=:E/
11926 let v:errmsg= ""
11927 sil NetrwKeepj call s:NetrwBMShow()
11928 endtry
Bram Moolenaarc236c162008-07-13 17:41:49 +000011929 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011930 " call Dret("s:UpdateBuffersMenu")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011931endfun
11932
11933" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011934" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
Bram Moolenaaradc21822011-04-01 18:03:16 +020011935" Matching function to s:SetBufWinVars()
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011936fun! s:UseBufWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011937 " call Dfunc("s:UseBufWinVars()")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011938 if exists("b:netrw_liststyle") && !exists("w:netrw_liststyle") |let w:netrw_liststyle = b:netrw_liststyle |endif
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011939 if exists("b:netrw_bannercnt") && !exists("w:netrw_bannercnt") |let w:netrw_bannercnt = b:netrw_bannercnt |endif
11940 if exists("b:netrw_method") && !exists("w:netrw_method") |let w:netrw_method = b:netrw_method |endif
11941 if exists("b:netrw_prvdir") && !exists("w:netrw_prvdir") |let w:netrw_prvdir = b:netrw_prvdir |endif
11942 if exists("b:netrw_explore_indx") && !exists("w:netrw_explore_indx") |let w:netrw_explore_indx = b:netrw_explore_indx |endif
11943 if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
11944 if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11945 if exists("b:netrw_explore_bufnr") && !exists("w:netrw_explore_bufnr") |let w:netrw_explore_bufnr = b:netrw_explore_bufnr |endif
11946 if exists("b:netrw_explore_line") && !exists("w:netrw_explore_line") |let w:netrw_explore_line = b:netrw_explore_line |endif
11947 if exists("b:netrw_explore_list") && !exists("w:netrw_explore_list") |let w:netrw_explore_list = b:netrw_explore_list |endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011948 " call Dret("s:UseBufWinVars")
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011949endfun
11950
Bram Moolenaar1afcace2005-11-25 19:54:28 +000011951" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011952" s:UserMaps: supports user-defined UserMaps {{{2
11953" * calls a user-supplied funcref(islocal,curdir)
11954" * interprets result
11955" See netrw#UserMaps()
11956fun! s:UserMaps(islocal,funcname)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011957 if !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011958 let b:netrw_curdir= getcwd()
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011959 endif
11960 let Funcref = function(a:funcname)
11961 let result = Funcref(a:islocal)
11962
11963 if type(result) == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011964 " if result from user's funcref is a string...
11965 if result == "refresh"
11966 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
11967 elseif result != ""
11968 exe result
11969 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011970
11971 elseif type(result) == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +010011972 " if result from user's funcref is a List...
11973 for action in result
11974 if action == "refresh"
11975 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
11976 elseif action != ""
11977 exe action
11978 endif
11979 endfor
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011980 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011981endfun
11982
Bram Moolenaar85850f32019-07-19 22:05:51 +020011983" ==========================
Bram Moolenaare6ae6222013-05-21 21:01:10 +020011984" Settings Restoration: {{{1
Bram Moolenaar85850f32019-07-19 22:05:51 +020011985" ==========================
Bram Moolenaar83bab712005-08-01 21:58:57 +000011986let &cpo= s:keepcpo
11987unlet s:keepcpo
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +000011988
Bram Moolenaar85850f32019-07-19 22:05:51 +020011989" ===============
Bram Moolenaar83bab712005-08-01 21:58:57 +000011990" Modelines: {{{1
Bram Moolenaar85850f32019-07-19 22:05:51 +020011991" ===============
Luca Saccarolac363ca12024-12-19 20:16:18 +010011992" vim:ts=8 sts=2 sw=2 et fdm=marker